diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java b/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java index 2aacf19a741..10ae30096e4 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java @@ -13,7 +13,6 @@ package com.cloud.agent.manager; import java.util.HashMap; -import java.util.List; import java.util.Map; import com.cloud.agent.api.Answer; @@ -39,6 +38,7 @@ import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -63,6 +63,8 @@ public interface MockVmManager extends Manager { Answer SetStaticNatRules(SetStaticNatRulesCommand cmd); Answer SetPortForwardingRules(SetPortForwardingRulesCommand cmd); + + Answer SetFirewallRules(SetFirewallRulesCommand cmd); Answer getNetworkUsage(NetworkUsageCommand cmd); diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index e791b65e6ca..cc98cf9371e 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -37,6 +37,7 @@ import com.cloud.agent.api.MigrateAnswer; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; @@ -53,6 +54,7 @@ import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -272,6 +274,12 @@ public class MockVmManagerImpl implements MockVmManager { return new Answer(cmd); } + @Override + public Answer SetFirewallRules(SetFirewallRulesCommand cmd) { + return new Answer(cmd); + } + + @Override public NetworkUsageAnswer getNetworkUsage(NetworkUsageCommand cmd) { return new NetworkUsageAnswer(cmd, null, 100L, 100L); @@ -340,12 +348,12 @@ public class MockVmManagerImpl implements MockVmManager { _mockAgentMgr.handleSystemVMStop(vm.getId()); } - return new StopAnswer(cmd, null, new Integer(0), new Long(100), new Long(200)); + return new StopAnswer(cmd, null, new Integer(0), true); } @Override public Answer rebootVM(RebootCommand cmd) { - return new Answer(cmd); + return new RebootAnswer(cmd, "Rebooted "+cmd.getVmName(), false); } @Override @@ -457,5 +465,5 @@ public class MockVmManagerImpl implements MockVmManager { } return maps; } - + } diff --git a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index 87846b3f4b2..1517c94d91a 100644 --- a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -64,6 +64,7 @@ import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -200,6 +201,8 @@ public class SimulatorManagerImpl implements SimulatorManager { return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd); } else if (cmd instanceof SetStaticNatRulesCommand) { return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd); + } else if (cmd instanceof SetFirewallRulesCommand) { + return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd); } else if (cmd instanceof NetworkUsageCommand) { diff --git a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java index 55bcc2909bc..fe4534f681a 100644 --- a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -229,10 +229,10 @@ public class AgentRoutingResource extends AgentStorageResource { Answer result = _simMgr.simulate(cmd, hostGuid); if (!result.getResult()) { - return new StopAnswer(cmd, result.getDetails()); + return new StopAnswer(cmd, result.getDetails(), false); } - answer = new StopAnswer(cmd, null, 0, new Long(100), new Long(200)); + answer = new StopAnswer(cmd, null, 0, true); Pair data = _runningVms.get(vmName); if (data != null) { this.usedCpu -= data.first(); diff --git a/agent/src/com/cloud/agent/resource/computing/CloudZonesComputingResource.java b/agent/src/com/cloud/agent/resource/computing/CloudZonesComputingResource.java index 49763107f11..12541fbd3ac 100644 --- a/agent/src/com/cloud/agent/resource/computing/CloudZonesComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/CloudZonesComputingResource.java @@ -215,9 +215,6 @@ public class CloudZonesComputingResource extends LibvirtComputingResource { protected Answer execute(StopCommand cmd) { final String vmName = cmd.getVmName(); - Long bytesReceived = new Long(0); - Long bytesSent = new Long(0); - State state = null; synchronized (_vms) { state = _vms.get(vmName); @@ -231,7 +228,7 @@ public class CloudZonesComputingResource extends LibvirtComputingResource { .nameUUIDFromBytes(vmName.getBytes())); } catch (LibvirtException e) { state = State.Stopped; - return new StopAnswer(cmd, null, 0, bytesSent, bytesReceived); + return new StopAnswer(cmd, null, 0, true); } String macAddress = null; @@ -254,9 +251,9 @@ public class CloudZonesComputingResource extends LibvirtComputingResource { } state = State.Stopped; - return new StopAnswer(cmd, result, 0, bytesSent, bytesReceived); + return new StopAnswer(cmd, result, 0, true); } catch (LibvirtException e) { - return new StopAnswer(cmd, e.getMessage()); + return new StopAnswer(cmd, e.getMessage(), false); } finally { synchronized (_vms) { if (state != null) { diff --git a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java index 0c1e2926b52..5f659301960 100644 --- a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java @@ -439,8 +439,6 @@ public class FakeComputingResource extends ServerResourceBase implements String vmName = cmd.getVmName(); Integer port = vmMgr.getVncPort(vmName); - Long bytesReceived = null; - Long bytesSent = null; State state = null; synchronized (_vms) { @@ -458,17 +456,16 @@ public class FakeComputingResource extends ServerResourceBase implements s_logger.warn("Couldn't stop " + vmName); if (result != null) { - return new StopAnswer(cmd, result); + return new StopAnswer(cmd, result, false); } } - answer = new StopAnswer(cmd, null, port, bytesSent, bytesReceived); + answer = new StopAnswer(cmd, null, port, true); String result2 = vmMgr.cleanupVnet(cmd.getVnet()); if (result2 != null) { result = result2 + (result != null ? ("\n" + result) : ""); - answer = new StopAnswer(cmd, result, port, bytesSent, - bytesReceived); + answer = new StopAnswer(cmd, result, port, true); } _dhcpSnooper.cleanup(vmName, null); @@ -494,7 +491,7 @@ public class FakeComputingResource extends ServerResourceBase implements protected Answer execute(RebootCommand cmd) { VmMgr vmMgr = getVmManager(); vmMgr.rebootVM(cmd.getVmName()); - return new RebootAnswer(cmd, "success", 0L, 0L); + return new RebootAnswer(cmd, "success", true); } private Answer execute(PingTestCommand cmd) { diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index 7d7987412a7..2bab8c2717c 100755 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -235,7 +235,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements private String _createTmplPath; private String _heartBeatPath; private String _securityGroupPath; - private String _networkUsagePath; + private String _routerProxyPath; private String _host; private String _dcId; private String _pod; @@ -539,11 +539,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements "Unable to find the security_group.py"); } - _networkUsagePath = Script.findScript("scripts/network/domr/", - "networkUsage.sh"); - if (_networkUsagePath == null) { + _routerProxyPath = Script.findScript("scripts/network/domr/", + "routerProxy.sh"); + if (_routerProxyPath == null) { throw new ConfigurationException( - "Unable to find the networkUsage.sh"); + "Unable to find the routerProxy.sh"); } String value = (String) params.get("developer"); @@ -2168,7 +2168,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements protected String networkUsage(final String privateIpAddress, final String option, final String vif) { - Script getUsage = new Script(_networkUsagePath, s_logger); + Script getUsage = new Script(_routerProxyPath, s_logger); + getUsage.add("netusage.sh"); + getUsage.add(privateIpAddress); if (option.equals("get")) { getUsage.add("-g"); } else if (option.equals("create")) { @@ -2181,7 +2183,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements getUsage.add("-d", vif); } - getUsage.add("-i", privateIpAddress); + final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); String result = getUsage.execute(usageParser); if (result != null) { @@ -2219,8 +2221,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private Answer execute(RebootCommand cmd) { - Long bytesReceived = null; - Long bytesSent = null; synchronized (_vms) { _vms.put(cmd.getVmName(), State.Starting); @@ -2237,13 +2237,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements } get_rule_logs_for_vms(); - return new RebootAnswer(cmd, null, bytesSent, bytesReceived, - vncPort); + return new RebootAnswer(cmd, null, vncPort); } else { - return new RebootAnswer(cmd, result); + return new RebootAnswer(cmd, result, false); } } catch (LibvirtException e) { - return new RebootAnswer(cmd, e.getMessage()); + return new RebootAnswer(cmd, e.getMessage(), false); } finally { synchronized (_vms) { _vms.put(cmd.getVmName(), State.Running); @@ -2252,16 +2251,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements } protected Answer execute(RebootRouterCommand cmd) { - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); String result = _virtRouterResource.connect(cmd.getPrivateIpAddress()); if (result == null) { networkUsage(cmd.getPrivateIpAddress(), "create", null); @@ -2294,9 +2284,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements protected Answer execute(StopCommand cmd) { final String vmName = cmd.getVmName(); - Long bytesReceived = new Long(0); - Long bytesSent = new Long(0); - State state = null; synchronized (_vms) { state = _vms.get(vmName); @@ -2322,9 +2309,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements result = result2 + result; } state = State.Stopped; - return new StopAnswer(cmd, result, 0, bytesSent, bytesReceived); + return new StopAnswer(cmd, result, 0, true); } catch (LibvirtException e) { - return new StopAnswer(cmd, e.getMessage()); + return new StopAnswer(cmd, e.getMessage(), false); } finally { synchronized (_vms) { if (state != null) { diff --git a/api/src/com/cloud/agent/api/NetworkUsageCommand.java b/api/src/com/cloud/agent/api/NetworkUsageCommand.java index ad6d6982194..6c4152af62d 100644 --- a/api/src/com/cloud/agent/api/NetworkUsageCommand.java +++ b/api/src/com/cloud/agent/api/NetworkUsageCommand.java @@ -13,28 +13,35 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; +import com.cloud.agent.api.to.NicTO; @LogLevel(Log4jLevel.Trace) public class NetworkUsageCommand extends Command { private String privateIP; private String domRName; private String option; + boolean forVpc = false; + NicTO guestNic; protected NetworkUsageCommand() { } - public NetworkUsageCommand(String privateIP, String domRName) + public NetworkUsageCommand(String privateIP, String domRName, boolean forVpc, NicTO guestNic) { this.privateIP = privateIP; this.domRName = domRName; + this.forVpc = forVpc; + this.guestNic = guestNic; + this.option = "get"; } - public NetworkUsageCommand(String privateIP, String domRName, String option) + public NetworkUsageCommand(String privateIP, String domRName, String option, boolean forVpc) { this.privateIP = privateIP; this.domRName = domRName; this.option = option; + this.forVpc = forVpc; } public String getPrivateIP() { @@ -49,6 +56,14 @@ public class NetworkUsageCommand extends Command { return option; } + public boolean isForVpc() { + return forVpc; + } + + public NicTO getGuestNic() { + return guestNic; + } + @Override public boolean executeInSequence() { return false; diff --git a/api/src/com/cloud/agent/api/PlugNicAnswer.java b/api/src/com/cloud/agent/api/PlugNicAnswer.java new file mode 100644 index 00000000000..3a76240ef22 --- /dev/null +++ b/api/src/com/cloud/agent/api/PlugNicAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class PlugNicAnswer extends Answer{ + public PlugNicAnswer() {} + + public PlugNicAnswer(PlugNicCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/PlugNicCommand.java b/api/src/com/cloud/agent/api/PlugNicCommand.java new file mode 100644 index 00000000000..7d340046bb2 --- /dev/null +++ b/api/src/com/cloud/agent/api/PlugNicCommand.java @@ -0,0 +1,47 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; + +/** + * @author Alena Prokharchyk + */ +public class PlugNicCommand extends Command { + + VirtualMachineTO vm; + NicTO nic; + + public VirtualMachineTO getVirtualMachine() { + return vm; + } + + public NicTO getNic() { + return nic; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected PlugNicCommand() { + } + + public PlugNicCommand(VirtualMachineTO vm, NicTO nic) { + this.vm = vm; + this.nic = nic; + } + +} diff --git a/api/src/com/cloud/agent/api/RebootAnswer.java b/api/src/com/cloud/agent/api/RebootAnswer.java index 2900fb3b3ef..a4eabad4c2f 100644 --- a/api/src/com/cloud/agent/api/RebootAnswer.java +++ b/api/src/com/cloud/agent/api/RebootAnswer.java @@ -13,52 +13,25 @@ package com.cloud.agent.api; public class RebootAnswer extends Answer { - Long bytesSent; - Long bytesReceived; Integer vncPort; protected RebootAnswer() { } - public RebootAnswer(RebootCommand cmd, String details, Long bytesSent, Long bytesReceived, Integer vncport) { + public RebootAnswer(RebootCommand cmd, String details, Integer vncport) { super(cmd, true, details); - this.bytesReceived = bytesReceived; - this.bytesSent = bytesSent; this.vncPort = vncport; } - public RebootAnswer(RebootCommand cmd, String details, Long bytesSent, Long bytesReceived) { - super(cmd, true, details); - this.bytesReceived = bytesReceived; - this.bytesSent = bytesSent; + public RebootAnswer(RebootCommand cmd, String details, boolean success) { + super(cmd, success, details); this.vncPort = null; } - public RebootAnswer(RebootCommand cmd, String details) { - super(cmd, false, details); - bytesSent = null; - bytesReceived = null; - } - public RebootAnswer(RebootCommand cmd, Exception e) { super(cmd, e); } - public void setBytesReceived(Long bytesReceived) { - this.bytesReceived = bytesReceived; - } - - public Long getBytesReceived() { - return bytesReceived; - } - - public void setBytesSent(Long bytesSent) { - this.bytesSent = bytesSent; - } - - public Long getBytesSent() { - return bytesSent; - } public Integer getVncPort() { return vncPort; } diff --git a/api/src/com/cloud/agent/api/SetSourceNatAnswer.java b/api/src/com/cloud/agent/api/SetSourceNatAnswer.java new file mode 100644 index 00000000000..b8837e20aa0 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetSourceNatAnswer.java @@ -0,0 +1,26 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.routing.SetSourceNatCommand; + +/** + * @author Alena Prokharchyk + */ +public class SetSourceNatAnswer extends Answer{ + public SetSourceNatAnswer() {} + + public SetSourceNatAnswer(SetSourceNatCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java b/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java new file mode 100644 index 00000000000..e20a9c5ccc8 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class SetupGuestNetworkAnswer extends Answer{ + public SetupGuestNetworkAnswer() {} + + public SetupGuestNetworkAnswer(SetupGuestNetworkCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java new file mode 100644 index 00000000000..1245e6eb4f8 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java @@ -0,0 +1,67 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.to.NicTO; + +/** + * @author Alena Prokharchyk + */ +public class SetupGuestNetworkCommand extends NetworkElementCommand{ + String dhcpRange; + String networkDomain; + String defaultDns1 = null; + String defaultDns2 = null; + boolean isRedundant = false; + Integer priority; + boolean add = true; + NicTO nic; + + public NicTO getNic() { + return nic; + } + + public String getDefaultDns1() { + return defaultDns1; + } + + public String getDefaultDns2() { + return defaultDns2; + } + + public String getNetworkDomain() { + return networkDomain; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected SetupGuestNetworkCommand() { + } + + + public SetupGuestNetworkCommand(String dhcpRange, String networkDomain, boolean isRedundant, Integer priority, + String defaultDns1, String defaultDns2, boolean add, NicTO nic) { + this.dhcpRange = dhcpRange; + this.networkDomain = networkDomain; + this.defaultDns1 = defaultDns1; + this.defaultDns2 = defaultDns2; + this.isRedundant = isRedundant; + this.priority = priority; + this.add = add; + this.nic = nic; + } +} diff --git a/api/src/com/cloud/agent/api/StopAnswer.java b/api/src/com/cloud/agent/api/StopAnswer.java index f32089cff9d..cb20a8247d1 100755 --- a/api/src/com/cloud/agent/api/StopAnswer.java +++ b/api/src/com/cloud/agent/api/StopAnswer.java @@ -18,13 +18,13 @@ public class StopAnswer extends RebootAnswer { protected StopAnswer() { } - public StopAnswer(StopCommand cmd, String details, Integer vncPort, Long bytesSent, Long bytesReceived) { - super(cmd, details, bytesSent, bytesReceived); + public StopAnswer(StopCommand cmd, String details, Integer vncPort, boolean success) { + super(cmd, details, success); this.vncPort = vncPort; } - public StopAnswer(StopCommand cmd, String details) { - super(cmd, details); + public StopAnswer(StopCommand cmd, String details, boolean success) { + super(cmd, details, success); vncPort = null; } diff --git a/api/src/com/cloud/agent/api/StopCommand.java b/api/src/com/cloud/agent/api/StopCommand.java index 0bbced8f92a..63ba9e071aa 100755 --- a/api/src/com/cloud/agent/api/StopCommand.java +++ b/api/src/com/cloud/agent/api/StopCommand.java @@ -19,7 +19,6 @@ public class StopCommand extends RebootCommand { private boolean isProxy=false; private String urlPort=null; private String publicConsoleProxyIpAddress=null; - private String privateRouterIpAddress=null; protected StopCommand() { } @@ -41,12 +40,6 @@ public class StopCommand extends RebootCommand { this.vnet = vnet; } - public StopCommand(VirtualMachine vm, String vmName, String vnet, String privateRouterIpAddress) { - super(vmName); - this.vnet = vnet; - this.privateRouterIpAddress = privateRouterIpAddress; - } - public StopCommand(String vmName) { super(vmName); } @@ -72,7 +65,4 @@ public class StopCommand extends RebootCommand { return this.publicConsoleProxyIpAddress; } - public String getPrivateRouterIpAddress() { - return privateRouterIpAddress; - } } diff --git a/api/src/com/cloud/agent/api/UnPlugNicAnswer.java b/api/src/com/cloud/agent/api/UnPlugNicAnswer.java new file mode 100644 index 00000000000..cd87c722697 --- /dev/null +++ b/api/src/com/cloud/agent/api/UnPlugNicAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class UnPlugNicAnswer extends Answer{ + public UnPlugNicAnswer() {} + + public UnPlugNicAnswer(UnPlugNicCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/UnPlugNicCommand.java b/api/src/com/cloud/agent/api/UnPlugNicCommand.java new file mode 100644 index 00000000000..26d9441092f --- /dev/null +++ b/api/src/com/cloud/agent/api/UnPlugNicCommand.java @@ -0,0 +1,45 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; + +/** + * @author Alena Prokharchyk + */ +public class UnPlugNicCommand extends Command{ + VirtualMachineTO vm; + NicTO nic; + + public VirtualMachineTO getVirtualMachine() { + return vm; + } + + public NicTO getNic() { + return nic; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected UnPlugNicCommand() { + } + + public UnPlugNicCommand(VirtualMachineTO vm, NicTO nic) { + this.vm = vm; + this.nic = nic; + } +} diff --git a/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java b/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java new file mode 100644 index 00000000000..7ab57b4f5c3 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java @@ -0,0 +1,28 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.to.IpAddressTO; + +/** + * @author Alena Prokharchyk + */ +public class IpAssocVpcCommand extends IpAssocCommand{ + protected IpAssocVpcCommand() { + super(); + } + + public IpAssocVpcCommand(IpAddressTO[] ips) { + super(ips); + } +} diff --git a/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java b/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java index 8956db8b5ce..266f3b0d3af 100644 --- a/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java +++ b/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java @@ -13,6 +13,7 @@ package com.cloud.agent.api.routing; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; /** * LoadBalancerConfigCommand sends the load balancer configuration @@ -27,23 +28,35 @@ public class LoadBalancerConfigCommand extends NetworkElementCommand { public String lbStatsSrcCidrs = "0/0" ; /* TODO : currently there is no filtering based on the source ip */ public String lbStatsAuth = "admin1:AdMiN123"; public String lbStatsUri = "/admin?stats"; + NicTO nic; + Long vpcId; protected LoadBalancerConfigCommand() { } - public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers) { + public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers, Long vpcId) { this.loadBalancers = loadBalancers; + this.vpcId = vpcId; } - public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers,String PublicIp,String GuestIp,String PrivateIp) { + public LoadBalancerConfigCommand(LoadBalancerTO[] loadBalancers,String PublicIp,String GuestIp,String PrivateIp, NicTO nic, Long vpcId) { this.loadBalancers = loadBalancers; this.lbStatsPublicIP = PublicIp; this.lbStatsPrivateIP = PrivateIp; this.lbStatsGuestIP = GuestIp; + this.nic = nic; + this.vpcId = vpcId; } + public NicTO getNic() { + return nic; + } public LoadBalancerTO[] getLoadBalancers() { return loadBalancers; } + + public Long getVpcId() { + return vpcId; + } } diff --git a/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java index b2d882baee6..db86bb48eb9 100644 --- a/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -27,6 +27,7 @@ public abstract class NetworkElementCommand extends Command { public static final String ROUTER_IP = "router.ip"; public static final String ROUTER_GUEST_IP = "router.guest.ip"; public static final String ZONE_NETWORK_TYPE = "zone.network.type"; + public static final String GUEST_BRIDGE = "guest.bridge"; protected NetworkElementCommand() { super(); diff --git a/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java b/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java index 210acc35e65..f5011aa860f 100644 --- a/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java +++ b/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.Set; import com.cloud.agent.api.to.FirewallRuleTO; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.utils.StringUtils; /** * diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java b/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java new file mode 100644 index 00000000000..b715a72a46a --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java @@ -0,0 +1,21 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.Answer; + +public class SetNetworkACLAnswer extends Answer { + String[] results; + + protected SetNetworkACLAnswer() { + } + + public SetNetworkACLAnswer(SetNetworkACLCommand cmd, boolean success, String[] results) { + super(cmd, success, null); + assert (cmd.getRules().length == results.length) : "ACLs and their results should be the same length"; + this.results = results; + } + + public String[] getResults() { + return results; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java b/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java new file mode 100644 index 00000000000..777f40e9948 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java @@ -0,0 +1,95 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.cloud.agent.api.to.NetworkACLTO; +import com.cloud.agent.api.to.NicTO; + +/** + * @author Alena Prokharchyk + */ +public class SetNetworkACLCommand extends NetworkElementCommand{ + NetworkACLTO[] rules; + NicTO nic; + + protected SetNetworkACLCommand() { + } + + public SetNetworkACLCommand(List rules, NicTO nic) { + this.rules = rules.toArray(new NetworkACLTO[rules.size()]); + this.nic = nic; + } + + public NetworkACLTO[] getRules() { + return rules; + } + public String[][] generateFwRules() { + String [][] result = new String [2][]; + Set toAdd = new HashSet(); + + + for (NetworkACLTO aclTO: rules) { + /* example : Ingress:tcp:80:80:0.0.0.0/0:,Egress:tcp:220:220:0.0.0.0/0:, + * each entry format Ingress/Egress:protocol:start port: end port:scidrs: + * reverted entry format Ingress/Egress:reverted:0:0:0: + */ + if (aclTO.revoked() == true) + { + StringBuilder sb = new StringBuilder(); + /* This entry is added just to make sure atleast there will one entry in the list to get the ipaddress */ + sb.append(aclTO.getTrafficType().toString()).append(":reverted:0:0:0:"); + String aclRuleEntry = sb.toString(); + toAdd.add(aclRuleEntry); + continue; + } + + List cidr; + StringBuilder sb = new StringBuilder(); + sb.append(aclTO.getTrafficType().toString()).append(":").append(aclTO.getProtocol()).append(":"); + if ("icmp".compareTo(aclTO.getProtocol()) == 0) + { + sb.append(aclTO.getIcmpType()).append(":").append(aclTO.getIcmpCode()).append(":"); + } else { + sb.append(aclTO.getStringPortRange()).append(":"); + } + cidr = aclTO.getSourceCidrList(); + if (cidr == null || cidr.isEmpty()) + { + sb.append("0.0.0.0/0"); + }else{ + Boolean firstEntry = true; + for (String tag : cidr) { + if (!firstEntry) sb.append("-"); + sb.append(tag); + firstEntry = false; + } + } + sb.append(":"); + String aclRuleEntry = sb.toString(); + + toAdd.add(aclRuleEntry); + + } + result[0] = toAdd.toArray(new String[toAdd.size()]); + + return result; + } + + public NicTO getNic() { + return nic; + } +} diff --git a/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java b/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java new file mode 100644 index 00000000000..e6e91f52c26 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java @@ -0,0 +1,29 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import java.util.List; + +import com.cloud.agent.api.to.PortForwardingRuleTO; + +/** + * @author Alena Prokharchyk + */ +public class SetPortForwardingRulesVpcCommand extends SetPortForwardingRulesCommand{ + protected SetPortForwardingRulesVpcCommand() { + } + + public SetPortForwardingRulesVpcCommand(List pfRules) { + super(pfRules); + } +} diff --git a/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java b/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java new file mode 100644 index 00000000000..5f2f7c0e6fd --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java @@ -0,0 +1,41 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.to.IpAddressTO; + +/** + * @author Alena Prokharchyk + */ +public class SetSourceNatCommand extends NetworkElementCommand{ + IpAddressTO ipAddress; + boolean add; + + protected SetSourceNatCommand() { + } + + public SetSourceNatCommand(IpAddressTO ip, boolean add) { + this.ipAddress = ip; + this.add = add; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public IpAddressTO getIpAddress() { + return ipAddress; + } + +} diff --git a/api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java b/api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java index 39485b806d5..a81a063a0a0 100644 --- a/api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java +++ b/api/src/com/cloud/agent/api/routing/SetStaticNatRulesCommand.java @@ -19,20 +19,25 @@ import com.cloud.agent.api.to.StaticNatRuleTO; public class SetStaticNatRulesCommand extends NetworkElementCommand{ StaticNatRuleTO[] rules; + Long vpcId; protected SetStaticNatRulesCommand() { } - public SetStaticNatRulesCommand(List staticNatRules) { + public SetStaticNatRulesCommand(List staticNatRules, Long vpcId) { rules = new StaticNatRuleTO[staticNatRules.size()]; int i = 0; for (StaticNatRuleTO rule : staticNatRules) { rules[i++] = rule; } + this.vpcId = vpcId; } public StaticNatRuleTO[] getRules() { return rules; } + public Long getVpcId() { + return vpcId; + } } diff --git a/api/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java b/api/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java new file mode 100644 index 00000000000..93e79aad0cb --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetStaticRouteAnswer.java @@ -0,0 +1,35 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.Answer; + +/** + * @author Alena Prokharchyk + */ +public class SetStaticRouteAnswer extends Answer{ + String[] results; + + protected SetStaticRouteAnswer() { + } + + public SetStaticRouteAnswer(SetStaticRouteCommand cmd, boolean success, String[] results) { + super(cmd, success, null); + assert (cmd.getStaticRoutes().length == results.length) : "Static routes and their results should be the same length"; + this.results = results; + } + + public String[] getResults() { + return results; + } +} diff --git a/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java b/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java new file mode 100644 index 00000000000..1ab59d7174e --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetStaticRouteCommand.java @@ -0,0 +1,35 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import java.util.List; + +import com.cloud.network.vpc.StaticRouteProfile; + +/** + * @author Alena Prokharchyk + */ +public class SetStaticRouteCommand extends NetworkElementCommand{ + StaticRouteProfile[] staticRoutes; + + protected SetStaticRouteCommand() { + } + + public SetStaticRouteCommand(List staticRoutes) { + this.staticRoutes = staticRoutes.toArray(new StaticRouteProfile[staticRoutes.size()]); + } + + public StaticRouteProfile[] getStaticRoutes() { + return staticRoutes; + } +} diff --git a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java new file mode 100644 index 00000000000..6e438f27fda --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -0,0 +1,118 @@ +package com.cloud.agent.api.routing; + +public class Site2SiteVpnCfgCommand extends NetworkElementCommand { + + private boolean create; + private String localPublicIp; + private String localGuestCidr; + private String localPublicGateway; + private String peerGatewayIp; + private String peerGuestCidrList; + private String ipsecPsk; + private String ikePolicy; + private String espPolicy; + private long lifetime; + + @Override + public boolean executeInSequence() { + return true; + } + + public Site2SiteVpnCfgCommand () { + this.create = false; + } + + public Site2SiteVpnCfgCommand (boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, + String peerGatewayIp, String peerGuestCidrList, String ikePolicy, String espPolicy, long lifetime, String ipsecPsk) { + this.create = create; + this.setLocalPublicIp(localPublicIp); + this.setLocalPublicGateway(localPublicGateway); + this.setLocalGuestCidr(localGuestCidr); + this.setPeerGatewayIp(peerGatewayIp); + this.setPeerGuestCidrList(peerGuestCidrList); + this.ipsecPsk = ipsecPsk; + this.ikePolicy = ikePolicy; + this.espPolicy = espPolicy; + this.lifetime = lifetime; + } + + public boolean isCreate() { + return create; + } + + public void setCreate(boolean create) { + this.create = create; + } + + public String getIpsecPsk() { + return ipsecPsk; + } + + public void setIpsecPsk(String ipsecPsk) { + this.ipsecPsk = ipsecPsk; + } + + public String getIkePolicy() { + return ikePolicy; + } + + public void setIkePolicy(String ikePolicy) { + this.ikePolicy = ikePolicy; + } + + public String getEspPolicy() { + return espPolicy; + } + + public void setEspPolicy(String espPolicy) { + this.espPolicy = espPolicy; + } + + public long getLifetime() { + return lifetime; + } + + public void setLifetime(long lifetime) { + this.lifetime = lifetime; + } + + public String getLocalPublicIp() { + return localPublicIp; + } + + public void setLocalPublicIp(String localPublicIp) { + this.localPublicIp = localPublicIp; + } + + public String getLocalGuestCidr() { + return localGuestCidr; + } + + public void setLocalGuestCidr(String localGuestCidr) { + this.localGuestCidr = localGuestCidr; + } + + public String getLocalPublicGateway() { + return localPublicGateway; + } + + public void setLocalPublicGateway(String localPublicGateway) { + this.localPublicGateway = localPublicGateway; + } + + public String getPeerGatewayIp() { + return peerGatewayIp; + } + + public void setPeerGatewayIp(String peerGatewayIp) { + this.peerGatewayIp = peerGatewayIp; + } + + public String getPeerGuestCidrList() { + return peerGuestCidrList; + } + + public void setPeerGuestCidrList(String peerGuestCidrList) { + this.peerGuestCidrList = peerGuestCidrList; + } +} diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/com/cloud/agent/api/to/IpAddressTO.java index 40770bff1ed..6b3a29edefd 100644 --- a/api/src/com/cloud/agent/api/to/IpAddressTO.java +++ b/api/src/com/cloud/agent/api/to/IpAddressTO.java @@ -14,7 +14,6 @@ package com.cloud.agent.api.to; import com.cloud.network.Networks.TrafficType; - public class IpAddressTO { private long accountId; @@ -32,7 +31,8 @@ public class IpAddressTO { private TrafficType trafficType; private String networkName; - public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, boolean isOneToOneNat) { + public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, + String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, boolean isOneToOneNat) { this.accountId = accountId; this.publicIp = ipAddress; this.add = add; diff --git a/api/src/com/cloud/agent/api/to/NetworkACLTO.java b/api/src/com/cloud/agent/api/to/NetworkACLTO.java new file mode 100644 index 00000000000..2f725638d02 --- /dev/null +++ b/api/src/com/cloud/agent/api/to/NetworkACLTO.java @@ -0,0 +1,109 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +package com.cloud.agent.api.to; + +import java.util.ArrayList; +import java.util.List; + +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.TrafficType; +import com.cloud.utils.net.NetUtils; + + +public class NetworkACLTO { + long id; + String vlanTag; + String protocol; + int[] portRange; + boolean revoked; + boolean alreadyAdded; + private List cidrList; + private Integer icmpType; + private Integer icmpCode; + private FirewallRule.TrafficType trafficType; + + + protected NetworkACLTO() { + } + + + public NetworkACLTO(long id,String vlanTag, String protocol, Integer portStart, Integer portEnd, boolean revoked, + boolean alreadyAdded, List cidrList, Integer icmpType,Integer icmpCode,TrafficType trafficType) { + this.vlanTag = vlanTag; + this.protocol = protocol; + + if (portStart != null) { + List range = new ArrayList(); + range.add(portStart); + if (portEnd != null) { + range.add(portEnd); + } + + portRange = new int[range.size()]; + int i = 0; + for (Integer port : range) { + portRange[i] = port.intValue(); + i ++; + } + } + + this.revoked = revoked; + this.alreadyAdded = alreadyAdded; + this.cidrList = cidrList; + this.icmpType = icmpType; + this.icmpCode = icmpCode; + this.trafficType = trafficType; + } + + public NetworkACLTO(FirewallRule rule, String vlanTag, FirewallRule.TrafficType trafficType ) { + this(rule.getId(), vlanTag, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getState() == FirewallRule.State.Revoke, rule.getState() == FirewallRule.State.Active, + rule.getSourceCidrList() ,rule.getIcmpType(), rule.getIcmpCode(),trafficType); + } + + public long getId() { + return id; + } + + public String getSrcVlanTag() { + return vlanTag; + } + + public String getProtocol() { + return protocol; + } + + public int[] getSrcPortRange() { + return portRange; + } + + public Integer getIcmpType(){ + return icmpType; + } + + public Integer getIcmpCode(){ + return icmpCode; + } + + public String getStringPortRange() { + if (portRange == null || portRange.length < 2) + return "0:0"; + else + return NetUtils.portRangeToString(portRange); + } + + public boolean revoked() { + return revoked; + } + + public List getSourceCidrList() { + return cidrList; + } + + public boolean isAlreadyAdded() { + return alreadyAdded; + } + + public FirewallRule.TrafficType getTrafficType() { + return trafficType; + } +} diff --git a/api/src/com/cloud/agent/api/to/NetworkTO.java b/api/src/com/cloud/agent/api/to/NetworkTO.java index 788e367a2dd..6a7ec1394a9 100644 --- a/api/src/com/cloud/agent/api/to/NetworkTO.java +++ b/api/src/com/cloud/agent/api/to/NetworkTO.java @@ -173,5 +173,4 @@ public class NetworkTO { public boolean isSecurityGroupEnabled() { return this.isSecurityGroupEnabled; } - } diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index d9d31cd1a5a..588a8d0bf69 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -353,6 +353,24 @@ public class ApiConstants { public static final String VSM_DEVICE_STATE = "vsmdevicestate"; public static final String INCL_ZONES = "includezones"; public static final String EXCL_ZONES = "excludezones"; + public static final String RESOURCE_IDS = "resourceids"; + public static final String RESOURCE_ID = "resourceid"; + public static final String CUSTOMER = "customer"; + public static final String VPC_OFF_ID = "vpcofferingid"; + public static final String NETWORK = "network"; + public static final String VPC_ID = "vpcid"; + public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy"; + public static final String GATEWAY_ID = "gatewayid"; + + + public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid"; + public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid"; + public static final String IPSEC_PSK = "ipsecpsk"; + public static final String GUEST_IP = "guestip"; + public static final String REMOVED = "removed"; + public static final String IKE_POLICY = "ikepolicy"; + public static final String ESP_POLICY = "esppolicy"; + public static final String LIFETIME = "lifetime"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/BaseAsyncCmd.java b/api/src/com/cloud/api/BaseAsyncCmd.java index 56cb2c513fd..ab925804f46 100644 --- a/api/src/com/cloud/api/BaseAsyncCmd.java +++ b/api/src/com/cloud/api/BaseAsyncCmd.java @@ -23,6 +23,8 @@ import com.cloud.user.UserContext; public abstract class BaseAsyncCmd extends BaseCmd { public static final String ipAddressSyncObject = "ipaddress"; public static final String networkSyncObject = "network"; + public static final String vpcSyncObject = "vpc"; + private AsyncJob job; diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index d88ce7b6fe3..5899354207b 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -37,14 +37,18 @@ import com.cloud.network.NetworkService; import com.cloud.network.StorageNetworkService; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.firewall.FirewallService; +import com.cloud.network.firewall.NetworkACLService; import com.cloud.network.lb.LoadBalancingRulesService; import com.cloud.network.rules.RulesService; import com.cloud.network.security.SecurityGroupService; +import com.cloud.network.vpc.VpcService; import com.cloud.network.vpn.RemoteAccessVpnService; +import com.cloud.network.vpn.Site2SiteVpnService; import com.cloud.projects.Project; import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceService; import com.cloud.server.ManagementService; +import com.cloud.server.TaggedResourceService; import com.cloud.storage.StorageService; import com.cloud.storage.snapshot.SnapshotService; import com.cloud.template.TemplateService; @@ -123,6 +127,10 @@ public abstract class BaseCmd { public static ResourceLimitService _resourceLimitService; public static IdentityService _identityService; public static StorageNetworkService _storageNetworkService; + public static TaggedResourceService _taggedResourceService; + public static VpcService _vpcService; + public static NetworkACLService _networkACLService; + public static Site2SiteVpnService _s2sVpnService; static void setComponents(ResponseGenerator generator) { ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); @@ -150,6 +158,10 @@ public abstract class BaseCmd { _resourceLimitService = locator.getManager(ResourceLimitService.class); _identityService = locator.getManager(IdentityService.class); _storageNetworkService = locator.getManager(StorageNetworkService.class); + _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcService = locator.getManager(VpcService.class); + _networkACLService = locator.getManager(NetworkACLService.class); + _s2sVpnService = locator.getManager(Site2SiteVpnService.class); } public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException; @@ -483,7 +495,7 @@ public abstract class BaseCmd { if (!enabledOnly || account.getState() == Account.State.enabled) { return account.getId(); } else { - throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active"); + throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active"); } } else { throw new InvalidParameterValueException("Unable to find account by name " + accountName + " in domain id=" + domainId); @@ -496,10 +508,14 @@ public abstract class BaseCmd { if (!enabledOnly || project.getState() == Project.State.Active) { return project.getProjectAccountId(); } else { - throw new PermissionDeniedException("Can't add resources to the project id=" + projectId + " in state=" + project.getState() + " as it's no longer active"); + PermissionDeniedException ex = new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } } else { - throw new InvalidParameterValueException("Unable to find project by id " + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified projectId"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } } return null; diff --git a/api/src/com/cloud/api/Implementation.java b/api/src/com/cloud/api/Implementation.java index 9e12bb79643..c52e6512876 100644 --- a/api/src/com/cloud/api/Implementation.java +++ b/api/src/com/cloud/api/Implementation.java @@ -18,10 +18,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.cloud.api.response.BaseResponse; + @Retention(RetentionPolicy.RUNTIME) @Target({ TYPE }) public @interface Implementation { - Class responseObject(); + Class responseObject(); String description() default ""; diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 9bf0a1cc1e7..e036162d303 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -41,10 +41,12 @@ import com.cloud.api.response.LBStickinessResponse; import com.cloud.api.response.LDAPConfigResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.LoadBalancerResponse; +import com.cloud.api.response.NetworkACLResponse; import com.cloud.api.response.NetworkOfferingResponse; import com.cloud.api.response.NetworkResponse; import com.cloud.api.response.PhysicalNetworkResponse; import com.cloud.api.response.PodResponse; +import com.cloud.api.response.PrivateGatewayResponse; import com.cloud.api.response.ProjectAccountResponse; import com.cloud.api.response.ProjectInvitationResponse; import com.cloud.api.response.ProjectResponse; @@ -52,11 +54,16 @@ import com.cloud.api.response.ProviderResponse; import com.cloud.api.response.RemoteAccessVpnResponse; import com.cloud.api.response.ResourceCountResponse; import com.cloud.api.response.ResourceLimitResponse; +import com.cloud.api.response.ResourceTagResponse; import com.cloud.api.response.SecurityGroupResponse; import com.cloud.api.response.ServiceOfferingResponse; import com.cloud.api.response.ServiceResponse; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; import com.cloud.api.response.StorageNetworkIpRangeResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.api.response.SwiftResponse; @@ -70,6 +77,8 @@ import com.cloud.api.response.UserVmResponse; import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; import com.cloud.api.response.VpnUsersResponse; import com.cloud.api.response.ZoneResponse; import com.cloud.async.AsyncJob; @@ -92,17 +101,25 @@ import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VpnUser; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.NetworkACL; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityRule; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -110,6 +127,7 @@ import com.cloud.org.Cluster; import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; +import com.cloud.server.ResourceTag; import com.cloud.storage.Snapshot; import com.cloud.storage.StoragePool; import com.cloud.storage.Swift; @@ -269,11 +287,53 @@ public interface ResponseGenerator { LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String baseSearch, String dn); StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result); - + /** * @param tableName TODO * @param token * @return */ Long getIdentiyId(String tableName, String token); + + /** + * @param resourceTag + * @return + */ + ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag); + + Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result); + + /** + * @param offering + * @return + */ + VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering); + + /** + * @param vpc + * @return + */ + VpcResponse createVpcResponse(Vpc vpc); + + /** + * @param networkACL + * @return + */ + NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL); + + /** + * @param result + * @return + */ + PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result); + + /** + * @param result + * @return + */ + StaticRouteResponse createStaticRouteResponse(StaticRoute result); + + Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result); + + Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result); } diff --git a/api/src/com/cloud/api/commands/AddAccountToProjectCmd.java b/api/src/com/cloud/api/commands/AddAccountToProjectCmd.java index fbbb2fa70b1..b430a706c2b 100644 --- a/api/src/com/cloud/api/commands/AddAccountToProjectCmd.java +++ b/api/src/com/cloud/api/commands/AddAccountToProjectCmd.java @@ -26,6 +26,8 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.projects.Project; import com.cloud.user.UserContext; +import com.cloud.utils.AnnotationHelper; + @Implementation(description="Adds acoount to a project", responseObject=SuccessResponse.class, since="3.0.0") public class AddAccountToProjectCmd extends BaseAsyncCmd { @@ -95,7 +97,9 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd { Project project= _projectService.getProject(projectId); //verify input parameters if (project == null) { - throw new InvalidParameterValueException("Unable to find project by id " + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } return _projectService.getProjectOwner(projectId).getId(); diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java index 63d94f93b05..e87548765cd 100644 --- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -37,6 +37,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; import com.cloud.network.Network; +import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -49,25 +50,35 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account to associate with this IP address") + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, + description="the account to associate with this IP address") private String accountName; @IdentityMapper(entityTableName="domain") - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the domain to associate with this IP address") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, + description="the ID of the domain to associate with this IP address") private Long domainId; @IdentityMapper(entityTableName="data_center") - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the ID of the availability zone you want to acquire an public IP address from") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, + description="the ID of the availability zone you want to acquire an public IP address from") private Long zoneId; @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The network this ip address should be associated to.") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network this ip address should be associated to.") private Long networkId; @IdentityMapper(entityTableName="projects") - @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Deploy vm for the project") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, + description="Deploy vm for the project") private Long projectId; + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="the VPC you want the ip address to " + + "be associated with") + private Long vpcId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,26 +101,50 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { return UserContext.current().getCaller().getDomainId(); } - private Long getZoneId() { + private long getZoneId() { + if (zoneId != null) { return zoneId; + } else if (vpcId != null) { + Vpc vpc = _entityMgr.findById(Vpc.class, vpcId); + if (vpc != null) { + return vpc.getZoneId(); + } + } else if (networkId != null) { + Network ntwk = _entityMgr.findById(Network.class, networkId); + if (ntwk != null) { + return ntwk.getDataCenterId(); + } + } + + throw new InvalidParameterValueException("Unable to figure out zone to assign ip to"); + } + + public Long getVpcId() { + return vpcId; } public Long getNetworkId() { + if (vpcId != null) { + return null; + } + if (networkId != null) { return networkId; } Long zoneId = getZoneId(); if (zoneId == null) { - throw new InvalidParameterValueException("Either networkId or zoneId has to be specified"); + return null; } DataCenter zone = _configService.getZone(zoneId); if (zone.getNetworkType() == NetworkType.Advanced) { - List networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), _accountService.getAccount(getEntityOwnerId())); + List networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), + _accountService.getAccount(getEntityOwnerId())); if (networks.size() == 0) { String domain = _domainService.getDomain(getDomainId()).getName(); - throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" + zone.getName()); + throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + + " doesn't have virtual networks in zone=" + zone.getName()); } if (networks.size() < 1) { @@ -122,7 +157,8 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { } else { Network defaultGuestNetwork = _networkService.getExclusiveGuestNetwork(zoneId); if (defaultGuestNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default Guest network for account " + getAccountName() + " in domain id=" + getDomainId()); + throw new InvalidParameterValueException("Unable to find a default Guest network for account " + + getAccountName() + " in domain id=" + getDomainId()); } else { return defaultGuestNetwork.getId(); } @@ -135,10 +171,18 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { if (accountName != null && domainId != null) { Account account = _accountService.finalizeOwner(caller, accountName, domainId, projectId); return account.getId(); - } else { + } else if (getNetworkId() != null){ Network network = _networkService.getNetwork(getNetworkId()); return network.getAccountId(); + } else if (vpcId != null) { + Vpc vpc = _vpcService.getVpc(getVpcId()); + if (vpc == null) { + throw new InvalidParameterValueException("Can't find Enabled vpc by id specified"); + } + return vpc.getAccountId(); } + + throw new InvalidParameterValueException("Failed to determine ip owner"); } @Override @@ -168,7 +212,7 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException{ try { - IpAddress ip = _networkService.allocateIP(getNetworkId(), _accountService.getAccount(getEntityOwnerId())); + IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), false, getZoneId()); if (ip != null) { this.setEntityId(ip.getId()); } else { @@ -185,9 +229,14 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { } @Override - public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + public void execute() throws ResourceUnavailableException, ResourceAllocationException, + ConcurrentOperationException, InsufficientCapacityException { UserContext.current().setEventDetails("Ip Id: " + getEntityId()); - IpAddress result = _networkService.associateIP(getEntityId()); + + IpAddress result = null; + + result = _networkService.associateIP(getEntityId(), getNetworkId(), getVpcId()); + if (result != null) { IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(result); ipResponse.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java index 24093d6be48..b13228b37c9 100644 --- a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java @@ -150,7 +150,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return ipAddressId; } @@ -187,7 +187,18 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal @Override public long getNetworkId() { - throw new UnsupportedOperationException("Not yet implemented"); + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } + + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create firewall rule for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; } @Override diff --git a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java index ae0943526cb..af65b4493fe 100644 --- a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java @@ -195,7 +195,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return ipAddressId; } diff --git a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index 0c052d3422a..c2ff39665f7 100644 --- a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -73,7 +73,9 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements @Parameter(name=ApiConstants.PUBLIC_PORT, type=CommandType.INTEGER, required=true, description="the public port from where the network traffic will be load balanced from") private Integer publicPort; - @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default") + @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for" + + " source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. If not specified 1) defaulted to false when LB" + + " rule is being created for VPC guest network 2) in all other cases defaulted to true") private Boolean openFirewall; @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the load balancer. Must be used with the domainId parameter.") @@ -87,7 +89,8 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements private List cidrlist; @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The guest network this rule will be created for") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The guest network this " + + "rule will be created for. Required when public Ip address is not associated with any Guest network yet (VPC case)") private Long networkId; ///////////////////////////////////////////////////// @@ -128,6 +131,19 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements return publicIpId; } + private Long getVpcId() { + if (publicIpId != null) { + IpAddress ipAddr = _networkService.getIp(publicIpId); + if (ipAddr == null || !ipAddr.readyToUse()) { + throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id " + ipAddr.getId()); + } else { + return ipAddr.getVpcId(); + } + } + return null; + } + + public Long getNetworkId() { if (networkId != null) { return networkId; @@ -167,9 +183,12 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements } } else { IpAddress ipAddr = _networkService.getIp(publicIpId); - return ipAddr.getAssociatedWithNetworkId(); + if (ipAddr.getAssociatedWithNetworkId() != null) { + return ipAddr.getAssociatedWithNetworkId(); + } else { + throw new InvalidParameterValueException("Ip address id=" + publicIpId + " is not associated with any network"); + } } - } public Integer getPublicPort() { @@ -181,9 +200,16 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements } public Boolean getOpenFirewall() { + boolean isVpc = getVpcId() == null ? false : true; if (openFirewall != null) { + if (isVpc && openFirewall) { + throw new InvalidParameterValueException("Can't have openFirewall=true when IP address belongs to VPC"); + } return openFirewall; } else { + if (isVpc) { + return false; + } return true; } } diff --git a/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java new file mode 100644 index 00000000000..487b6c9d041 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java @@ -0,0 +1,314 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +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.BaseAsyncCmd; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.NetworkACLResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.NetworkACL; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; +import com.cloud.user.UserContext; +import com.cloud.utils.net.NetUtils; + +@Implementation(description = "Creates a ACL rule the given network (the network has to belong to VPC)", +responseObject = NetworkACLResponse.class) +public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements NetworkACL { + public static final Logger s_logger = Logger.getLogger(CreateNetworkACLCmd.class.getName()); + + private static final String s_name = "createnetworkaclresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = + "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP.") + private String protocol; + + @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, required=true, description = "the starting port of ACL") + private Integer publicStartPort; + + @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL") + private Integer publicEndPort; + + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, + description = "the cidr list to allow traffic from/to") + private List cidrlist; + + @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the icmp message being sent") + private Integer icmpType; + + @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message") + private Integer icmpCode; + + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, required=true, + description="The network of the vm the ACL will be created for") + private Long networkId; + + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="the traffic type for the ACL," + + "can be Ingress or Egress, defaulted to Ingress if not specified") + private String trafficType; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public String getEntityTable() { + return "firewall_rules"; + } + + public Long getIpAddressId() { + return null; + } + + @Override + public String getProtocol() { + return protocol.trim(); + } + + public List getSourceCidrList() { + if (cidrlist != null) { + return cidrlist; + } else { + List oneCidrList = new ArrayList(); + oneCidrList.add(NetUtils.ALL_CIDRS); + return oneCidrList; + } + } + + public long getVpcId() { + Network network = _networkService.getNetwork(getNetworkId()); + if (network == null) { + throw new InvalidParameterValueException("Invalid networkId is given"); + } + + Long vpcId = network.getVpcId(); + if (vpcId == null) { + throw new InvalidParameterValueException("Can create network ACL only for the network belonging to the VPC"); + } + + return vpcId; + } + + @Override + public FirewallRule.TrafficType getTrafficType() { + if (trafficType == null) { + return FirewallRule.TrafficType.Ingress; + } + for (FirewallRule.TrafficType type : FirewallRule.TrafficType.values()) { + if (type.toString().equalsIgnoreCase(trafficType)) { + return type; + } + } + throw new InvalidParameterValueException("Invalid traffic type " + trafficType); + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + public void setSourceCidrList(List cidrs){ + cidrlist = cidrs; + } + + @Override + public void execute() throws ResourceUnavailableException { + UserContext callerContext = UserContext.current(); + boolean success = false; + NetworkACL rule = _networkACLService.getNetworkACL(getEntityId()); + try { + UserContext.current().setEventDetails("Rule Id: " + getEntityId()); + success = _networkACLService.applyNetworkACLs(rule.getNetworkId(), callerContext.getCaller()); + + // State is different after the rule is applied, so get new object here + NetworkACLResponse aclResponse = new NetworkACLResponse(); + if (rule != null) { + aclResponse = _responseGenerator.createNetworkACLResponse(rule); + setResponseObject(aclResponse); + } + aclResponse.setResponseName(getCommandName()); + } finally { + if (!success || rule == null) { + _networkACLService.revokeNetworkACL(getEntityId(), true); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create network ACL"); + } + } + } + + @Override + public long getId() { + throw new UnsupportedOperationException("database id can only provided by VO objects"); + } + + @Override + public String getXid() { + // FIXME: We should allow for end user to specify Xid. + return null; + } + + @Override + public Long getSourceIpAddressId() { + return null; + } + + @Override + public Integer getSourcePortStart() { + if (publicStartPort != null) { + return publicStartPort.intValue(); + } + return null; + } + + @Override + public Integer getSourcePortEnd() { + if (publicEndPort == null) { + if (publicStartPort != null) { + return publicStartPort.intValue(); + } + } else { + return publicEndPort.intValue(); + } + + return null; + } + + @Override + public Purpose getPurpose() { + return Purpose.Firewall; + } + + @Override + public State getState() { + throw new UnsupportedOperationException("Should never call me to find the state"); + } + + @Override + public long getNetworkId() { + return networkId; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _vpcService.getVpc(getVpcId()); + if (vpc == null) { + throw new InvalidParameterValueException("Invalid vpcId is given"); + } + + Account account = _accountService.getAccount(vpc.getAccountId()); + return account.getId(); + } + + @Override + public long getDomainId() { + Vpc vpc = _vpcService.getVpc(getVpcId()); + return vpc.getDomainId(); + } + + @Override + public void create() { + if (getSourceCidrList() != null) { + for (String cidr: getSourceCidrList()){ + if (!NetUtils.isValidCIDR(cidr)){ + throw new ServerApiException(BaseCmd.PARAM_ERROR, "Source cidrs formatting error " + cidr); + } + } + } + + try { + NetworkACL result = _networkACLService.createNetworkACL(this); + setEntityId(result.getId()); + } catch (NetworkRuleConflictException ex) { + s_logger.info("Network rule conflict: " + ex.getMessage()); + s_logger.trace("Network Rule Conflict: ", ex); + throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage()); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_FIREWALL_OPEN; + } + + @Override + public String getEventDescription() { + Network network = _networkService.getNetwork(networkId); + return ("Createing Network ACL for Netowrk: " + network + " for protocol:" + this.getProtocol()); + } + + @Override + public long getAccountId() { + Vpc vpc = _vpcService.getVpc(getVpcId()); + return vpc.getAccountId(); + } + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.networkSyncObject; + } + + @Override + public Long getSyncObjId() { + return getNetworkId(); + } + + @Override + public Integer getIcmpCode() { + if (icmpCode != null) { + return icmpCode; + } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) { + return -1; + } + return null; + } + + @Override + public Integer getIcmpType() { + if (icmpType != null) { + return icmpType; + } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) { + return -1; + + } + return null; + } + + @Override + public Long getRelated() { + return null; + } + + @Override + public FirewallRuleType getType() { + return FirewallRuleType.User; + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.FirewallRule; + } + +} diff --git a/api/src/com/cloud/api/commands/CreateNetworkCmd.java b/api/src/com/cloud/api/commands/CreateNetworkCmd.java index 7058165396c..a9e1291a782 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkCmd.java @@ -58,16 +58,19 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, description="the Physical Network ID the network belongs to") private Long physicalNetworkId; - @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, description="the gateway of the network") + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, description="the gateway of the network. Required " + + "for Shared networks and Isolated networks when it belongs to VPC") private String gateway; - @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, description="the netmask of the network") + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, description="the netmask of the network. Required " + + "for Shared networks and Isolated networks when it belongs to VPC") private String netmask; @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, description="the beginning IP address in the network IP range") private String startIp; - @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP range. If not specified, will be defaulted to startIP") + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP" + + " range. If not specified, will be defaulted to startIP") private String endIp; @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network") @@ -76,7 +79,9 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") private String networkDomain; - @Parameter(name=ApiConstants.ACL_TYPE, type=CommandType.STRING, description="Access control type; supported values are account and domain. In 3.0 all shared networks should have aclType=Domain, and all Isolated networks - Account. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network") + @Parameter(name=ApiConstants.ACL_TYPE, type=CommandType.STRING, description="Access control type; supported values" + + " are account and domain. In 3.0 all shared networks should have aclType=Domain, and all Isolated networks" + + " - Account. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network") private String aclType; @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network") @@ -90,9 +95,13 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a network") private Long domainId; - @Parameter(name=ApiConstants.SUBDOMAIN_ACCESS, type=CommandType.BOOLEAN, description="Defines whether to allow subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified") + @Parameter(name=ApiConstants.SUBDOMAIN_ACCESS, type=CommandType.BOOLEAN, description="Defines whether to allow" + + " subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified") private Boolean subdomainAccess; + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="the VPC network belongs to") + private Long vpcId; ///////////////////////////////////////////////////// @@ -154,7 +163,11 @@ public class CreateNetworkCmd extends BaseCmd { return subdomainAccess; } - public Long getZoneId() { + public Long getVpcId() { + return vpcId; + } + + public Long getZoneId() { Long physicalNetworkId = getPhysicalNetworkId(); if (physicalNetworkId == null && zoneId == null) { @@ -204,7 +217,7 @@ public class CreateNetworkCmd extends BaseCmd { @Override public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{ - Network result = _networkService.createNetwork(this); + Network result = _networkService.createGuestNetwork(this); if (result != null) { NetworkResponse response = _responseGenerator.createNetworkResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java b/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java index 220b4155de7..d2d43ce6a49 100644 --- a/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java @@ -55,13 +55,15 @@ public class CreatePhysicalNetworkCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a physical network") private Long domainId; - @Parameter(name=ApiConstants.BROADCAST_DOMAIN_RANGE, type=CommandType.STRING, description="the broadcast domain range for the physical network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic") + @Parameter(name=ApiConstants.BROADCAST_DOMAIN_RANGE, type=CommandType.STRING, description="the broadcast domain " + + "range for the physical network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic") private String broadcastDomainRange; @Parameter(name=ApiConstants.TAGS, type=CommandType.LIST, collectionType=CommandType.STRING, description="Tag the physical network") private List tags; - @Parameter(name=ApiConstants.ISOLATION_METHODS, type=CommandType.LIST, collectionType=CommandType.STRING, description="the isolation method for the physical network[VLAN/L3/GRE]") + @Parameter(name=ApiConstants.ISOLATION_METHODS, type=CommandType.LIST, collectionType=CommandType.STRING, + description="the isolation method for the physical network[VLAN/L3/GRE]") private List isolationMethods; @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the physical network") diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 8acd1e18764..50650810cc7 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -47,27 +47,42 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P // /////////////////////////////////////////////////// @IdentityMapper(entityTableName = "user_ip_address") - @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.LONG, required = true, description = "the IP address id of the port forwarding rule") + @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.LONG, required = true, + description = "the IP address id of the port forwarding rule") private Long ipAddressId; - @Parameter(name = ApiConstants.PRIVATE_START_PORT, type = CommandType.INTEGER, required = true, description = "the starting port of port forwarding rule's private port range") + @Parameter(name = ApiConstants.PRIVATE_START_PORT, type = CommandType.INTEGER, required = true, + description = "the starting port of port forwarding rule's private port range") private Integer privateStartPort; - @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the port fowarding rule. Valid values are TCP or UDP.") + @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, + description = "the protocol for the port fowarding rule. Valid values are TCP or UDP.") private String protocol; - @Parameter(name = ApiConstants.PUBLIC_START_PORT, type = CommandType.INTEGER, required = true, description = "the starting port of port forwarding rule's public port range") + @Parameter(name = ApiConstants.PUBLIC_START_PORT, type = CommandType.INTEGER, required = true, + description = "the starting port of port forwarding rule's public port range") private Integer publicStartPort; @IdentityMapper(entityTableName = "vm_instance") - @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, description = "the ID of the virtual machine for the port forwarding rule") + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, + description = "the ID of the virtual machine for the port forwarding rule") private Long virtualMachineId; - @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from") + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, + description = "the cidr list to forward traffic from") private List cidrlist; - @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default") + @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, + description = "if true, firewall rule for source/end pubic port is automatically created; " + + "if false - firewall rule has to be created explicitely. If not specified 1) defaulted to false when PF" + + " rule is being created for VPC guest network 2) in all other cases defaulted to true") private Boolean openFirewall; + + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the vm the Port Forwarding rule will be created for. " + + "Required when public Ip address is not associated with any Guest network yet (VPC case)") + private Long networkId; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// @@ -93,18 +108,38 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P public List getSourceCidrList() { if (cidrlist != null) { - throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); + throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall " + + "rule for the specific cidr, please refer to createFirewallRule command"); } return null; } public Boolean getOpenFirewall() { + boolean isVpc = getVpcId() == null ? false : true; if (openFirewall != null) { + if (isVpc && openFirewall) { + throw new InvalidParameterValueException("Can't have openFirewall=true when IP address belongs to VPC"); + } return openFirewall; } else { + if (isVpc) { + return false; + } return true; } } + + private Long getVpcId() { + if (ipAddressId != null) { + IpAddress ipAddr = _networkService.getIp(ipAddressId); + if (ipAddr == null || !ipAddr.readyToUse()) { + throw new InvalidParameterValueException("Unable to create PF rule, invalid IP address id " + ipAddr.getId()); + } else { + return ipAddr.getVpcId(); + } + } + return null; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// @@ -163,7 +198,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return ipAddressId; } @@ -189,7 +224,19 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public long getNetworkId() { - throw new UnsupportedOperationException("Not yet implemented"); + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create port forwarding rule for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; } @Override @@ -201,7 +248,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P } return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are -// tracked + // tracked } @Override @@ -232,7 +279,6 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public void create() { - // cidr list parameter is deprecated if (cidrlist != null) { throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); diff --git a/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java new file mode 100644 index 00000000000..d493b8bc291 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java @@ -0,0 +1,181 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.PrivateGatewayResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +@Implementation(description="Creates a private gateway", responseObject=PrivateGatewayResponse.class) +public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreatePrivateGatewayCmd.class.getName()); + + private static final String s_name = "createprivategatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="physical_network") + @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, description="the Physical Network ID the network belongs to") + private Long physicalNetworkId; + + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway of the Private gateway") + private String gateway; + + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the Private gateway") + private String netmask; + + @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the IP address of the Private gateaway") + private String ipAddress; + + @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, required=true, description="the Vlan for the private gateway") + private String vlan; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, required=true, description="the VPC network belongs to") + private Long vpcId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getGateway() { + return gateway; + } + + public String getVlan() { + return vlan; + } + + public String getNetmask() { + return netmask; + } + + public String getStartIp() { + return ipAddress; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public Long getVpcId() { + return vpcId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public void create() throws ResourceAllocationException { + PrivateGateway result = null; + try { + result = _vpcService.createVpcPrivateGateway(getVpcId(), getPhysicalNetworkId(), + getVlan(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId()); + } catch (InsufficientCapacityException ex){ + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create private gateway"); + } + } + + @Override + public void execute() throws InsufficientCapacityException, ConcurrentOperationException, + ResourceAllocationException, ResourceUnavailableException { + PrivateGateway result = _vpcService.applyVpcPrivateGateway(getEntityId()); + if (result != null) { + PrivateGatewayResponse response = _responseGenerator.createPrivateGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create private gateway"); + } + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_PRIVATE_GATEWAY_CREATE; + } + + @Override + public String getEventDescription() { + return "creating private gateway"; + } + + @Override + public String getEntityTable() { + return "vpc_gateways"; + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + Vpc vpc = _vpcService.getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Invalid id is specified for the vpc"); + } + return vpc.getId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.PrivateGateway; + } +} diff --git a/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java b/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java new file mode 100644 index 00000000000..276c1fb8e24 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java @@ -0,0 +1,195 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.NetworkResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.Network; +import com.cloud.user.UserContext; + +@Implementation(description="Creates a private network", responseObject=NetworkResponse.class) +public class CreatePrivateNetworkCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreatePrivateNetworkCmd.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; + + @IdentityMapper(entityTableName="physical_network") + @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, required=true, description="the Physical Network ID the network belongs to") + private Long physicalNetworkId; + + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway of the network") + private String gateway; + + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the network") + private String netmask; + + @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the network IP range") + private String startIp; + + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP" + + " range. If not specified, will be defaulted to startIP") + private String endIp; + + @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, required=true, description="the ID or VID of the network") + private String vlan; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network") + private String accountName; + + @IdentityMapper(entityTableName="projects") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="an optional project for the ssh key") + private Long projectId; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a network") + private Long domainId; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getGateway() { + return gateway; + } + + 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 getNetworkName() { + return name; + } + + public String getDisplayText() { + return displayText; + } + + public Long getProjectId() { + return projectId; + } + + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getEndIp() { + return endIp; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public void create() throws ResourceAllocationException { + Network result = null; + try { + result = _networkService.createPrivateNetwork(getNetworkName(), getDisplayText(), getPhysicalNetworkId(), getVlan(), + getStartIp(), getEndIp(), getGateway(), getNetmask(), getEntityOwnerId()); + } catch (InsufficientCapacityException ex){ + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a Private network"); + } + } + + @Override + public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{ + Network result = _networkService.getNetwork(getEntityId()); + if (result != null) { + NetworkResponse response = _responseGenerator.createNetworkResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create private network"); + } + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, projectId, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return accountId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETWORK_CREATE; + } + + @Override + public String getEventDescription() { + return "creating private network"; + + } + + @Override + public String getEntityTable() { + return "networks"; + } +} diff --git a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java index b6e13878f46..7964166b009 100644 --- a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java +++ b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java @@ -125,10 +125,25 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { return EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE; } + public long getNetworkId() { + IpAddress ip = _entityMgr.findById(IpAddress.class, getPublicIpId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } + + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create remote access vpn for the ipAddress id=" + getPublicIpId() + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; + } + @Override public void create() { try { - RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall()); + RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), getNetworkId()); if (vpn != null) { this.setEntityId(vpn.getServerAddressId()); } else { diff --git a/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java index 790c94c1f5c..890c66c9121 100644 --- a/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotPolicyCmd.java @@ -106,7 +106,9 @@ public class CreateSnapshotPolicyCmd extends BaseCmd { if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { Project project = _projectService.findByProjectAccountId(volume.getAccountId()); if (project.getState() != Project.State.Active) { - throw new PermissionDeniedException("Can't add resources to the project id=" + project.getId() + " in state=" + project.getState() + " as it's no longer active"); + PermissionDeniedException ex = new PermissionDeniedException("Can't add resources to the specified project id in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, project.getId(), "projectId"); + throw ex; } } else if (account.getState() == Account.State.disabled) { throw new PermissionDeniedException("The owner of template is disabled: " + account); diff --git a/api/src/com/cloud/api/commands/CreateStaticRouteCmd.java b/api/src/com/cloud/api/commands/CreateStaticRouteCmd.java new file mode 100644 index 00000000000..4be141b3cd3 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateStaticRouteCmd.java @@ -0,0 +1,151 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.StaticRouteResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.VpcGateway; +import com.cloud.user.UserContext; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Creates a static route", responseObject=StaticRouteResponse.class) +public class CreateStaticRouteCmd extends BaseAsyncCreateCmd{ + private static final String s_name = "createstaticrouteresponse"; + public static final Logger s_logger = Logger.getLogger(CreateStaticRouteCmd.class.getName()); + + @IdentityMapper(entityTableName="vpc_gateways") + @Parameter(name=ApiConstants.GATEWAY_ID, type=CommandType.LONG, required=true, + description="the gateway id we are creating static route for") + private Long gatewayId; + + @Parameter(name = ApiConstants.CIDR, required = true, type = CommandType.STRING, description = "static route cidr") + private String cidr; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public long getGatewayId() { + return gatewayId; + } + + public String getCidr() { + return cidr; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public void create() throws ResourceAllocationException { + try { + StaticRoute result = _vpcService.createStaticRoute(getGatewayId(), getCidr()); + setEntityId(result.getId()); + } catch (NetworkRuleConflictException ex) { + s_logger.info("Network rule conflict: " + ex.getMessage()); + s_logger.trace("Network rule conflict: ", ex); + throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage()); + } + } + + @Override + public String getEntityTable() { + return "static_routes"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_STATIC_ROUTE_CREATE; + } + + @Override + public String getEventDescription() { + return "creating static route"; + } + + @Override + public void execute() throws ResourceUnavailableException { + boolean success = false; + StaticRoute route = _entityMgr.findById(StaticRoute.class, getEntityId()); + try { + UserContext.current().setEventDetails("Static route Id: " + getEntityId()); + success = _vpcService.applyStaticRoutes(route.getVpcId()); + + // State is different after the route is applied, so get new object here + route = _entityMgr.findById(StaticRoute.class, getEntityId()); + StaticRouteResponse routeResponse = new StaticRouteResponse(); + if (route != null) { + routeResponse = _responseGenerator.createStaticRouteResponse(route); + setResponseObject(routeResponse); + } + routeResponse.setResponseName(getCommandName()); + } finally { + if (!success || route == null) { + _vpcService.revokeStaticRoute(getEntityId()); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create static route"); + } + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + VpcGateway gateway = _vpcService.getVpcGateway(gatewayId); + if (gateway == null) { + throw new InvalidParameterValueException("Invalid gateway id is specified"); + } + return _vpcService.getVpc(gateway.getVpcId()).getAccountId(); + } + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + VpcGateway gateway = _vpcService.getVpcGateway(gatewayId); + if (gateway == null) { + throw new InvalidParameterValueException("Invalid id is specified for the gateway"); + } + return gateway.getVpcId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.StaticRoute; + } +} diff --git a/api/src/com/cloud/api/commands/CreateTagsCmd.java b/api/src/com/cloud/api/commands/CreateTagsCmd.java new file mode 100644 index 00000000000..5a0b56e544e --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateTagsCmd.java @@ -0,0 +1,131 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description = "Creates resource tag(s)", responseObject = SuccessResponse.class, since = "Burbank") +public class CreateTagsCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(CreateTagsCmd.class.getName()); + + private static final String s_name = "createtagsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, required=true, description = "Map of tags (key/value pairs)") + private Map tag; + + @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="type of the resource") + private String resourceType; + + @Parameter(name=ApiConstants.RESOURCE_IDS, type=CommandType.LIST, required=true, + collectionType=CommandType.STRING, description="list of resources to create the tags for") + private List resourceIds; + + @Parameter(name=ApiConstants.CUSTOMER, type=CommandType.STRING, description="identifies client specific tag. " + + "When the value is not null, the tag can't be used by cloudStack code internally") + private String customer; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public TaggedResourceType getResourceType(){ + return _taggedResourceService.getResourceType(resourceType); + } + + public Map getTags() { + Map tagsMap = null; + if (!tag.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tag.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + tagsMap.put(key, value); + } + } + return tagsMap; + } + + public List getResourceIds() { + return resourceIds; + } + + public String getCustomer() { + return customer; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + //FIXME - validate the owner here + return 1; + } + + @Override + public void execute() { + List tags = _taggedResourceService.createTags(getResourceIds(), getResourceType(), getTags(), getCustomer()); + + if (tags != null && !tags.isEmpty()) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create tags"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_TAGS_CREATE; + } + + @Override + public String getEventDescription() { + return "creating tags"; + } +} diff --git a/api/src/com/cloud/api/commands/CreateTemplateCmd.java b/api/src/com/cloud/api/commands/CreateTemplateCmd.java index d7775dec3cf..10c8b6ac6b8 100755 --- a/api/src/com/cloud/api/commands/CreateTemplateCmd.java +++ b/api/src/com/cloud/api/commands/CreateTemplateCmd.java @@ -204,7 +204,8 @@ import com.cloud.user.UserContext; if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { Project project = _projectService.findByProjectAccountId(accountId); if (project.getState() != Project.State.Active) { - throw new PermissionDeniedException("Can't add resources to the project id=" + project.getId() + " in state=" + project.getState() + " as it's no longer active"); + PermissionDeniedException ex = new PermissionDeniedException("Can't add resources to the specified project id in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, project.getId(), "projectId"); } } else if (account.getState() == Account.State.disabled) { throw new PermissionDeniedException("The owner of template is disabled: " + account); diff --git a/api/src/com/cloud/api/commands/CreateVPCCmd.java b/api/src/com/cloud/api/commands/CreateVPCCmd.java new file mode 100644 index 00000000000..8802f55983f --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVPCCmd.java @@ -0,0 +1,184 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.UserContext; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Creates a VPC", responseObject=VpcResponse.class) +public class CreateVPCCmd extends BaseAsyncCreateCmd{ + public static final Logger s_logger = Logger.getLogger(CreateVPCCmd.class.getName()); + private static final String s_name = "createvpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the VPC. " + + "Must be used with the domainId parameter.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID associated with the VPC. " + + "If used with the account parameter returns the VPC associated with the account for the specified domain.") + private Long domainId; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the availability zone") + private Long zoneId; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of " + + "the VPC") + private String displayText; + + @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, required=true, description="the cidr of the VPC. All VPC " + + "guest networks' cidrs should be within this CIDR") + private String cidr; + + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.LONG, required=true, description="the ID of the VPC offering") + private Long vpcOffering; + + @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") + private String networkDomain; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getZoneId() { + return zoneId; + } + + public String getVpcName() { + return vpcName; + } + + public String getCidr() { + return cidr; + } + + public String getDisplayText() { + return displayText; + } + + public Long getVpcOffering() { + return vpcOffering; + } + + public String getNetworkDomain() { + return networkDomain; + } + + @Override + public void create() throws ResourceAllocationException { + Vpc vpc = _vpcService.createVpc(getZoneId(), getVpcOffering(), getEntityOwnerId(), getVpcName(), getDisplayText(), + getCidr(), getNetworkDomain()); + if (vpc != null) { + this.setEntityId(vpc.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a VPC"); + } + } + + @Override + public void execute() { + Vpc vpc = null; + try { + if (_vpcService.startVpc(this.getEntityId())) { + vpc = _vpcService.getVpc(getEntityId()); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } catch (InsufficientCapacityException ex) { + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } + + if (vpc != null) { + VpcResponse response = _responseGenerator.createVpcResponse(vpc); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VPC"); + } + } + + @Override + public String getEntityTable() { + return "vpc"; + } + + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_CREATE; + } + + + @Override + public String getEventDescription() { + return "creating VPC. Id: " + getEntityId(); + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + + return accountId; + } +} diff --git a/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java b/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java new file mode 100644 index 00000000000..184bd8ee45e --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java @@ -0,0 +1,119 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +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.response.VpcOfferingResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Creates VPC offering", responseObject=VpcOfferingResponse.class) +public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd{ + public static final Logger s_logger = Logger.getLogger(CreateVPCOfferingCmd.class.getName()); + private static final String _name = "createvpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the vpc offering") + private String vpcOfferingName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of " + + "the vpc offering") + private String displayText; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, required=true, collectionType=CommandType.STRING, + description="services supported by the vpc offering") + private List supportedServices; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcOfferingName() { + return vpcOfferingName; + } + + public String getDisplayText() { + return displayText; + } + + public List getSupportedServices() { + return supportedServices; + } + + + @Override + public void create() throws ResourceAllocationException { + VpcOffering vpcOff = _vpcService.createVpcOffering(getVpcOfferingName(), getDisplayText(), getSupportedServices()); + if (vpcOff != null) { + this.setEntityId(vpcOff.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a VPC offering"); + } + } + + @Override + public void execute() { + VpcOffering vpc = _vpcService.getVpcOffering(this.getEntityId()); + if (vpc != null) { + VpcOfferingResponse response = _responseGenerator.createVpcOfferingResponse(vpc); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VPC offering"); + } + } + + @Override + public String getEntityTable() { + return "vpc_offerings"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_OFFERING_CREATE; + } + + @Override + public String getEventDescription() { + return "creating VPC offering. Id: " + getEntityId(); + } + + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + +} diff --git a/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java b/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java index 48c6c4e19a3..ef5f8e8e4c7 100644 --- a/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java +++ b/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ResourceAllocationException; import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.element.VirtualRouterElementService; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -92,7 +93,7 @@ public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - VirtualRouterProvider result = _service.addElement(getNspId()); + VirtualRouterProvider result = _service.addElement(getNspId(), VirtualRouterProviderType.VirtualRouter); if (result != null) { setEntityId(result.getId()); } else { diff --git a/api/src/com/cloud/api/commands/CreateVpnConnectionCmd.java b/api/src/com/cloud/api/commands/CreateVpnConnectionCmd.java new file mode 100644 index 00000000000..228b70b3d42 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVpnConnectionCmd.java @@ -0,0 +1,144 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Create site to site vpn connection", responseObject=Site2SiteVpnConnectionResponse.class) +public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateVpnConnectionCmd.class.getName()); + + private static final String s_name = "createvpnconnectionresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_vpn_gateway") + @Parameter(name=ApiConstants.S2S_VPN_GATEWAY_ID, type=CommandType.LONG, required=true, description="id of the vpn gateway") + private Long vpnGatewayId; + + @IdentityMapper(entityTableName="s2s_customer_gateway") + @Parameter(name=ApiConstants.S2S_CUSTOMER_GATEWAY_ID, type=CommandType.LONG, required=true, description="id of the customer gateway") + private Long customerGatewayId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_vpn_connection"; + } + + public Long getVpnGatewayId() { + return vpnGatewayId; + } + + public Long getCustomerGatewayId() { + return customerGatewayId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Create site-to-site VPN connection"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CONNECTION_CREATE; + } + + @Override + public void create() { + try { + Site2SiteVpnConnection conn = _s2sVpnService.createVpnConnection(this); + if (conn != null) { + this.setEntityId(conn.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create site to site vpn connection"); + } + } catch (NetworkRuleConflictException e) { + s_logger.info("Network rule conflict: " + e.getMessage()); + s_logger.trace("Network Rule Conflict: ", e); + throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, e.getMessage()); + } + } + + @Override + public void execute(){ + try { + Site2SiteVpnConnection result = _s2sVpnService.startVpnConnection(this.getEntityId()); + if (result != null) { + Site2SiteVpnConnectionResponse response = _responseGenerator.createSite2SiteVpnConnectionResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create site to site vpn connection"); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + return getIp().getVpcId(); + } + + private IpAddress getIp() { + IpAddress ip = _s2sVpnService.getVpnGatewayIp(vpnGatewayId); + if (ip == null) { + throw new InvalidParameterValueException("Unable to find ip address by vpn gateway id " + vpnGatewayId); + } + return ip; + } +} diff --git a/api/src/com/cloud/api/commands/CreateVpnCustomerGatewayCmd.java b/api/src/com/cloud/api/commands/CreateVpnCustomerGatewayCmd.java new file mode 100644 index 00000000000..b4d68f930ea --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVpnCustomerGatewayCmd.java @@ -0,0 +1,126 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Creates site to site vpn customer gateway", responseObject=Site2SiteCustomerGatewayResponse.class) +public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(CreateVpnCustomerGatewayCmd.class.getName()); + + private static final String s_name = "createvpncustomergatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="public ip address id of the customer gateway") + private String gatewayIp; + + @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.STRING, required=true, description="guest cidr list of the customer gateway") + private String guestCidrList; + + @Parameter(name=ApiConstants.IPSEC_PSK, type=CommandType.STRING, required=true, description="IPsec Preshared-Key of the customer gateway") + private String ipsecPsk; + + @Parameter(name=ApiConstants.IKE_POLICY, type=CommandType.STRING, required=true, description="IKE policy of the customer gateway") + private String ikePolicy; + + @Parameter(name=ApiConstants.ESP_POLICY, type=CommandType.STRING, required=true, description="ESP policy of the customer gateway") + private String espPolicy; + + @Parameter(name=ApiConstants.LIFETIME, type=CommandType.LONG, required=false, description="Lifetime of vpn connection to the customer gateway, in seconds") + private Long lifetime; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_customer_gateway"; + } + + public String getIpsecPsk() { + return ipsecPsk; + } + + public String getGuestCidrList() { + return guestCidrList; + } + + public String getGatewayIp() { + return gatewayIp; + } + + public String getIkePolicy() { + return ikePolicy; + } + + public String getEspPolicy() { + return espPolicy; + } + + public Long getLifetime() { + return lifetime; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Create site-to-site VPN customer gateway"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CUSTOMER_GATEWAY_CREATE; + } + + @Override + public void execute(){ + Site2SiteCustomerGateway result = _s2sVpnService.createCustomerGateway(this); + if (result != null) { + Site2SiteCustomerGatewayResponse response = _responseGenerator.createSite2SiteCustomerGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create customer VPN gateway"); + } + } +} diff --git a/api/src/com/cloud/api/commands/CreateVpnGatewayCmd.java b/api/src/com/cloud/api/commands/CreateVpnGatewayCmd.java new file mode 100644 index 00000000000..050dbdaf2ff --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVpnGatewayCmd.java @@ -0,0 +1,115 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.IpAddress; +import com.cloud.network.Site2SiteVpnGateway; + +@Implementation(description="Creates site to site vpn local gateway", responseObject=Site2SiteVpnGatewayResponse.class) +public class CreateVpnGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(CreateVpnGatewayCmd.class.getName()); + + private static final String s_name = "createvpngatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="user_ip_address") + @Parameter(name=ApiConstants.PUBLIC_IP_ID, type=CommandType.LONG, required=true, description="public ip address id of the vpn gateway") + private Long publicIpId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "user_ip_address"; + } + + public Long getPublicIpId() { + return publicIpId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + IpAddress ip = _networkService.getIp(publicIpId); + + if (ip == null) { + throw new InvalidParameterValueException("Unable to find ip address by id=" + publicIpId); + } + + return ip.getAccountId(); + } + + @Override + public String getEventDescription() { + return "Create site-to-site VPN gateway for account " + getEntityOwnerId() + " using public ip id=" + publicIpId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_VPN_GATEWAY_CREATE; + } + + @Override + public void execute(){ + Site2SiteVpnGateway result = _s2sVpnService.createVpnGateway(this); + if (result != null) { + Site2SiteVpnGatewayResponse response = _responseGenerator.createSite2SiteVpnGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VPN gateway"); + } + } + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + return getIp().getVpcId(); + } + + private IpAddress getIp() { + IpAddress ip = _networkService.getIp(publicIpId); + if (ip == null) { + throw new InvalidParameterValueException("Unable to find ip address by id " + publicIpId); + } + return ip; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java b/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java new file mode 100644 index 00000000000..414822bdb33 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteNetworkACLCmd.java @@ -0,0 +1,120 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +/** + * @author Alena Prokharchyk + */ +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.NetworkACL; +import com.cloud.user.UserContext; + +@Implementation(description="Deletes a Network ACL", responseObject=SuccessResponse.class) +public class DeleteNetworkACLCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteNetworkACLCmd.class.getName()); + private static final String s_name = "deletenetworkaclresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="firewall_rules") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the network ACL") + private Long id; + + // unexposed parameter needed for events logging + @IdentityMapper(entityTableName="account") + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, expose=false) + private Long ownerId; + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_FIREWALL_CLOSE; + } + + @Override + public String getEventDescription() { + return ("Deleting Network ACL id=" + id); + } + + @Override + public long getEntityOwnerId() { + if (ownerId == null) { + NetworkACL rule = _networkACLService.getNetworkACL(id); + if (rule == null) { + throw new InvalidParameterValueException("Unable to find network ACL by id=" + id); + } else { + ownerId = rule.getAccountId(); + } + } + return ownerId; + } + + @Override + public void execute() throws ResourceUnavailableException { + UserContext.current().setEventDetails("Network ACL Id: " + id); + boolean result = _networkACLService.revokeNetworkACL(id, true); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete network ACL"); + } + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.networkSyncObject; + } + + @Override + public Long getSyncObjId() { + return _firewallService.getFirewallRule(id).getNetworkId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.FirewallRule; + } +} + diff --git a/api/src/com/cloud/api/commands/DeletePrivateGatewayCmd.java b/api/src/com/cloud/api/commands/DeletePrivateGatewayCmd.java new file mode 100644 index 00000000000..83714582b1d --- /dev/null +++ b/api/src/com/cloud/api/commands/DeletePrivateGatewayCmd.java @@ -0,0 +1,113 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.VpcGateway; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +/** + * @author Alena Prokharchyk + */ +@Implementation(description="Deletes a Private gateway", responseObject=SuccessResponse.class) +public class DeletePrivateGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeletePrivateGatewayCmd.class.getName()); + private static final String s_name = "deleteprivategatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc_gateways") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the private gateway") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_PRIVATE_GATEWAY_DELETE; + } + + @Override + public String getEventDescription() { + return ("Deleting private gateway id=" + id); + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() throws ResourceUnavailableException, ConcurrentOperationException { + UserContext.current().setEventDetails("Network ACL Id: " + id); + boolean result = _vpcService.deleteVpcPrivateGateway(id); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete private gateway"); + } + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + VpcGateway gateway = _vpcService.getVpcPrivateGateway(getId()); + if (gateway == null) { + throw new InvalidParameterValueException("Invalid private gateway id"); + } + return gateway.getVpcId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.PrivateGateway; + } + +} \ No newline at end of file diff --git a/api/src/com/cloud/api/commands/DeleteStaticRouteCmd.java b/api/src/com/cloud/api/commands/DeleteStaticRouteCmd.java new file mode 100644 index 00000000000..a6fc85b798b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteStaticRouteCmd.java @@ -0,0 +1,124 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.async.AsyncJob; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.user.UserContext; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Deletes a static route", responseObject=SuccessResponse.class) +public class DeleteStaticRouteCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteStaticRouteCmd.class.getName()); + private static final String s_name = "deletestaticrouteresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="static_routes") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the static route") + private Long id; + + // unexposed parameter needed for events logging + @IdentityMapper(entityTableName="account") + @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, expose=false) + private Long ownerId; + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_STATIC_ROUTE_DELETE; + } + + @Override + public String getEventDescription() { + return ("Deleting static route id=" + id); + } + + @Override + public long getEntityOwnerId() { + if (ownerId == null) { + StaticRoute route = _entityMgr.findById(StaticRoute.class, id); + if (route == null) { + throw new InvalidParameterValueException("Unable to find static route by id=" + id); + } else { + ownerId = route.getAccountId(); + } + } + return ownerId; + } + + @Override + public void execute() throws ResourceUnavailableException { + UserContext.current().setEventDetails("Route Id: " + id); + boolean result = _vpcService.revokeStaticRoute(id); + + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete static route"); + } + } + + + @Override + public String getSyncObjType() { + return BaseAsyncCmd.vpcSyncObject; + } + + @Override + public Long getSyncObjId() { + StaticRoute route = _vpcService.getStaticRoute(id); + if (route == null) { + throw new InvalidParameterValueException("Invalid id is specified for the static route"); + } + return route.getVpcId(); + } + + @Override + public AsyncJob.Type getInstanceType() { + return AsyncJob.Type.StaticRoute; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteTagsCmd.java b/api/src/com/cloud/api/commands/DeleteTagsCmd.java new file mode 100644 index 00000000000..a84a09ec38b --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteTagsCmd.java @@ -0,0 +1,112 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +package com.cloud.api.commands; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +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.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description = "Deleting resource tag(s)", responseObject = SuccessResponse.class, since = "Burbank") +public class DeleteTagsCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteTagsCmd.class.getName()); + + private static final String s_name = "deleteTagsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "Delete tags matching key/value pairs") + private Map tag; + + @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, required=true, description="Delete tag by resource type") + private String resourceType; + + @Parameter(name=ApiConstants.RESOURCE_IDS, type=CommandType.LIST, required=true, + collectionType=CommandType.STRING, description="Delete tags for resource id(s)") + private List resourceIds; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public TaggedResourceType getResourceType(){ + return _taggedResourceService.getResourceType(resourceType); + } + + public Map getTags() { + Map tagsMap = null; + if (tag != null && !tag.isEmpty()) { + tagsMap = new HashMap(); + Collection servicesCollection = tag.values(); + Iterator iter = servicesCollection.iterator(); + while (iter.hasNext()) { + HashMap services = (HashMap) iter.next(); + String key = services.get("key"); + String value = services.get("value"); + tagsMap.put(key, value); + } + } + return tagsMap; + } + + public List getResourceIds() { + return resourceIds; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + //FIXME - validate the owner here + return 1; + } + + @Override + public void execute() { + boolean success = _taggedResourceService.deleteTags(getResourceIds(), getResourceType(), getTags()); + + if (success) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete tags"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_TAGS_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting tags"; + } +} diff --git a/api/src/com/cloud/api/commands/DeleteVPCCmd.java b/api/src/com/cloud/api/commands/DeleteVPCCmd.java new file mode 100644 index 00000000000..eb8ad3d1fd8 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVPCCmd.java @@ -0,0 +1,106 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Deletes a VPC", responseObject=SuccessResponse.class) +public class DeleteVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteVPCCmd.class.getName()); + private static final String s_name = "deletevpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the VPC") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting VPC id=" + getId(); + } + + @Override + public void execute() { + try { + boolean result = _vpcService.deleteVpc(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete VPC"); + } + }catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + +} diff --git a/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java b/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java new file mode 100644 index 00000000000..29fcc633978 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java @@ -0,0 +1,92 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Deletes VPC offering", responseObject=SuccessResponse.class) +public class DeleteVPCOfferingCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteVPCOfferingCmd.class.getName()); + private static final String s_name = "deletevpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the VPC offering") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + boolean result = _vpcService.deleteVpcOffering(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete VPC offering"); + } + } + + @Override + public String getEventType(){ + return EventTypes.EVENT_VPC_OFFERING_DELETE; + } + + + @Override + public String getEventDescription() { + return "Deleting VPC offering id=" + getId(); + } + + +} diff --git a/api/src/com/cloud/api/commands/DeleteVpnConnectionCmd.java b/api/src/com/cloud/api/commands/DeleteVpnConnectionCmd.java new file mode 100644 index 00000000000..53cc112620e --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVpnConnectionCmd.java @@ -0,0 +1,117 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Delete site to site vpn connection", responseObject=Site2SiteVpnConnectionResponse.class) +public class DeleteVpnConnectionCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteVpnConnectionCmd.class.getName()); + + private static final String s_name = "deletevpnconnectionresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_vpn_connection") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of vpn connection") + private Long id; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for connection. Must be used with domainId.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for connection. If the account parameter is used, domainId must also be used.") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_vpn_connection"; + } + + public Long getDomainId() { + return domainId; + } + + public Long getAccountId() { + return getEntityOwnerId(); + } + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Delete site-to-site VPN connection for account " + getEntityOwnerId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CONNECTION_DELETE; + } + + @Override + public void execute(){ + try { + Site2SiteVpnConnection result = _s2sVpnService.deleteVpnConnection(this); + if (result != null) { + Site2SiteVpnConnectionResponse response = _responseGenerator.createSite2SiteVpnConnectionResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete site to site VPN connection"); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } + } +} diff --git a/api/src/com/cloud/api/commands/DeleteVpnCustomerGatewayCmd.java b/api/src/com/cloud/api/commands/DeleteVpnCustomerGatewayCmd.java new file mode 100644 index 00000000000..17528a95af8 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVpnCustomerGatewayCmd.java @@ -0,0 +1,111 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Delete site to site vpn customer gateway", responseObject=Site2SiteCustomerGatewayResponse.class) +public class DeleteVpnCustomerGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteVpnCustomerGatewayCmd.class.getName()); + + private static final String s_name = "deletecustomergatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_customer_gateway") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of customer gateway") + private Long id; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for gateway. Must be used with domainId.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId fo: gateway. If the account parameter is used, domainId must also be used.") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_customer_gateway"; + } + + public Long getDomainId() { + return domainId; + } + + public Long getAccountId() { + return getEntityOwnerId(); + } + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Delete site-to-site VPN customer gateway for account " + getEntityOwnerId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CUSTOMER_GATEWAY_DELETE; + } + + @Override + public void execute(){ + Site2SiteCustomerGateway result = _s2sVpnService.deleteCustomerGateway(this); + if (result != null) { + Site2SiteCustomerGatewayResponse response = _responseGenerator.createSite2SiteCustomerGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete customer VPN gateway"); + } + } +} diff --git a/api/src/com/cloud/api/commands/DeleteVpnGatewayCmd.java b/api/src/com/cloud/api/commands/DeleteVpnGatewayCmd.java new file mode 100644 index 00000000000..b8569691864 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVpnGatewayCmd.java @@ -0,0 +1,111 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Delete site to site vpn gateway", responseObject=Site2SiteVpnGatewayResponse.class) +public class DeleteVpnGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteVpnGatewayCmd.class.getName()); + + private static final String s_name = "deletevpngatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_vpn_gateway") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of customer gateway") + private Long id; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for gateway. Must be used with domainId.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId fo: gateway. If the account parameter is used, domainId must also be used.") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_vpn_gateway"; + } + + public Long getDomainId() { + return domainId; + } + + public Long getAccountId() { + return getEntityOwnerId(); + } + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Delete site-to-site VPN gateway for account " + getEntityOwnerId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE; + } + + @Override + public void execute(){ + Site2SiteVpnGateway result = _s2sVpnService.deleteVpnGateway(this); + if (result != null) { + Site2SiteVpnGatewayResponse response = _responseGenerator.createSite2SiteVpnGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete customer VPN gateway"); + } + } +} diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index 85914cb9289..a88449c7909 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -250,7 +251,7 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { } Map ipToNetworkMap = null; if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) { - ipToNetworkMap = new HashMap(); + ipToNetworkMap = new LinkedHashMap(); Collection ipsCollection = ipToNetworkList.values(); Iterator iter = ipsCollection.iterator(); while (iter.hasNext()) { diff --git a/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java b/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java index afdc7d7ff47..ea19ea319c6 100644 --- a/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java @@ -41,7 +41,8 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="user_ip_address") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the public ip address to disassociate") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the public ip address" + + " to disassociate") private Long id; // unexposed parameter needed for events logging @@ -67,8 +68,8 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd { @Override public void execute() throws InsufficientAddressCapacityException{ - UserContext.current().setEventDetails("Ip Id: "+getIpAddressId()); - boolean result = _networkService.disassociateIpAddress(id); + UserContext.current().setEventDetails("Ip Id: " + getIpAddressId()); + boolean result = _networkService.releaseIpAddress(getIpAddressId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java index 9e649ec9d08..a8cd131f1c2 100644 --- a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java +++ b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java @@ -21,8 +21,10 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; import com.cloud.user.Account; import com.cloud.uservm.UserVm; @@ -37,13 +39,21 @@ public class EnableStaticNatCmd extends BaseCmd{ ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="user_ip_address") - @Parameter(name=ApiConstants.IP_ADDRESS_ID, type=CommandType.LONG, required=true, description="the public IP address id for which static nat feature is being enabled") + @Parameter(name=ApiConstants.IP_ADDRESS_ID, type=CommandType.LONG, required=true, description="the public IP " + + "address id for which static nat feature is being enabled") private Long ipAddressId; @IdentityMapper(entityTableName="vm_instance") - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for enabling static nat feature") + @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of " + + "the virtual machine for enabling static nat feature") private Long virtualMachineId; + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the vm the static nat will be enabled for." + + " Required when public Ip address is not associated with any Guest network yet (VPC case)") + private Long networkId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -56,6 +66,22 @@ public class EnableStaticNatCmd extends BaseCmd{ return virtualMachineId; } + public long getNetworkId() { + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -78,7 +104,7 @@ public class EnableStaticNatCmd extends BaseCmd{ @Override public void execute() throws ResourceUnavailableException{ try { - boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, false); + boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java index 89023db6414..db406fe77fb 100644 --- a/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListFirewallRulesCmd.java @@ -18,7 +18,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -30,7 +29,6 @@ import com.cloud.network.rules.FirewallRule; @Implementation(description="Lists all firewall rules for an IP address.", responseObject=FirewallResponse.class) public class ListFirewallRulesCmd extends BaseListProjectAndAccountResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListFirewallRulesCmd.class.getName()); - private static final String s_name = "listfirewallrulesresponse"; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java new file mode 100644 index 00000000000..c6e477b9428 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListNetworkACLsCmd.java @@ -0,0 +1,93 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +/** + * @author Alena Prokharchyk + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.FirewallResponse; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.NetworkACLResponse; +import com.cloud.network.rules.NetworkACL; + +@Implementation(description="Lists all network ACLs", responseObject=NetworkACLResponse.class) +public class ListNetworkACLsCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger(ListNetworkACLsCmd.class.getName()); + + private static final String s_name = "listnetworkaclsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="firewall_rules") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="Lists network ACL with the specified ID.") + private Long id; + + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="list network ACLs by network Id") + private Long networkId; + + @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list network ACLs by traffic type - Ingress or Egress") + private String trafficType; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNetworkId() { + return networkId; + } + + public Long getId() { + return id; + } + + public String getTrafficType() { + return trafficType; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List result = _networkACLService.listNetworkACLs(this); + ListResponse response = new ListResponse(); + List aclResponses = new ArrayList(); + + for (NetworkACL acl : result) { + NetworkACLResponse ruleData = _responseGenerator.createNetworkACLResponse(acl); + aclResponses.add(ruleData); + } + response.setResponses(aclResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListNetworksCmd.java b/api/src/com/cloud/api/commands/ListNetworksCmd.java index e7bea4d2d2f..676c453d72c 100644 --- a/api/src/com/cloud/api/commands/ListNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -59,14 +59,21 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, description="list networks by physical network id") private Long physicalNetworkId; - @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, description="list network offerings supporting certain services") + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, description="list networks supporting certain services") private List supportedServices; - @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list network offerings by restartRequired option") + @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list networks by restartRequired") private Boolean restartRequired; @Parameter(name=ApiConstants.SPECIFY_IP_RANGES, type=CommandType.BOOLEAN, description="true if need to list only networks which support specifying ip ranges") private Boolean specifyIpRanges; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; + + @Parameter(name=ApiConstants.CAN_USE_FOR_DEPLOY, type=CommandType.BOOLEAN, description="list networks available for vm deployment") + private Boolean canUseForDeploy; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -111,8 +118,16 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { public Boolean getSpecifyIpRanges() { return specifyIpRanges; } + + public Boolean canUseForDeploy() { + return canUseForDeploy; + } - ///////////////////////////////////////////////////// + public Long getVpcId() { + return vpcId; + } + + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @Override diff --git a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java new file mode 100644 index 00000000000..67ff27deee8 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java @@ -0,0 +1,99 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.BaseCmd.CommandType; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.PrivateGatewayResponse; +import com.cloud.network.vpc.PrivateGateway; + +/** + * @author Alena Prokharchyk + */ +@Implementation(description="List private gateways", responseObject=PrivateGatewayResponse.class) +public class ListPrivateGatewaysCmd extends BaseListProjectAndAccountResourcesCmd{ + public static final Logger s_logger = Logger.getLogger(ListPrivateGatewaysCmd.class.getName()); + + private static final String s_name = "listprivategatewaysresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="static_routes") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list private gateway by id") + private Long id; + + @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="list gateways by ip address") + private String ipAddress; + + @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="list gateways by vlan") + private String vlan; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="list gateways by vpc") + private Long vpcId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public String getVlan() { + return vlan; + } + + public String getIpAddress() { + return ipAddress; + } + + public Long getVpcId() { + return vpcId; + } + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() { + List gateways = _vpcService.listPrivateGateway(this); + ListResponse response = new ListResponse(); + List projectResponses = new ArrayList(); + for (PrivateGateway gateway : gateways) { + PrivateGatewayResponse gatewayResponse = _responseGenerator.createPrivateGatewayResponse(gateway); + projectResponses.add(gatewayResponse); + } + response.setResponses(projectResponses); + response.setResponseName(getCommandName()); + + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index d853d65f5fd..60add46ff46 100644 --- a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -74,6 +74,10 @@ public class ListPublicIpAddressesCmd extends BaseListProjectAndAccountResources @Parameter(name=ApiConstants.IS_STATIC_NAT, type=CommandType.BOOLEAN, description="list only static nat ip addresses") private Boolean isStaticNat; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List ips belonging to the VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -118,6 +122,10 @@ public class ListPublicIpAddressesCmd extends BaseListProjectAndAccountResources return isStaticNat; } + public Long getVpcId() { + return vpcId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListRoutersCmd.java b/api/src/com/cloud/api/commands/ListRoutersCmd.java index 2e713e66988..0fb4dcc65c9 100644 --- a/api/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/api/src/com/cloud/api/commands/ListRoutersCmd.java @@ -18,7 +18,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -63,6 +62,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @IdentityMapper(entityTableName="networks") @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="list by network id") private Long networkId; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -95,6 +98,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Long getNetworkId() { return networkId; } + + public Long getVpcId() { + return vpcId; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java new file mode 100644 index 00000000000..f3e0021bc94 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListStaticRoutesCmd.java @@ -0,0 +1,86 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.StaticRouteResponse; +import com.cloud.network.vpc.StaticRoute; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Lists all static routes", responseObject=StaticRouteResponse.class) +public class ListStaticRoutesCmd extends BaseListProjectAndAccountResourcesCmd { + private static final String s_name = "liststaticroutesresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="static_routes") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list static route by id") + private Long id; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="list static routes by vpc id") + private Long vpcId; + + @IdentityMapper(entityTableName="vpc_gateways") + @Parameter(name=ApiConstants.GATEWAY_ID, type=CommandType.LONG, description="list static routes by gateway id") + private Long gatewayId; + + public Long getId() { + return id; + } + + public Long getVpcId() { + return vpcId; + } + + public Long getGatewayId() { + return gatewayId; + } + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List result = _vpcService.listStaticRoutes(this); + ListResponse response = new ListResponse(); + List routeResponses = new ArrayList(); + + for (StaticRoute route : result) { + StaticRouteResponse ruleData = _responseGenerator.createStaticRouteResponse(route); + routeResponses.add(ruleData); + } + response.setResponses(routeResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + +} diff --git a/api/src/com/cloud/api/commands/ListTagsCmd.java b/api/src/com/cloud/api/commands/ListTagsCmd.java new file mode 100644 index 00000000000..8b9eae195ed --- /dev/null +++ b/api/src/com/cloud/api/commands/ListTagsCmd.java @@ -0,0 +1,94 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.ResourceTagResponse; +import com.cloud.server.ResourceTag; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description = "List resource tag(s)", responseObject = ResourceTagResponse.class, since = "Burbank") +public class ListTagsCmd extends BaseListProjectAndAccountResourcesCmd{ + private static final String s_name = "listtagsresponse"; + + @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.STRING, description="list by resource type") + private String resourceType; + + @Parameter(name=ApiConstants.RESOURCE_ID, type=CommandType.STRING, description="list by resource id") + private String resourceId; + + @Parameter(name=ApiConstants.KEY, type=CommandType.STRING, description="list by key") + private String key; + + @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, description="list by value") + private String value; + + @Parameter(name=ApiConstants.CUSTOMER, type=CommandType.STRING, description="list by customer name") + private String customer; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() { + + List tags = _taggedResourceService.listTags(this); + ListResponse response = new ListResponse(); + List tagResponses = new ArrayList(); + for (ResourceTag tag : tags) { + ResourceTagResponse tagResponse = _responseGenerator.createResourceTagResponse(tag); + tagResponses.add(tagResponse); + } + response.setResponses(tagResponses); + + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + public String getResourceType() { + return resourceType; + } + + public String getResourceId() { + return resourceId; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + @Override + public String getCommandName() { + return s_name; + } + + public String getCustomer() { + return customer; + } +} diff --git a/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java b/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java new file mode 100644 index 00000000000..bd112414b40 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java @@ -0,0 +1,116 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.network.vpc.VpcOffering; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Lists VPC offerings", responseObject=VpcOfferingResponse.class) +public class ListVPCOfferingsCmd extends BaseListCmd{ + public static final Logger s_logger = Logger.getLogger(ListVPCOfferingsCmd.class.getName()); + private static final String _name = "listvpcofferingsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list VPC offerings by id") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list VPC offerings by name") + private String vpcOffName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list VPC offerings by display text") + private String displayText; + + @Parameter(name=ApiConstants.IS_DEFAULT, type=CommandType.BOOLEAN, description="true if need to list only default " + + "VPC offerings. Default value is false") + private Boolean isDefault; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, + description="list VPC offerings supporting certain services") + private List supportedServices; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list VPC offerings by state") + private String state; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public Long getId() { + return id; + } + + public String getVpcOffName() { + return vpcOffName; + } + + public String getDisplayText() { + return displayText; + } + + public Boolean getIsDefault() { + return isDefault; + } + + public List getSupportedServices() { + return supportedServices; + } + + public String getState() { + return state; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute(){ + List offerings = _vpcService.listVpcOfferings(getId(), getVpcOffName(), getDisplayText(), + getSupportedServices(), isDefault, this.getKeyword(), getState(), this.getStartIndex(), this.getPageSizeVal()); + ListResponse response = new ListResponse(); + List offeringResponses = new ArrayList(); + for (VpcOffering offering : offerings) { + VpcOfferingResponse offeringResponse = _responseGenerator.createVpcOfferingResponse(offering); + offeringResponses.add(offeringResponse); + } + + response.setResponses(offeringResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + + @Override + public String getCommandName() { + return _name; + } + +} diff --git a/api/src/com/cloud/api/commands/ListVPCsCmd.java b/api/src/com/cloud/api/commands/ListVPCsCmd.java new file mode 100644 index 00000000000..26064e79084 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVPCsCmd.java @@ -0,0 +1,158 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.BaseListAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.VpcResponse; +import com.cloud.network.vpc.Vpc; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Lists VPCs", responseObject=VpcResponse.class) +public class ListVPCsCmd extends BaseListAccountResourcesCmd{ + public static final Logger s_logger = Logger.getLogger(ListVPCsCmd.class.getName()); + private static final String s_name = "listvpcsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list VPC by id") + private Long id; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="list by zone") + private Long zoneId; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list by name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="List by display text of " + + "the VPC") + private String displayText; + + @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, description="list by cidr of the VPC. All VPC " + + "guest networks' cidrs should be within this CIDR") + private String cidr; + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.LONG, description="list by ID of the VPC offering") + private Long VpcOffId; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="list by account associated with the VPC. " + + "Must be used with the domainId parameter.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="list by domain ID associated with the VPC. " + + "If used with the account parameter returns the VPC associated with the account for the specified domain.") + private Long domainId; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, + description="list VPC supporting certain services") + private List supportedServices; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list VPCs by state") + private String state; + + @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list VPCs by restartRequired option") + private Boolean restartRequired; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getZoneId() { + return zoneId; + } + + public String getVpcName() { + return vpcName; + } + + public String getCidr() { + return cidr; + } + + public String getDisplayText() { + return displayText; + } + + public Long getVpcOffId() { + return VpcOffId; + } + + public Long getId() { + return id; + } + + public List getSupportedServices() { + return supportedServices; + } + + public String getState() { + return state; + } + + public Boolean getRestartRequired() { + return restartRequired; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() { + List vpcs = _vpcService.listVpcs(getId(), getVpcName(), getDisplayText(), + getSupportedServices(), getCidr(), getVpcOffId(), getState(), getAccountName(), getDomainId(), + this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getZoneId(), this.isRecursive(), + this.listAll(), getRestartRequired()); + ListResponse response = new ListResponse(); + List offeringResponses = new ArrayList(); + for (Vpc vpc : vpcs) { + VpcResponse offeringResponse = _responseGenerator.createVpcResponse(vpc); + offeringResponses.add(offeringResponse); + } + + response.setResponses(offeringResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java b/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java new file mode 100644 index 00000000000..e942bc4226f --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVpnConnectionsCmd.java @@ -0,0 +1,77 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.network.Site2SiteVpnConnection; + +@Implementation(description="Lists site to site vpn connection gateways", responseObject=Site2SiteVpnConnectionResponse.class) +public class ListVpnConnectionsCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger (ListVpnCustomerGatewaysCmd.class.getName()); + + private static final String s_name = "listvpnconnectionsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="s2s_vpn_connection") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="id of the vpn connection") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List conns = _s2sVpnService.searchForVpnConnections(this); + ListResponse response = new ListResponse(); + List connResponses = new ArrayList(); + if (conns != null && !conns.isEmpty()) { + for (Site2SiteVpnConnection conn : conns) { + Site2SiteVpnConnectionResponse site2SiteVpnConnectonRes = _responseGenerator.createSite2SiteVpnConnectionResponse(conn); + site2SiteVpnConnectonRes.setObjectName("vpnconnection"); + connResponses.add(site2SiteVpnConnectonRes); + } + } + response.setResponses(connResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java b/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java new file mode 100644 index 00000000000..4f1488b68c5 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVpnCustomerGatewaysCmd.java @@ -0,0 +1,77 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.network.Site2SiteCustomerGateway; + +@Implementation(description="Lists site to site vpn customer gateways", responseObject=Site2SiteCustomerGatewayResponse.class) +public class ListVpnCustomerGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger (ListVpnCustomerGatewaysCmd.class.getName()); + + private static final String s_name = "listvpncustomergatewaysresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="s2s_customer_gateway") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="id of the customer gateway") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List gws = _s2sVpnService.searchForCustomerGateways(this); + ListResponse response = new ListResponse(); + List gwResponses = new ArrayList(); + if (gws != null && !gws.isEmpty()) { + for (Site2SiteCustomerGateway gw : gws) { + Site2SiteCustomerGatewayResponse site2SiteCustomerGatewayRes = _responseGenerator.createSite2SiteCustomerGatewayResponse(gw); + site2SiteCustomerGatewayRes.setObjectName("vpncustomergateway"); + gwResponses.add(site2SiteCustomerGatewayRes); + } + } + response.setResponses(gwResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java b/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java new file mode 100644 index 00000000000..543110e8971 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVpnGatewaysCmd.java @@ -0,0 +1,77 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.BaseListProjectAndAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; +import com.cloud.network.Site2SiteVpnGateway; + +@Implementation(description="Lists site 2 site vpn gateways", responseObject=Site2SiteVpnGatewayResponse.class) +public class ListVpnGatewaysCmd extends BaseListProjectAndAccountResourcesCmd { + public static final Logger s_logger = Logger.getLogger (ListVpnGatewaysCmd.class.getName()); + + private static final String s_name = "listvpngatewaysresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="s2s_vpn_gateway") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="id of the vpn gateway") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute(){ + List gws = _s2sVpnService.searchForVpnGateways(this); + ListResponse response = new ListResponse(); + List gwResponses = new ArrayList(); + if (gws != null && !gws.isEmpty()) { + for (Site2SiteVpnGateway gw : gws) { + Site2SiteVpnGatewayResponse site2SiteVpnGatewayRes = _responseGenerator.createSite2SiteVpnGatewayResponse(gw); + site2SiteVpnGatewayRes.setObjectName("vpngateway"); + gwResponses.add(site2SiteVpnGatewayRes); + } + } + response.setResponses(gwResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/com/cloud/api/commands/ResetVpnConnectionCmd.java b/api/src/com/cloud/api/commands/ResetVpnConnectionCmd.java new file mode 100644 index 00000000000..e904fb0ed9f --- /dev/null +++ b/api/src/com/cloud/api/commands/ResetVpnConnectionCmd.java @@ -0,0 +1,117 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@Implementation(description="Reset site to site vpn connection", responseObject=Site2SiteVpnConnectionResponse.class) +public class ResetVpnConnectionCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(ResetVpnConnectionCmd.class.getName()); + + private static final String s_name = "resetvpnconnectionresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_vpn_connection") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of vpn connection") + private Long id; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for connection. Must be used with domainId.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for connection. If the account parameter is used, domainId must also be used.") + private Long domainId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_vpn_connection"; + } + + public Long getDomainId() { + return domainId; + } + + public Long getAccountId() { + return getEntityOwnerId(); + } + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Reset site-to-site VPN connection for account " + getEntityOwnerId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CONNECTION_RESET; + } + + @Override + public void execute(){ + try { + Site2SiteVpnConnection result = _s2sVpnService.resetVpnConnection(this); + if (result != null) { + Site2SiteVpnConnectionResponse response = _responseGenerator.createSite2SiteVpnConnectionResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to reset site to site VPN connection"); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } + } +} diff --git a/api/src/com/cloud/api/commands/RestartVPCCmd.java b/api/src/com/cloud/api/commands/RestartVPCCmd.java new file mode 100644 index 00000000000..c65b2615ef0 --- /dev/null +++ b/api/src/com/cloud/api/commands/RestartVPCCmd.java @@ -0,0 +1,99 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.api.response.VpcResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Restarts a VPC", responseObject=VpcResponse.class) +public class RestartVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName()); + private static final String _name = "restartvpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute(){ + try { + boolean result = _vpcService.restartVpc(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to restart VPC"); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } catch (InsufficientCapacityException ex) { + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_RESTART; + } + + @Override + public String getEventDescription() { + return "restarting VPC id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java index 27ba31b2565..319f58f946e 100755 --- a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java +++ b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java @@ -43,7 +43,8 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the network offering") private String displayText; - @Parameter(name=ApiConstants.AVAILABILITY, type=CommandType.STRING, description="the availability of network offering. Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering") + @Parameter(name=ApiConstants.AVAILABILITY, type=CommandType.STRING, description="the availability of network offering." + + " Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering") private String availability; @Parameter(name=ApiConstants.SORT_KEY, type=CommandType.INTEGER, description="sort key of the network offering, integer") diff --git a/api/src/com/cloud/api/commands/UpdateStorageNetworkIpRangeCmd.java b/api/src/com/cloud/api/commands/UpdateStorageNetworkIpRangeCmd.java index 47bc126bbe2..d70298236f6 100755 --- a/api/src/com/cloud/api/commands/UpdateStorageNetworkIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/UpdateStorageNetworkIpRangeCmd.java @@ -12,25 +12,26 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.api.commands; -import org.apache.log4j.Logger; +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.StorageNetworkIpRangeResponse; +import com.cloud.dc.StorageNetworkIpRange; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; -import com.cloud.api.ApiConstants; -import com.cloud.api.BaseAsyncCmd; -import com.cloud.api.BaseCmd; -import com.cloud.api.IdentityMapper; -import com.cloud.api.Implementation; -import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; -import com.cloud.api.response.StorageNetworkIpRangeResponse; -import com.cloud.dc.StorageNetworkIpRange; -import com.cloud.event.EventTypes; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.user.Account; - -@Implementation(description="Update a Storage network IP range, only allowed when no IPs in this range have been allocated.", responseObject=UpdateStorageNetworkIpRangeCmd.class, since="3.0.0") +@Implementation(description="Update a Storage network IP range, only allowed when no IPs in this range have been allocated.", +responseObject=StorageNetworkIpRangeResponse.class, since="3.0.0") public class UpdateStorageNetworkIpRangeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(UpdateStorageNetworkIpRangeCmd.class); private static final String s_name = "updatestoragenetworkiprangeresponse"; diff --git a/api/src/com/cloud/api/commands/UpdateVPCCmd.java b/api/src/com/cloud/api/commands/UpdateVPCCmd.java new file mode 100644 index 00000000000..b418d05fc61 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateVPCCmd.java @@ -0,0 +1,109 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Updates a VPC", responseObject=VpcResponse.class) +public class UpdateVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateVPCCmd.class.getName()); + private static final String _name = "updatevpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC") + private String displayText; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcName() { + return vpcName; + } + + public String getDisplayText() { + return displayText; + } + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute(){ + Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText()); + if (result != null) { + VpcResponse response = _responseGenerator.createVpcResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update VPC"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_UPDATE; + } + + @Override + public String getEventDescription() { + return "updating VPC id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java new file mode 100644 index 00000000000..390a2260d92 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java @@ -0,0 +1,111 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ + +@Implementation(description="Updates VPC offering", responseObject=VpcOfferingResponse.class) +public class UpdateVPCOfferingCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateVPCOfferingCmd.class.getName()); + private static final String _name = "updatevpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC offering") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC offering") + private String vpcOffName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC offering") + private String displayText; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the VPC offering; " + + "supported states - Enabled/Disabled") + private String state; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcOfferingName() { + return vpcOffName; + } + + public String getDisplayText() { + return displayText; + } + + public Long getId() { + return id; + } + + public String getState() { + return state; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + VpcOffering result = _vpcService.updateVpcOffering(getId(), getVpcOfferingName(), getDisplayText(), getState()); + if (result != null) { + VpcOfferingResponse response = _responseGenerator.createVpcOfferingResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update VPC offering"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_OFFERING_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating VPC offering id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/UpdateVpnCustomerGatewayCmd.java b/api/src/com/cloud/api/commands/UpdateVpnCustomerGatewayCmd.java new file mode 100644 index 00000000000..2c32fae25c9 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateVpnCustomerGatewayCmd.java @@ -0,0 +1,139 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +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.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.user.Account; + +@Implementation(description="Update site to site vpn customer gateway", responseObject=Site2SiteCustomerGatewayResponse.class) +public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(UpdateVpnCustomerGatewayCmd.class.getName()); + + private static final String s_name = "updatecustomergatewayresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="s2s_customer_gateway") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="id of customer gateway") + private Long id; + + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="public ip address id of the customer gateway") + private String gatewayIp; + + @Parameter(name=ApiConstants.GUEST_IP, type=CommandType.STRING, required=true, description="guest ip of the customer gateway") + private String guestIp; + + @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.STRING, required=true, description="guest cidr of the customer gateway") + private String guestCidrList; + + @Parameter(name=ApiConstants.IPSEC_PSK, type=CommandType.STRING, required=true, description="IPsec Preshared-Key of the customer gateway") + private String ipsecPsk; + + @Parameter(name=ApiConstants.IKE_POLICY, type=CommandType.STRING, required=true, description="IKE policy of the customer gateway") + private String ikePolicy; + + @Parameter(name=ApiConstants.ESP_POLICY, type=CommandType.STRING, required=true, description="ESP policy of the customer gateway") + private String espPolicy; + + @Parameter(name=ApiConstants.LIFETIME, type=CommandType.STRING, required=false, description="Lifetime of vpn connection to the customer gateway, in seconds") + private Long lifetime; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "s2s_customer_gateway"; + } + + public Long getId() { + return id; + } + + public String getIpsecPsk() { + return ipsecPsk; + } + + public String getGuestCidrList() { + return guestCidrList; + } + + public String getGuestIp() { + return guestIp; + } + + public String getGatewayIp() { + return gatewayIp; + } + + public String getIkePolicy() { + return ikePolicy; + } + + public String getEspPolicy() { + return espPolicy; + } + + public Long getLifetime() { + return lifetime; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public String getEventDescription() { + return "Update site-to-site VPN customer gateway"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_S2S_CUSTOMER_GATEWAY_UPDATE; + } + + @Override + public void execute(){ + Site2SiteCustomerGateway result = _s2sVpnService.updateCustomerGateway(this); + if (result != null) { + Site2SiteCustomerGatewayResponse response = _responseGenerator.createSite2SiteCustomerGatewayResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update customer VPN gateway"); + } + } +} diff --git a/api/src/com/cloud/api/response/DomainRouterResponse.java b/api/src/com/cloud/api/response/DomainRouterResponse.java index 10c50f5eeec..bd7e7d07d6f 100644 --- a/api/src/com/cloud/api/response/DomainRouterResponse.java +++ b/api/src/com/cloud/api/response/DomainRouterResponse.java @@ -15,8 +15,8 @@ package com.cloud.api.response; import java.util.Date; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.cloud.vm.VirtualMachine.State; import com.google.gson.annotations.SerializedName; @@ -133,6 +133,9 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti @SerializedName("scriptsversion") @Param(description="the version of scripts") private String scriptsVersion; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + @Override public Long getObjectId() { return getId(); @@ -301,4 +304,8 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/FirewallResponse.java b/api/src/com/cloud/api/response/FirewallResponse.java index 681bcfaf456..7b9243f1f63 100644 --- a/api/src/com/cloud/api/response/FirewallResponse.java +++ b/api/src/com/cloud/api/response/FirewallResponse.java @@ -13,10 +13,11 @@ package com.cloud.api.response; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; +@SuppressWarnings("unused") public class FirewallResponse extends BaseResponse { @SerializedName(ApiConstants.ID) @Param(description="the ID of the firewall rule") private IdentityProxy id = new IdentityProxy("firewall_rules"); @@ -30,10 +31,10 @@ public class FirewallResponse extends BaseResponse { @SerializedName(ApiConstants.END_PORT) @Param(description = "the ending port of firewall rule's port range") private String endPort; - @SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the port forwarding rule") + @SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the firewall rule") private Long publicIpAddressId; - @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the port forwarding rule") + @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the firewall rule") private String publicIpAddress; @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule") @@ -87,7 +88,4 @@ public class FirewallResponse extends BaseResponse { public void setIcmpCode(Integer icmpCode) { this.icmpCode = icmpCode; } - - - } diff --git a/api/src/com/cloud/api/response/IPAddressResponse.java b/api/src/com/cloud/api/response/IPAddressResponse.java index 9c803881c22..1113dd3a0b1 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -92,16 +92,10 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.PURPOSE) @Param(description="purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value") private String purpose; + + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the ip belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); -/* - @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") - private IdentityProxy jobId = new IdentityProxy("async_job"); -*/ - -/* - @SerializedName(ApiConstants.JOB_STATUS) @Param(description="shows the current pending asynchronous job status") - private Integer jobStatus; -*/ public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; @@ -212,4 +206,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setPurpose(String purpose) { this.purpose = purpose; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/NetworkACLResponse.java b/api/src/com/cloud/api/response/NetworkACLResponse.java new file mode 100644 index 00000000000..1338d89f57a --- /dev/null +++ b/api/src/com/cloud/api/response/NetworkACLResponse.java @@ -0,0 +1,84 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class NetworkACLResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the ID of the ACL") + private IdentityProxy id = new IdentityProxy("firewall_rules"); + + @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the ACL") + private String protocol; + + @SerializedName(ApiConstants.START_PORT) @Param(description="the starting port of ACL's port range") + private String startPort; + + @SerializedName(ApiConstants.END_PORT) @Param(description = "the ending port of ACL's port range") + private String endPort; + + @SerializedName(ApiConstants.TRAFFIC_TYPE) @Param(description="the traffic type for the ACL") + private String trafficType; + + @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule") + private String state; + + @SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from") + private String cidrList; + + @SerializedName(ApiConstants.ICMP_TYPE) @Param(description= "type of the icmp message being sent") + private Integer icmpType; + + @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message") + private Integer icmpCode; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public void setStartPort(String startPort) { + this.startPort = startPort; + } + + public void setEndPort(String endPort) { + this.endPort = endPort; + } + + public void setState(String state) { + this.state = state; + } + + public void setCidrList(String cidrList) { + this.cidrList = cidrList; + } + + public void setIcmpType(Integer icmpType) { + this.icmpType = icmpType; + } + + public void setIcmpCode(Integer icmpCode) { + this.icmpCode = icmpCode; + } + + public void setTrafficType(String trafficType) { + this.trafficType = trafficType; + } +} diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index 834248b8670..87eab0ce8fc 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -15,8 +15,8 @@ package com.cloud.api.response; import java.util.List; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.google.gson.annotations.SerializedName; @SuppressWarnings("unused") @@ -127,6 +127,12 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.SPECIFY_IP_RANGES) @Param(description="true if network supports specifying ip ranges, false otherwise") private Boolean specifyIpRanges; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.CAN_USE_FOR_DEPLOY) @Param(description="list networks available for vm deployment") + private Boolean canUseForDeploy; + public void setId(Long id) { this.id.setValue(id); } @@ -268,4 +274,12 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes public void setSpecifyIpRanges(Boolean specifyIpRanges) { this.specifyIpRanges = specifyIpRanges; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } + + public void setCanUseForDeploy(Boolean canUseForDeploy) { + this.canUseForDeploy = canUseForDeploy; + } } diff --git a/api/src/com/cloud/api/response/PrivateGatewayResponse.java b/api/src/com/cloud/api/response/PrivateGatewayResponse.java new file mode 100644 index 00000000000..52f1b0b887a --- /dev/null +++ b/api/src/com/cloud/api/response/PrivateGatewayResponse.java @@ -0,0 +1,133 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +/** + * @author Alena Prokharchyk + */ +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class PrivateGatewayResponse extends BaseResponse implements ControlledEntityResponse{ + + @SerializedName(ApiConstants.ID) @Param(description="the id of the private gateway") + private IdentityProxy id = new IdentityProxy("vpc_gateways"); + + @SerializedName(ApiConstants.GATEWAY) @Param(description="the gateway") + private String gateway; + + @SerializedName(ApiConstants.NETMASK) @Param(description="the private gateway's netmask") + private String netmask; + + @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the private gateway's ip address") + private String address; + + @SerializedName(ApiConstants.ZONE_ID) @Param(description="zone id of the private gateway") + private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone the private gateway belongs to") + private String zoneName; + + @SerializedName(ApiConstants.VLAN) @Param(description="the vlan of the private gateway") + private String vlan; + + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the private gateaway belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network id") + private IdentityProxy physicalNetworkId = new IdentityProxy("physical_network"); + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account associated with the private gateway") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the private gateway") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the private gateway") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the ID of the domain associated with the private gateway") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain associated with the private gateway") + private String domainName; + + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + public void setVlan(String vlan) { + this.vlan = vlan; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } + + public void setAddress(String address) { + this.address = address; + } + + public void setPhysicalNetworkId(Long physicalNetworkId) { + this.physicalNetworkId.setValue(physicalNetworkId); + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } +} + diff --git a/api/src/com/cloud/api/response/ResourceTagResponse.java b/api/src/com/cloud/api/response/ResourceTagResponse.java new file mode 100644 index 00000000000..aa69141113e --- /dev/null +++ b/api/src/com/cloud/api/response/ResourceTagResponse.java @@ -0,0 +1,100 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ + +@SuppressWarnings("unused") +public class ResourceTagResponse extends BaseResponse implements ControlledEntityResponse{ + @SerializedName(ApiConstants.KEY) @Param(description="tag key name") + private String key; + + @SerializedName(ApiConstants.VALUE) @Param(description="tag value") + private String value; + + @SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type") + private String resourceType; + + @SerializedName(ApiConstants.RESOURCE_ID) @Param(description="id of the resource") + private String id; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account associated with the tag") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id the tag belongs to") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name where tag belongs to") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the ID of the domain associated with the tag") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain associated with the tag") + private String domainName; + + @SerializedName(ApiConstants.CUSTOMER) @Param(description="customer associated with the tag") + private String customer; + + public void setKey(String key) { + this.key = key; + } + + public void setValue(String value) { + this.value = value; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public void setId(String id) { + this.id = id; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public void setCustomer(String customer) { + this.customer = customer; + } +} diff --git a/api/src/com/cloud/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/com/cloud/api/response/Site2SiteCustomerGatewayResponse.java new file mode 100644 index 00000000000..75fab2bcede --- /dev/null +++ b/api/src/com/cloud/api/response/Site2SiteCustomerGatewayResponse.java @@ -0,0 +1,65 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class Site2SiteCustomerGatewayResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the vpn gateway ID") + private IdentityProxy id = new IdentityProxy("s2s_vpn_gateway"); + + @SerializedName(ApiConstants.GATEWAY) @Param(description="public ip address id of the customer gateway") + private String gatewayIp; + + @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="guest ip of the customer gateway") + private String guestIp; + + @SerializedName(ApiConstants.CIDR_LIST) @Param(description="guest cidr list of the customer gateway") + private String guestCidrList; + + @SerializedName(ApiConstants.IPSEC_PSK) @Param(description="IPsec preshared-key of customer gateway") + private String ipsecPsk; + + @SerializedName(ApiConstants.REMOVED) @Param(description="the date and time the host was removed") + private Date removed; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + } + + public void setGuestIp(String guestIp) { + this.guestIp = guestIp; + } + + public void setGuestCidrList(String guestCidrList) { + this.guestCidrList = guestCidrList; + } + + public void setIpsecPsk(String ipsecPsk) { + this.ipsecPsk = ipsecPsk; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } +} diff --git a/api/src/com/cloud/api/response/Site2SiteVpnConnectionResponse.java b/api/src/com/cloud/api/response/Site2SiteVpnConnectionResponse.java new file mode 100644 index 00000000000..41508202cfd --- /dev/null +++ b/api/src/com/cloud/api/response/Site2SiteVpnConnectionResponse.java @@ -0,0 +1,59 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class Site2SiteVpnConnectionResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the vpn gateway ID") + private IdentityProxy id = new IdentityProxy("s2s_vpn_gateway"); + + @SerializedName(ApiConstants.S2S_VPN_GATEWAY_ID) @Param(description="the vpn gateway ID") + private IdentityProxy vpnGatewayId= new IdentityProxy("s2s_vpn_gateway"); + + @SerializedName(ApiConstants.S2S_CUSTOMER_GATEWAY_ID) @Param(description="the customer gateway ID") + private IdentityProxy customerGatewayId = new IdentityProxy("s2s_customer_gateway"); + + @SerializedName(ApiConstants.CREATED) @Param(description="the date and time the host was created") + private Date created; + + @SerializedName(ApiConstants.REMOVED) @Param(description="the date and time the host was removed") + private Date removed; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setVpnGatewayId(Long vpnGatewayId) { + this.vpnGatewayId.setValue(vpnGatewayId); + } + + public void setCustomerGatewayId(Long customerGatewayId) { + this.customerGatewayId.setValue(customerGatewayId); + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + +} diff --git a/api/src/com/cloud/api/response/Site2SiteVpnGatewayResponse.java b/api/src/com/cloud/api/response/Site2SiteVpnGatewayResponse.java new file mode 100644 index 00000000000..529288c18d5 --- /dev/null +++ b/api/src/com/cloud/api/response/Site2SiteVpnGatewayResponse.java @@ -0,0 +1,44 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; + +import com.cloud.api.ApiConstants; +import com.cloud.utils.IdentityProxy; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("unused") +public class Site2SiteVpnGatewayResponse extends BaseResponse { + @SerializedName(ApiConstants.ID) @Param(description="the vpn gateway ID") + private IdentityProxy id = new IdentityProxy("s2s_vpn_gateway"); + + @SerializedName(ApiConstants.PUBLIC_IP) @Param(description="the public IP address") + private String ip; + + @SerializedName(ApiConstants.REMOVED) @Param(description="the date and time the host was removed") + private Date removed; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setIp(String ip) { + this.ip = ip; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } +} diff --git a/api/src/com/cloud/api/response/StaticRouteResponse.java b/api/src/com/cloud/api/response/StaticRouteResponse.java new file mode 100644 index 00000000000..025be6e0b82 --- /dev/null +++ b/api/src/com/cloud/api/response/StaticRouteResponse.java @@ -0,0 +1,102 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ +@SuppressWarnings("unused") +public class StaticRouteResponse extends BaseResponse implements ControlledEntityResponse{ + @SerializedName(ApiConstants.ID) @Param(description="the ID of static route") + private IdentityProxy id = new IdentityProxy("static_routes"); + + @SerializedName(ApiConstants.STATE) @Param(description="the state of the static route") + private String state; + + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the static route belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.GATEWAY_ID) @Param(description="VPC gateway the route is created for") + private IdentityProxy gatewayId = new IdentityProxy("vpc_gateways"); + + @SerializedName(ApiConstants.CIDR) @Param(description="static route CIDR") + private String cidr; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account associated with the static route") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the static route") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the static route") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the ID of the domain associated with the static route") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain associated with the static route") + private String domainName; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setState(String state) { + this.state = state; + } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } + + public void setGatewayId(Long gatewayId) { + this.gatewayId.setValue(gatewayId); + } + + public void setCidr(String cidr) { + this.cidr = cidr; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } +} diff --git a/api/src/com/cloud/api/response/VolumeResponse.java b/api/src/com/cloud/api/response/VolumeResponse.java index cb393f6e787..5318c1e8df9 100755 --- a/api/src/com/cloud/api/response/VolumeResponse.java +++ b/api/src/com/cloud/api/response/VolumeResponse.java @@ -288,5 +288,5 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp @Override public void setProjectName(String projectName) { this.projectName = projectName; - } + } } diff --git a/api/src/com/cloud/api/response/VpcOfferingResponse.java b/api/src/com/cloud/api/response/VpcOfferingResponse.java new file mode 100644 index 00000000000..8fe536181a1 --- /dev/null +++ b/api/src/com/cloud/api/response/VpcOfferingResponse.java @@ -0,0 +1,77 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ +@SuppressWarnings("unused") +public class VpcOfferingResponse extends BaseResponse{ + @SerializedName("id") @Param(description="the id of the vpc offering") + private final IdentityProxy id = new IdentityProxy("vpc_offerings"); + + @SerializedName(ApiConstants.NAME) @Param(description="the name of the vpc offering") + private String name; + + @SerializedName(ApiConstants.DISPLAY_TEXT) @Param(description="an alternate display text of the vpc offering.") + private String displayText; + + @SerializedName(ApiConstants.CREATED) @Param(description="the date this vpc offering was created") + private Date created; + + @SerializedName(ApiConstants.IS_DEFAULT) @Param(description="true if vpc offering is default, false otherwise") + private Boolean isDefault; + + @SerializedName(ApiConstants.STATE) @Param(description="state of the vpc offering. Can be Disabled/Enabled") + private String state; + + @SerializedName(ApiConstants.SERVICE) @Param(description="the list of supported services", responseObject = ServiceResponse.class) + private List services; + + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + public void setServices(List services) { + this.services = services; + } + + public void setState(String state) { + this.state = state; + } +} diff --git a/api/src/com/cloud/api/response/VpcResponse.java b/api/src/com/cloud/api/response/VpcResponse.java new file mode 100644 index 00000000000..ae5b33d7043 --- /dev/null +++ b/api/src/com/cloud/api/response/VpcResponse.java @@ -0,0 +1,156 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ + +@SuppressWarnings("unused") +public class VpcResponse extends BaseResponse implements ControlledEntityResponse{ + @SerializedName("id") @Param(description="the id of the VPC") + private final IdentityProxy id = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.NAME) @Param(description="the name of the VPC") + private String name; + + @SerializedName(ApiConstants.DISPLAY_TEXT) @Param(description="an alternate display text of the VPC.") + private String displayText; + + @SerializedName(ApiConstants.STATE) @Param(description="state of the VPC. Can be Inactive/Enabled") + private String state; + + @SerializedName(ApiConstants.ZONE_ID) @Param(description="zone id of the vpc") + private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.SERVICE) @Param(description="the list of supported services", responseObject = ServiceResponse.class) + private List services; + + @SerializedName(ApiConstants.CIDR) @Param(description="the cidr the VPC") + private String cidr; + + @SerializedName(ApiConstants.VPC_OFF_ID) @Param(description="vpc offering id the VPC is created from") + private IdentityProxy vpcOfferingId = new IdentityProxy("vpc_offerings"); + + @SerializedName(ApiConstants.CREATED) @Param(description="the date this VPC was created") + private Date created; + + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the VPC") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the VPC") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the VPC") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the VPC owner") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the owner") + private String domain; + + @SerializedName(ApiConstants.NETWORK) @Param(description="the list of networks belongign to the VPC", responseObject = NetworkResponse.class) + private List networks; + + @SerializedName(ApiConstants.RESTART_REQUIRED) @Param(description="true network requires restart") + private Boolean restartRequired; + + @SerializedName(ApiConstants.NETWORK_DOMAIN) @Param(description="the network domain") + private String networkDomain; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setServices(List services) { + this.services = services; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domain = domainName; + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + public void setCidr(String cidr) { + this.cidr = cidr; + } + + public void setVpcOfferingId(Long vpcOfferingId) { + this.vpcOfferingId.setValue(vpcOfferingId); + } + + public List getNetworks() { + return networks; + } + + public void setNetworks(List networks) { + this.networks = networks; + } + + public void setRestartRequired(Boolean restartRequired) { + this.restartRequired = restartRequired; + } + + public void setNetworkDomain(String networkDomain) { + this.networkDomain = networkDomain; + } +} diff --git a/api/src/com/cloud/async/AsyncJob.java b/api/src/com/cloud/async/AsyncJob.java index 04ecb8f8972..32fa9ac38b2 100644 --- a/api/src/com/cloud/async/AsyncJob.java +++ b/api/src/com/cloud/async/AsyncJob.java @@ -36,7 +36,9 @@ public interface AsyncJob extends Identity { PhysicalNetworkServiceProvider, FirewallRule, Account, - User + User, + PrivateGateway, + StaticRoute } Long getId(); diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index eedf5462400..5516751370a 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -196,6 +196,14 @@ public class EventTypes { public static final String EVENT_REMOTE_ACCESS_VPN_DESTROY = "VPN.REMOTE.ACCESS.DESTROY"; public static final String EVENT_VPN_USER_ADD = "VPN.USER.ADD"; public static final String EVENT_VPN_USER_REMOVE = "VPN.USER.REMOVE"; + public static final String EVENT_S2S_VPN_GATEWAY_CREATE = "VPN.S2S.VPN.GATEWAY.CREATE"; + public static final String EVENT_S2S_VPN_GATEWAY_DELETE = "VPN.S2S.VPN.GATEWAY.DELETE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_CREATE = "VPN.S2S.CUSTOMER.GATEWAY.CREATE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_DELETE = "VPN.S2S.CUSTOMER.GATEWAY.DELETE"; + public static final String EVENT_S2S_CUSTOMER_GATEWAY_UPDATE = "VPN.S2S.CUSTOMER.GATEWAY.UPDATE"; + public static final String EVENT_S2S_CONNECTION_CREATE = "VPN.S2S.CONNECTION.CREATE"; + public static final String EVENT_S2S_CONNECTION_DELETE = "VPN.S2S.CONNECTION.DELETE"; + public static final String EVENT_S2S_CONNECTION_RESET = "VPN.S2S.CONNECTION.RESET"; // Network public static final String EVENT_NETWORK_RESTART = "NETWORK.RESTART"; @@ -255,4 +263,27 @@ public class EventTypes { public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_ADD = "PHYSICAL.FIREWALL.ADD"; public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE = "PHYSICAL.FIREWALL.DELETE"; public static final String EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE = "PHYSICAL.FIREWALL.CONFIGURE"; + + // tag related events + public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; + public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; + + // VPC + public static final String EVENT_VPC_CREATE = "VPC.CREATE"; + public static final String EVENT_VPC_UPDATE = "VPC.UPDATE"; + public static final String EVENT_VPC_DELETE = "VPC.DELETE"; + public static final String EVENT_VPC_RESTART = "VPC.RESTART"; + + // VPC offerings + public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE"; + public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE"; + public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE"; + + // Private gateway + public static final String EVENT_PRIVATE_GATEWAY_CREATE = "PRIVATE.GATEWAY.CREATE"; + public static final String EVENT_PRIVATE_GATEWAY_DELETE = "PRIVATE.GATEWAY.DELETE"; + + // Static routes + public static final String EVENT_STATIC_ROUTE_CREATE = "STATIC.ROUTE.CREATE"; + public static final String EVENT_STATIC_ROUTE_DELETE = "STATIC.ROUTE.DELETE"; } diff --git a/api/src/com/cloud/exception/CloudException.java b/api/src/com/cloud/exception/CloudException.java index 94ba8ea6c58..8a30a866bd5 100644 --- a/api/src/com/cloud/exception/CloudException.java +++ b/api/src/com/cloud/exception/CloudException.java @@ -1,73 +1,88 @@ -/** - * Copyright (C) 2011 Citrix Systems, 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.exception; - -import com.cloud.utils.IdentityProxy; -import java.util.ArrayList; -import com.cloud.utils.exception.CSExceptionErrorCode; - -/** - * CloudException is a generic exception class that has an IdentityProxy - * object in it to enable on the fly conversion of database ids to uuids - * by the API response serializer. Any exceptions that are thrown by - * command invocations must extend this class, or the RuntimeCloudException - * class, which extends RuntimeException instead of Exception like this - * class does. - */ - -public class CloudException extends Exception { - - // This holds a list of uuids and their names. Add uuid:fieldname pairs - // if required, to this list before throwing an exception, using addProxyObject(). - protected ArrayList idList = new ArrayList(); - - // This holds an error code. Set this before throwing an exception, if applicable. - protected Integer csErrorCode; - - public CloudException(String message) { - super(message); - setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); - } - - public CloudException(String message, Throwable cause) { - super(message, cause); - setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); - } - - public CloudException() { - super(); - setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); - } - - public void addProxyObject(String tableName, Long id, String idFieldName) { - idList.add(new IdentityProxy(tableName, id, idFieldName)); - return; - } - - public ArrayList getIdProxyList() { - return idList; - } - - public void setCSErrorCode(int cserrcode) { - this.csErrorCode = cserrcode; - } - - public int getCSErrorCode() { - return this.csErrorCode; - } -} +/** + * Copyright (C) 2011 Citrix Systems, 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.exception; + +import java.util.ArrayList; + +import com.cloud.utils.AnnotationHelper; +import com.cloud.utils.IdentityProxy; +import com.cloud.utils.exception.CSExceptionErrorCode; + +/** + * CloudException is a generic exception class that has an IdentityProxy + * object in it to enable on the fly conversion of database ids to uuids + * by the API response serializer. Any exceptions that are thrown by + * command invocations must extend this class, or the RuntimeCloudException + * class, which extends RuntimeException instead of Exception like this + * class does. + */ + +public class CloudException extends Exception { + + // This holds a list of uuids and their names. Add uuid:fieldname pairs + // if required, to this list before throwing an exception, using addProxyObject(). + protected ArrayList idList = new ArrayList(); + + // This holds an error code. Set this before throwing an exception, if applicable. + protected Integer csErrorCode; + + public CloudException(String message) { + super(message); + setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); + } + + public CloudException(String message, Throwable cause) { + super(message, cause); + setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); + } + + public void addProxyObject(Object voObj, Long id, String idFieldName) { + // Get the VO object's table name. + if (voObj != null) { + String tablename = AnnotationHelper.getTableName(voObj); + if (tablename != null) { + addProxyObject(tablename, id, idFieldName); + } + } + return; + } + + public CloudException() { + super(); + setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName())); + } + + public void addProxyObject(String tableName, Long id, String idFieldName) { + if (tableName != null) { + idList.add(new IdentityProxy(tableName, id, idFieldName)); + } + return; + } + + public ArrayList getIdProxyList() { + return idList; + } + + public void setCSErrorCode(int cserrcode) { + this.csErrorCode = cserrcode; + } + + public int getCSErrorCode() { + return this.csErrorCode; + } +} diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java index 8d869d74fab..09cc3673e7a 100644 --- a/api/src/com/cloud/hypervisor/HypervisorGuru.java +++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java @@ -13,9 +13,11 @@ package com.cloud.hypervisor; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.component.Adapter; +import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -45,4 +47,10 @@ public interface HypervisorGuru extends Adapter { * */ boolean trackVmHostChange(); + + /** + * @param profile + * @return + */ + NicTO toNicTO(NicProfile profile); } diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 0a4c2e4671d..416dcb7f919 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -76,4 +76,14 @@ public interface IpAddress extends ControlledEntity { boolean getSystem(); + /** + * @return + */ + Long getVpcId(); + + /** + * @param vpcId + */ + void setVpcId(Long vpcId); + } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index e8394961b2b..17ea4e72c61 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -37,12 +37,15 @@ public interface Network extends ControlledEntity { public static class Service { private static List supportedServices = new ArrayList(); - public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnTypes); + public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes); public static final Service Dhcp = new Service("Dhcp"); public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification); public static final Service Gateway = new Service("Gateway"); - public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, Capability.MultipleIps, Capability.TrafficStatistics); - public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, Capability.SupportedStickinessMethods, Capability.ElasticLb); + public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, + Capability.MultipleIps, Capability.TrafficStatistics, Capability.FirewallType); + public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, + Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, + Capability.SupportedStickinessMethods, Capability.ElasticLb); public static final Service UserData = new Service("UserData"); public static final Service SourceNat = new Service("SourceNat", Capability.SupportedSourceNatTypes, Capability.RedundantRouter); public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp); @@ -109,6 +112,7 @@ public interface Network extends ControlledEntity { public static final Provider ExternalGateWay = new Provider("ExternalGateWay", true); public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm", false); public static final Provider SecurityGroupProvider = new Provider("SecurityGroupProvider", false); + public static final Provider VPCVirtualRouter = new Provider("VpcVirtualRouter", false); public static final Provider None = new Provider("None", false); private String name; @@ -148,13 +152,15 @@ public interface Network extends ControlledEntity { public static final Capability SupportedStickinessMethods = new Capability("SupportedStickinessMethods"); public static final Capability MultipleIps = new Capability("MultipleIps"); public static final Capability SupportedSourceNatTypes = new Capability("SupportedSourceNatTypes"); - public static final Capability SupportedVpnTypes = new Capability("SupportedVpnTypes"); + public static final Capability SupportedVpnProtocols = new Capability("SupportedVpnTypes"); + public static final Capability VpnTypes = new Capability("VpnTypes"); public static final Capability TrafficStatistics = new Capability("TrafficStatistics"); public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps"); public static final Capability AllowDnsSuffixModification = new Capability("AllowDnsSuffixModification"); public static final Capability RedundantRouter = new Capability("RedundantRouter"); public static final Capability ElasticIp = new Capability("ElasticIp"); public static final Capability ElasticLb = new Capability("ElasticLb"); + public static final Capability FirewallType = new Capability("FirewallType"); private String name; @@ -279,4 +285,9 @@ public interface Network extends ControlledEntity { boolean isRestartRequired(); boolean getSpecifyIpRanges(); + + /** + * @return + */ + Long getVpcId(); } diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java index 8c965e12abe..065529c4dfa 100644 --- a/api/src/com/cloud/network/NetworkProfile.java +++ b/api/src/com/cloud/network/NetworkProfile.java @@ -43,6 +43,7 @@ public class NetworkProfile implements Network { private ACLType aclType; private boolean restartRequired; private boolean specifyIpRanges; + private Long vpcId; public NetworkProfile(Network network) { this.id = network.getId(); @@ -67,6 +68,7 @@ public class NetworkProfile implements Network { this.aclType = network.getAclType(); this.restartRequired = network.isRestartRequired(); this.specifyIpRanges = network.getSpecifyIpRanges(); + this.vpcId = network.getVpcId(); } public String getDns1() { @@ -206,4 +208,9 @@ public class NetworkProfile implements Network { return false; } + @Override + public Long getVpcId() { + return vpcId; + } + } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 048d7145b6f..d0754f171cb 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -37,28 +37,21 @@ public interface NetworkService { List getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner); - IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException; - /** - * Associates a public IP address for a router. - * - * @param ipId - * - the command specifying ipAddress - * @return ip address object - * @throws ResourceAllocationException - * , InsufficientCapacityException - */ - IpAddress associateIP(long ipId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException; + IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, + InsufficientAddressCapacityException, ConcurrentOperationException; - boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; + boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; - Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException; + Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, + ResourceAllocationException; List searchForNetworks(ListNetworksCmd cmd); boolean deleteNetwork(long networkId); - boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; int getActiveNicsInNetwork(long networkId); @@ -74,7 +67,8 @@ public interface NetworkService { Long getDedicatedNetworkDomain(long networkId); - Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId, Boolean changeCidr); + Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, + String domainSuffix, Long networkOfferingId, Boolean changeCidr); Integer getNetworkRate(long networkId, Long vmId); @@ -82,11 +76,14 @@ public interface NetworkService { Map> getNetworkOfferingServiceProvidersMap(long networkOfferingId); - PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRange, Long domainId, List tags, String name); + PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, + List isolationMethods, String broadcastDomainRange, Long domainId, List tags, String name); - List searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name); + List searchPhysicalNetworks(Long id, Long zoneId, String keyword, + Long startIndex, Long pageSize, String name); - PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List tags, String newVnetRangeString, String state); + PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List tags, + String newVnetRangeString, String state); boolean deletePhysicalNetwork(Long id); @@ -94,9 +91,11 @@ public interface NetworkService { List listSupportedNetworkServiceProviders(String serviceName); - PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId, List enabledServices); + PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, + Long destinationPhysicalNetworkId, List enabledServices); - List listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize); + List listNetworkServiceProviders(Long physicalNetworkId, String name, + String state, Long startIndex, Long pageSize); PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List enabledServices); @@ -112,7 +111,8 @@ public interface NetworkService { long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType); - PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan); + PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, + String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan); PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id); @@ -130,4 +130,45 @@ public interface NetworkService { List getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner); + List listNetworksByVpc(long vpcId); + + boolean isVmPartOfNetwork(long vmId, long ntwkId); + + /** + * @param entityId + * @param networkId + * @param vpcId + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws ResourceAllocationException + * @throws InsufficientAddressCapacityException + */ + IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, + ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException; + + /** + * @param networkName + * @param displayText + * @param physicalNetworkId + * @param vlan + * @param startIp + * @param endIP TODO + * @param gateway + * @param netmask + * @param networkOwnerId + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceAllocationException + */ + Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, + String startIp, String endIP, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException; + /** + * @param network + * @return + */ + boolean canUseForDeploy(Network network); + } diff --git a/api/src/com/cloud/network/Site2SiteCustomerGateway.java b/api/src/com/cloud/network/Site2SiteCustomerGateway.java new file mode 100644 index 00000000000..0dbda6523c5 --- /dev/null +++ b/api/src/com/cloud/network/Site2SiteCustomerGateway.java @@ -0,0 +1,11 @@ +package com.cloud.network; + +import java.util.Date; + +public interface Site2SiteCustomerGateway { + public long getId(); + public String getGatewayIp(); + public String getGuestCidrList(); + public String getIpsecPsk(); + public Date getRemoved(); +} diff --git a/api/src/com/cloud/network/Site2SiteVpnConnection.java b/api/src/com/cloud/network/Site2SiteVpnConnection.java new file mode 100644 index 00000000000..d5a615ff0b0 --- /dev/null +++ b/api/src/com/cloud/network/Site2SiteVpnConnection.java @@ -0,0 +1,18 @@ +package com.cloud.network; + +import java.util.Date; + +public interface Site2SiteVpnConnection { + enum State { + Pending, + Connected, + Disconnected, + Error, + } + public long getId(); + public long getVpnGatewayId(); + public long getCustomerGatewayId(); + public State getState(); + public Date getCreated(); + public Date getRemoved(); +} diff --git a/api/src/com/cloud/network/Site2SiteVpnGateway.java b/api/src/com/cloud/network/Site2SiteVpnGateway.java new file mode 100644 index 00000000000..19ec7425641 --- /dev/null +++ b/api/src/com/cloud/network/Site2SiteVpnGateway.java @@ -0,0 +1,9 @@ +package com.cloud.network; + +import java.util.Date; + +public interface Site2SiteVpnGateway { + public long getId(); + public long getAddrId(); + public Date getRemoved(); +} diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index 0a964b4dcee..8ef4dd814e3 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -26,7 +26,8 @@ public interface VirtualNetworkApplianceService { * the command specifying router's id * @return DomainRouter object */ - VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; /** * Reboots domain router @@ -35,7 +36,8 @@ public interface VirtualNetworkApplianceService { * the command specifying router's id * @return router if successful */ - VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; VirtualRouter upgradeRouter(UpgradeRouterCmd cmd); @@ -55,4 +57,5 @@ public interface VirtualNetworkApplianceService { VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException; VirtualRouter destroyRouter(long routerId) throws ResourceUnavailableException, ConcurrentOperationException; + } diff --git a/api/src/com/cloud/network/VirtualRouterProvider.java b/api/src/com/cloud/network/VirtualRouterProvider.java index 81eaf1e3c68..f6d416faa6b 100644 --- a/api/src/com/cloud/network/VirtualRouterProvider.java +++ b/api/src/com/cloud/network/VirtualRouterProvider.java @@ -15,7 +15,8 @@ package com.cloud.network; public interface VirtualRouterProvider { public enum VirtualRouterProviderType { VirtualRouter, - ElasticLoadBalancerVm + ElasticLoadBalancerVm, + VPCVirtualRouter } public VirtualRouterProviderType getType(); diff --git a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java new file mode 100644 index 00000000000..078d4053534 --- /dev/null +++ b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java @@ -0,0 +1,48 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; + +/** + * @author Alena Prokharchyk + */ +public interface VpcVirtualNetworkApplianceService { + + /** + * @param router + * @param network + * @param isRedundant + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientCapacityException + */ + boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param router + * @param network + * @param isRedundant + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean removeRouterFromGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException; + +} diff --git a/api/src/com/cloud/network/element/NetworkACLServiceProvider.java b/api/src/com/cloud/network/element/NetworkACLServiceProvider.java new file mode 100644 index 00000000000..92c4bb4eb78 --- /dev/null +++ b/api/src/com/cloud/network/element/NetworkACLServiceProvider.java @@ -0,0 +1,34 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.element; + +import java.util.List; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.rules.FirewallRule; + +/** + * @author Alena Prokharchyk + */ +public interface NetworkACLServiceProvider extends NetworkElement{ + + /** + * @param config + * @param rules + * @return + * @throws ResourceUnavailableException + */ + boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException; + +} diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index e18a34f6308..c6845d3d346 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -52,7 +52,8 @@ public interface NetworkElement extends Adapter { * @return true if network configuration is now usable; false if not; null if not handled by this element. * @throws InsufficientNetworkCapacityException TODO */ - boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; /** * Prepare for a nic to be added into this network. @@ -66,7 +67,9 @@ public interface NetworkElement extends Adapter { * @throws ResourceUnavailableException * @throws InsufficientNetworkCapacityException */ - boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; /** * A nic is released from this network. @@ -78,7 +81,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being shutdown. @@ -89,7 +93,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being destroyed. @@ -114,7 +119,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException; /** * This should return true if out of multiple services provided by this element, only some can be enabled. If all the services MUST be provided, this should return false. diff --git a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java new file mode 100644 index 00000000000..0dc4a5ad190 --- /dev/null +++ b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java @@ -0,0 +1,11 @@ +package com.cloud.network.element; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Site2SiteVpnConnection; + +public interface Site2SiteVpnServiceProvider extends NetworkElement { + boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException; + + boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException; +} diff --git a/api/src/com/cloud/network/element/UserDataServiceProvider.java b/api/src/com/cloud/network/element/UserDataServiceProvider.java index 59c64bb965d..7ffbe9548a0 100644 --- a/api/src/com/cloud/network/element/UserDataServiceProvider.java +++ b/api/src/com/cloud/network/element/UserDataServiceProvider.java @@ -17,7 +17,6 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.uservm.UserVm; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; diff --git a/api/src/com/cloud/network/element/VirtualRouterElementService.java b/api/src/com/cloud/network/element/VirtualRouterElementService.java index dc4e510259a..32139be141e 100644 --- a/api/src/com/cloud/network/element/VirtualRouterElementService.java +++ b/api/src/com/cloud/network/element/VirtualRouterElementService.java @@ -17,11 +17,12 @@ import java.util.List; import com.cloud.api.commands.ConfigureVirtualRouterElementCmd; import com.cloud.api.commands.ListVirtualRouterElementsCmd; import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.utils.component.PluggableService; public interface VirtualRouterElementService extends PluggableService{ VirtualRouterProvider configure(ConfigureVirtualRouterElementCmd cmd); - VirtualRouterProvider addElement(Long nspId); + VirtualRouterProvider addElement(Long nspId, VirtualRouterProviderType providerType); VirtualRouterProvider getCreatedElement(long id); List searchForVirtualRouterElement(ListVirtualRouterElementsCmd cmd); } diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/com/cloud/network/element/VpcProvider.java new file mode 100644 index 00000000000..3e369b3e721 --- /dev/null +++ b/api/src/com/cloud/network/element/VpcProvider.java @@ -0,0 +1,53 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.element; + + +import java.util.List; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.vm.ReservationContext; + +/** + * @author Alena Prokharchyk + */ +public interface VpcProvider extends NetworkElement{ + /** + * Start vpc element as specified + * @param vpc fully specified vpc configuration. + * @throws InsufficientNetworkCapacityException TODO + */ + boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + + boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException; + + boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException; + + boolean applyStaticRoutes(Vpc vpc, List routes) throws ResourceUnavailableException; +} diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java new file mode 100644 index 00000000000..3cdb0583aae --- /dev/null +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -0,0 +1,47 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.firewall; + +import java.util.List; + +import com.cloud.api.commands.ListNetworkACLsCmd; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.rules.NetworkACL; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public interface NetworkACLService { + NetworkACL getNetworkACL(long ruleId); + boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException; + + /** + * @param createNetworkACLCmd + * @return + */ + NetworkACL createNetworkACL(NetworkACL acl) throws NetworkRuleConflictException; + /** + * @param ruleId + * @param apply + * @return + */ + boolean revokeNetworkACL(long ruleId, boolean apply); + /** + * @param listNetworkACLsCmd + * @return + */ + List listNetworkACLs(ListNetworkACLsCmd cmd); + +} diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java index e0aa9013d96..0ef55a16afe 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRule.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -74,7 +74,7 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{ } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return lb.getSourceIpAddressId(); } diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index 34ed9c12445..2ab2a5deafb 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -30,8 +30,11 @@ public interface VirtualRouter extends VirtualMachine { FAULT } RedundantState getRedundantState(); - String getGuestIpAddress(); String getPublicIpAddress(); boolean isStopPending(); void setStopPending(boolean stopPending); + /** + * @return + */ + Long getVpcId(); } diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java index 807dbe3f22a..b3b90a94567 100644 --- a/api/src/com/cloud/network/rules/FirewallRule.java +++ b/api/src/com/cloud/network/rules/FirewallRule.java @@ -23,6 +23,7 @@ public interface FirewallRule extends ControlledEntity { LoadBalancing, Vpn, StaticNat, + NetworkACL, } enum FirewallRuleType { @@ -37,6 +38,11 @@ public interface FirewallRule extends ControlledEntity { Revoke // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. } + enum TrafficType { + Ingress, + Egress + } + /** * @return database id. */ @@ -68,7 +74,7 @@ public interface FirewallRule extends ControlledEntity { long getNetworkId(); - long getSourceIpAddressId(); + Long getSourceIpAddressId(); Integer getIcmpCode(); diff --git a/api/src/com/cloud/network/rules/NetworkACL.java b/api/src/com/cloud/network/rules/NetworkACL.java new file mode 100644 index 00000000000..d0f7f21eca0 --- /dev/null +++ b/api/src/com/cloud/network/rules/NetworkACL.java @@ -0,0 +1,26 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.rules; + + +/** + * @author Alena Prokharchyk + */ +public interface NetworkACL extends FirewallRule{ + + /** + * @return + */ + TrafficType getTrafficType(); + +} diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java index cde28dbfd52..28db9dc385d 100644 --- a/api/src/com/cloud/network/rules/RulesService.java +++ b/api/src/com/cloud/network/rules/RulesService.java @@ -60,7 +60,7 @@ public interface RulesService { boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException; - boolean enableStaticNat(long ipAddressId, long vmId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException; + boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException; PortForwardingRule getPortForwardigRule(long ruleId); diff --git a/api/src/com/cloud/network/rules/StaticNatRule.java b/api/src/com/cloud/network/rules/StaticNatRule.java index acc1539f85d..bc401b0c8da 100644 --- a/api/src/com/cloud/network/rules/StaticNatRule.java +++ b/api/src/com/cloud/network/rules/StaticNatRule.java @@ -36,7 +36,7 @@ public interface StaticNatRule extends ControlledEntity, FirewallRule { long getNetworkId(); - long getSourceIpAddressId(); + Long getSourceIpAddressId(); String getDestIpAddress(); } diff --git a/api/src/com/cloud/network/vpc/PrivateGateway.java b/api/src/com/cloud/network/vpc/PrivateGateway.java new file mode 100644 index 00000000000..d23b1b4c5b1 --- /dev/null +++ b/api/src/com/cloud/network/vpc/PrivateGateway.java @@ -0,0 +1,20 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +/** + * @author Alena Prokharchyk + */ +public interface PrivateGateway extends VpcGateway{ + long getPhysicalNetworkId(); +} diff --git a/api/src/com/cloud/network/vpc/PrivateIp.java b/api/src/com/cloud/network/vpc/PrivateIp.java new file mode 100644 index 00000000000..771a2aa6386 --- /dev/null +++ b/api/src/com/cloud/network/vpc/PrivateIp.java @@ -0,0 +1,45 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +/** + * @author Alena Prokharchyk + */ +public interface PrivateIp { + + /** + * @return + */ + String getIpAddress(); + + /** + * @return + */ + String getVlanTag(); + + /** + * @return + */ + String getGateway(); + + /** + * @return + */ + String getNetmask(); + + /** + * @return + */ + String getMacAddress(); + +} diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/com/cloud/network/vpc/StaticRoute.java new file mode 100644 index 00000000000..eb4d7670527 --- /dev/null +++ b/api/src/com/cloud/network/vpc/StaticRoute.java @@ -0,0 +1,55 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import com.cloud.acl.ControlledEntity; + + +/** + * @author Alena Prokharchyk + */ +public interface StaticRoute extends ControlledEntity{ + enum State { + Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router. + Add, // Add means the route has been created and has gone through network rule conflict detection. + Active, // Route has been sent to the VPC router and reported to be active. + Revoke // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + } + + /** + * @return + */ + long getVpcGatewayId(); + + /** + * @return + */ + String getCidr(); + + /** + * @return + */ + State getState(); + + /** + * @return + */ + Long getVpcId(); + + /** + * @return + */ + long getId(); + + +} diff --git a/api/src/com/cloud/network/vpc/StaticRouteProfile.java b/api/src/com/cloud/network/vpc/StaticRouteProfile.java new file mode 100644 index 00000000000..75bfe751a94 --- /dev/null +++ b/api/src/com/cloud/network/vpc/StaticRouteProfile.java @@ -0,0 +1,97 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +/** + * @author Alena Prokharchyk + */ +public class StaticRouteProfile implements StaticRoute{ + private long id; + private String targetCidr; + private long accountId; + private long domainId; + private long gatewayId; + private StaticRoute.State state; + private long vpcId; + String vlanTag; + String gateway; + String netmask; + String ipAddress; + + + public StaticRouteProfile(StaticRoute staticRoute, VpcGateway gateway) { + this.id = staticRoute.getId(); + this.targetCidr = staticRoute.getCidr(); + this.accountId = staticRoute.getAccountId(); + this.domainId = staticRoute.getDomainId(); + this.gatewayId = staticRoute.getVpcGatewayId(); + this.state = staticRoute.getState(); + this.vpcId = staticRoute.getVpcId(); + this.vlanTag = gateway.getVlanTag(); + this.gateway = gateway.getGateway(); + this.netmask = gateway.getNetmask(); + this.ipAddress = gateway.getIp4Address(); + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getVpcGatewayId() { + return gatewayId; + } + + @Override + public String getCidr() { + return targetCidr; + } + + @Override + public State getState() { + return state; + } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public long getId() { + return id; + } + + public String getVlanTag() { + return vlanTag; + } + + public String getIp4Address() { + return ipAddress; + } + + public String getGateway() { + return gateway; + } + + public String getNetmask() { + return netmask; + } + +} diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java new file mode 100644 index 00000000000..5efd2e859c8 --- /dev/null +++ b/api/src/com/cloud/network/vpc/Vpc.java @@ -0,0 +1,52 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import com.cloud.acl.ControlledEntity; +import com.cloud.network.Network; + + +/** + * @author Alena Prokharchyk + */ +public interface Vpc extends ControlledEntity{ + public enum State { + Enabled, + Inactive + } + + public static final String _supportedProviders = Network.Provider.VPCVirtualRouter.getName(); + + boolean readyToUse(); + + long getId(); + + String getUuid(); + + String getName(); + + long getZoneId(); + + String getCidr(); + + State getState(); + + long getVpcOfferingId(); + + String getDisplayText(); + + String getNetworkDomain(); + + boolean isRestartRequired(); + +} diff --git a/api/src/com/cloud/network/vpc/VpcGateway.java b/api/src/com/cloud/network/vpc/VpcGateway.java new file mode 100644 index 00000000000..cde9a04ae08 --- /dev/null +++ b/api/src/com/cloud/network/vpc/VpcGateway.java @@ -0,0 +1,69 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import com.cloud.acl.ControlledEntity; +import com.cloud.api.Identity; + +/** + * @author Alena Prokharchyk + */ +public interface VpcGateway extends Identity, ControlledEntity { + public enum Type { + Private, + Public, + Vpn + } + + long getId(); + + /** + * @return + */ + String getIp4Address(); + + /** + * @return + */ + Type getType(); + + /** + * @return + */ + Long getVpcId(); + + /** + * @return + */ + long getZoneId(); + + /** + * @return + */ + Long getNetworkId(); + + /** + * @return + */ + String getGateway(); + + /** + * @return + */ + String getNetmask(); + + /** + * @return + */ + String getVlanTag(); +} diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java new file mode 100644 index 00000000000..167cdced8bb --- /dev/null +++ b/api/src/com/cloud/network/vpc/VpcOffering.java @@ -0,0 +1,46 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + + +/** + * @author Alena Prokharchyk + */ +public interface VpcOffering { + public enum State { + Disabled, + Enabled + } + + public static final String defaultVPCOfferingName = "Default VPC offering"; + + long getId(); + + String getUuid(); + + String getName(); + + String getUniqueName(); + + String getDisplayText(); + + State getState(); + + boolean isDefault(); + + /** + * @return + */ + Long getServiceOfferingId(); + +} diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java new file mode 100644 index 00000000000..fec908083fc --- /dev/null +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -0,0 +1,222 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.cloud.api.commands.ListPrivateGatewaysCmd; +import com.cloud.api.commands.ListStaticRoutesCmd; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; + +/** + * @author Alena Prokharchyk + */ +public interface VpcService { + + public VpcOffering getVpcOffering(long vpcOfferingId); + + public VpcOffering createVpcOffering(String name, String displayText, List supportedServices); + + public Vpc getVpc(long vpcId); + + public Vpc getActiveVpc(long vpcId); + + public List getVpcNetworks(long vpcId); + + Map> getVpcOffSvcProvidersMap(long vpcOffId); + + List listVpcOfferings(Long id, String name, String displayText, List supportedServicesStr, + Boolean isDefault, String keyword, String state, Long startIndex, Long pageSizeVal); + + /** + * @param offId + * @return + */ + public boolean deleteVpcOffering(long offId); + + /** + * @param vpcOffId + * @param vpcOfferingName + * @param displayText + * @param state + * @return + */ + public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state); + + /** + * @param zoneId + * @param vpcOffId + * @param vpcOwnerId + * @param vpcName + * @param displayText + * @param cidr + * @param networkDomain TODO + * @return + */ + public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain); + + /** + * @param vpcId + * @return + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param vpcId + * @param vpcName + * @param displayText + * @return + */ + public Vpc updateVpc(long vpcId, String vpcName, String displayText); + + /** + * @param id + * @param vpcName + * @param displayText + * @param supportedServicesStr + * @param cidr + * @param state TODO + * @param accountName + * @param domainId + * @param keyword + * @param startIndex + * @param pageSizeVal + * @param zoneId TODO + * @param isRecursive TODO + * @param listAll TODO + * @param restartRequired TODO + * @param vpc + * @return + */ + public List listVpcs(Long id, String vpcName, String displayText, + List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, + String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, + Boolean restartRequired); + + /** + * @param vpcId + * @return + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vpcId + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean shutdownVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param id + * @return + * @throws InsufficientCapacityException + */ + boolean restartVpc(long id) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + PrivateGateway getVpcPrivateGateway(long id); + + /** + * @param vpcId TODO + * @param physicalNetworkId + * @param vlan + * @param ipAddress + * @param gateway + * @param netmask + * @param gatewayOwnerId + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceAllocationException + */ + public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, + String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException, + ConcurrentOperationException, InsufficientCapacityException; + + /** + * @param gatewayId + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + public PrivateGateway applyVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param id + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean deleteVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param listPrivateGatewaysCmd + * @return + */ + public List listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd); + + /** + * @param routeId + * @return + */ + StaticRoute getStaticRoute(long routeId); + + /** + * @param vpcId + * @return + * @throws ResourceUnavailableException + */ + public boolean applyStaticRoutes(long vpcId) throws ResourceUnavailableException; + + /** + * @param routeId + * @return TODO + * @throws ResourceUnavailableException + */ + public boolean revokeStaticRoute(long routeId) throws ResourceUnavailableException; + + /** + * @param gatewayId + * @param cidr + * @return + */ + public StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException; + + /** + * @param listStaticRoutesCmd + * @return + */ + public List listStaticRoutes(ListStaticRoutesCmd cmd); + + /** + * @param id + * @return + */ + VpcGateway getVpcGateway(long id); + +} diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java index 3a50d7466d1..091626cdc26 100644 --- a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java +++ b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java @@ -23,7 +23,8 @@ import com.cloud.network.VpnUser; public interface RemoteAccessVpnService { - RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException; + RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, long networkId) + throws NetworkRuleConflictException; void destroyRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException; RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException; diff --git a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java new file mode 100644 index 00000000000..f3f188d430c --- /dev/null +++ b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java @@ -0,0 +1,49 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpn; + +import java.util.List; + +import com.cloud.api.commands.CreateVpnConnectionCmd; +import com.cloud.api.commands.CreateVpnCustomerGatewayCmd; +import com.cloud.api.commands.CreateVpnGatewayCmd; +import com.cloud.api.commands.DeleteVpnConnectionCmd; +import com.cloud.api.commands.DeleteVpnCustomerGatewayCmd; +import com.cloud.api.commands.DeleteVpnGatewayCmd; +import com.cloud.api.commands.ListVpnConnectionsCmd; +import com.cloud.api.commands.ListVpnCustomerGatewaysCmd; +import com.cloud.api.commands.ListVpnGatewaysCmd; +import com.cloud.api.commands.ResetVpnConnectionCmd; +import com.cloud.api.commands.UpdateVpnCustomerGatewayCmd; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; + +public interface Site2SiteVpnService { + Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd); + Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCmd cmd); + Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException; + IpAddress getVpnGatewayIp(Long vpnGatewayId); + Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException; + Site2SiteCustomerGateway deleteCustomerGateway(DeleteVpnCustomerGatewayCmd deleteVpnCustomerGatewayCmd); + Site2SiteVpnGateway deleteVpnGateway(DeleteVpnGatewayCmd deleteVpnGatewayCmd); + Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd) throws ResourceUnavailableException; + Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd) throws ResourceUnavailableException; + List searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd); + List searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd); + List searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd); + Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCmd updateVpnCustomerGatewayCmd); +} diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 195bc0d6926..7415e1a44bc 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -35,13 +35,16 @@ public interface NetworkOffering { public final static String SystemControlNetwork = "System-Control-Network"; public final static String SystemManagementNetwork = "System-Management-Network"; public final static String SystemStorageNetwork = "System-Storage-Network"; - + public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering"; + public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService"; public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService"; public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService"; public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering"; public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering"; public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering"; + public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks"; + long getId(); diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java new file mode 100644 index 00000000000..c3307b6b17b --- /dev/null +++ b/api/src/com/cloud/server/ResourceTag.java @@ -0,0 +1,66 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.server; + +import com.cloud.acl.ControlledEntity; + +/** + * @author Alena Prokharchyk + */ +public interface ResourceTag extends ControlledEntity{ + + public enum TaggedResourceType { + UserVm, + Template, + ISO, + Volume, + Snapshot, + Network, + LoadBalancer, + PortForwardingRule, + FirewallRule, + SecurityGroup, + PublicIpAddress + } + + /** + * @return + */ + long getId(); + + /** + * @return + */ + String getKey(); + + /** + * @return + */ + String getValue(); + + /** + * @return + */ + long getResourceId(); + + /** + * @return + */ + TaggedResourceType getResourceType(); + + /** + * @return + */ + String getCustomer(); + +} diff --git a/api/src/com/cloud/server/TaggedResourceService.java b/api/src/com/cloud/server/TaggedResourceService.java new file mode 100644 index 00000000000..d76d19265df --- /dev/null +++ b/api/src/com/cloud/server/TaggedResourceService.java @@ -0,0 +1,57 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.server; + +import java.util.List; +import java.util.Map; + +import com.cloud.api.commands.ListTagsCmd; +import com.cloud.server.ResourceTag.TaggedResourceType; + +/** + * @author Alena Prokharchyk + */ +public interface TaggedResourceService { + + TaggedResourceType getResourceType (String resourceTypeStr); + + /** + * @param resourceIds TODO + * @param resourceType + * @param tags + * @param customer TODO + * @return + */ + List createTags(List resourceIds, TaggedResourceType resourceType, Map tags, String customer); + + /** + * @param resourceId + * @param resourceType + * @return + */ + String getUuid(String resourceId, TaggedResourceType resourceType); + + /** + * @param listTagsCmd + * @return + */ + List listTags(ListTagsCmd listTagsCmd); + + /** + * @param resourceIds + * @param resourceType + * @param tags + * @return + */ + boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags); +} diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 7553f9e84b2..4fa097ee50f 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -43,7 +43,8 @@ public interface StorageService{ * @throws ResourceUnavailableException * TODO */ - StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; + StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, + UnknownHostException, ResourceUnavailableException; /** * Creates the database object for a volume based on the given criteria @@ -88,7 +89,8 @@ public interface StorageService{ * @throws InsufficientCapacityException * TODO */ - public StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException; + public StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, + InsufficientCapacityException; /** * Complete maintenance for primary storage @@ -99,7 +101,8 @@ public interface StorageService{ * @throws ResourceUnavailableException * TODO */ - public StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException; + public StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) + throws ResourceUnavailableException; public StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException; diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/com/cloud/vm/Nic.java index 3bc92920fd8..d121034867c 100644 --- a/api/src/com/cloud/vm/Nic.java +++ b/api/src/com/cloud/vm/Nic.java @@ -31,7 +31,8 @@ public interface Nic { } public enum State implements FiniteState { - Allocated("Resource is allocated but not reserved"), Reserving("Resource is being reserved right now"), Reserved("Resource has been reserved."), Releasing("Resource is being released"), Deallocating( + Allocated("Resource is allocated but not reserved"), Reserving("Resource is being reserved right now"), + Reserved("Resource has been reserved."), Releasing("Resource is being released"), Deallocating( "Resource is being deallocated"); String _description; diff --git a/api/src/com/cloud/vm/NicProfile.java b/api/src/com/cloud/vm/NicProfile.java index 128e36172e8..a21748f3db2 100644 --- a/api/src/com/cloud/vm/NicProfile.java +++ b/api/src/com/cloud/vm/NicProfile.java @@ -203,7 +203,8 @@ public class NicProfile { return strategy; } - public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri, Integer networkRate, boolean isSecurityGroupEnabled, String name) { + public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri, Integer networkRate, + boolean isSecurityGroupEnabled, String name) { this.id = nic.getId(); this.networkId = network.getId(); this.gateway = nic.getGateway(); @@ -230,13 +231,6 @@ public class NicProfile { } } - public NicProfile(long id, BroadcastDomainType type, Mode mode, long vmId) { - this.id = id; - this.broadcastType = type; - this.mode = mode; - this.vmId = vmId; - } - public NicProfile(ReservationStrategy strategy, String ip4Address, String macAddress, String gateway, String netmask) { this.format = AddressFormat.Ip4; this.ip4Address = ip4Address; diff --git a/api/src/com/cloud/vm/PluggableNics.java b/api/src/com/cloud/vm/PluggableNics.java new file mode 100644 index 00000000000..3b6c34970f2 --- /dev/null +++ b/api/src/com/cloud/vm/PluggableNics.java @@ -0,0 +1,20 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.vm; + +/** + * @author Alena Prokharchyk + */ +public interface PluggableNics { + boolean canPlugNics(); +} diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 8b8eb205b36..5d4b668790c 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -50,7 +50,6 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.exception.ExecutionException; -import com.cloud.vm.VirtualMachineProfile.Param; public interface UserVmService { /** diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index d282aa6464f..9dc04c1ee0b 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -286,4 +286,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, S HypervisorType getHypervisorType(); public Map getDetails(); + + boolean canPlugNics(); } diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index 8f863d9032e..ea714c2d80c 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -36,7 +36,7 @@ public interface VirtualMachineProfile { public static final Param VmPassword = new Param("VmPassword"); public static final Param ControlNic = new Param("ControlNic"); - public static final Param ReProgramNetwork = new Param("RestartNetwork"); + public static final Param ReProgramGuestNetworks = new Param("RestartNetwork"); public static final Param PxeSeverType = new Param("PxeSeverType"); public static final Param HaTag = new Param("HaTag"); diff --git a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java index 075a92f346b..74eb6393390 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java +++ b/awsapi/src/com/cloud/bridge/service/EC2RestServlet.java @@ -23,6 +23,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.net.URLEncoder; import java.security.KeyStore; import java.security.SignatureException; import java.security.cert.Certificate; @@ -178,7 +179,7 @@ public class EC2RestServlet extends HttpServlet { } String keystore = EC2Prop.getProperty( "keystore" ); keystorePassword = EC2Prop.getProperty( "keystorePass" ); - wsdlVersion = EC2Prop.getProperty( "WSDLVersion", "2009-11-30" ); + wsdlVersion = EC2Prop.getProperty( "WSDLVersion", "2010-11-15" ); version = EC2Prop.getProperty( "cloudbridgeVersion", "UNKNOWN VERSION" ); String installedPath = System.getenv("CATALINA_HOME"); @@ -1706,18 +1707,37 @@ public class EC2RestServlet extends HttpServlet { // [C] Verify the signature // -> getting the query-string in this way maintains its URL encoding - EC2RestAuth restAuth = new EC2RestAuth(); - restAuth.setHostHeader( request.getHeader( "Host" )); - String requestUri = request.getRequestURI(); - - //If forwarded from another basepath: - String forwardedPath = (String) request.getAttribute("javax.servlet.forward.request_uri"); - if(forwardedPath!=null){ - requestUri=forwardedPath; - } - restAuth.setHTTPRequestURI( requestUri); - restAuth.setQueryString( request.getQueryString()); - + EC2RestAuth restAuth = new EC2RestAuth(); + restAuth.setHostHeader( request.getHeader( "Host" )); + String requestUri = request.getRequestURI(); + + // If forwarded from another basepath: + String forwardedPath = (String) request.getAttribute("javax.servlet.forward.request_uri"); + if(forwardedPath!=null){ + requestUri=forwardedPath; + } + restAuth.setHTTPRequestURI( requestUri); + + String queryString = request.getQueryString(); + // getQueryString returns null (does it ever NOT return null for these), + // we need to construct queryString to avoid changing the auth code... + if (queryString == null) { + // construct our idea of a queryString with parameters! + Enumeration params = request.getParameterNames(); + if (params != null) { + while(params.hasMoreElements()) { + String paramName = (String) params.nextElement(); + // exclude the signature string obviously. ;) + if (paramName.equalsIgnoreCase("Signature")) continue; + if (queryString == null) + queryString = paramName + "=" + request.getParameter(paramName); + else + queryString = queryString + "&" + paramName + "=" + URLEncoder.encode(request.getParameter(paramName), "UTF-8"); + } + } + } + restAuth.setQueryString(queryString); + if ( restAuth.verifySignature( request.getMethod(), cloudSecretKey, signature, sigMethod )) { UserContext.current().initContext( cloudAccessKey, cloudSecretKey, cloudAccessKey, "REST request", null ); return true; diff --git a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java index a70d930d3fc..222ef49084f 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java +++ b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java @@ -27,6 +27,7 @@ import com.cloud.bridge.service.core.ec2.EC2Address; import com.cloud.bridge.service.core.ec2.EC2AddressFilterSet; import com.cloud.bridge.service.core.ec2.EC2AssociateAddress; import com.cloud.bridge.service.core.ec2.EC2AuthorizeRevokeSecurityGroup; +import com.cloud.bridge.service.core.ec2.EC2AvailabilityZonesFilterSet; import com.cloud.bridge.service.core.ec2.EC2CreateImage; import com.cloud.bridge.service.core.ec2.EC2CreateImageResponse; import com.cloud.bridge.service.core.ec2.EC2CreateKeyPair; @@ -232,6 +233,12 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { if (null != items) { // -> can be empty for( int i=0; i < items.length; i++ ) request.addZone( items[i].getZoneName()); } + + FilterSetType fst = dazt.getFilterSet(); + if (fst != null) { + request.setFilterSet( toAvailabiltyZonesFilterSet(fst)); + } + return toDescribeAvailabilityZonesResponse( engine.handleRequest( request )); } @@ -1065,6 +1072,29 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { return ifs; } + + private EC2AvailabilityZonesFilterSet toAvailabiltyZonesFilterSet( FilterSetType fst ) { + EC2AvailabilityZonesFilterSet azfs = new EC2AvailabilityZonesFilterSet(); + + FilterType[] items = fst.getItem(); + if (items != null) { + for (FilterType item : items) { + EC2Filter oneFilter = new EC2Filter(); + String filterName = item.getName(); + oneFilter.setName( filterName ); + + ValueSetType vft = item.getValueSet(); + ValueType[] valueItems = vft.getItem(); + for (ValueType valueItem : valueItems) { + oneFilter.addValueEncoded( valueItem.getValue()); + } + azfs.addFilter( oneFilter ); + } + } + return azfs; + } + + // toMethods public static DescribeVolumesResponse toDescribeVolumesResponse( EC2DescribeVolumesResponse engineResponse ) { @@ -1100,7 +1130,12 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { String devicePath = engine.cloudDeviceIdToDevicePath( vol.getHypervisor(), vol.getDeviceId()); param5.setDevice( devicePath ); param5.setStatus( toVolumeAttachmentState( vol.getInstanceId(), vol.getVMState())); - param5.setAttachTime( cal ); + if (vol.getAttached() == null) { + param5.setAttachTime( cal ); + } else { + Calendar attachTime = EC2RestAuth.parseDateString(vol.getAttached()); + param5.setAttachTime( attachTime ); + } param5.setDeleteOnTermination( false ); param4.addItem( param5 ); } diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2AvailabilityZonesFilterSet.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2AvailabilityZonesFilterSet.java new file mode 100644 index 00000000000..793af89deca --- /dev/null +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2AvailabilityZonesFilterSet.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package com.cloud.bridge.service.core.ec2; + + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +import com.cloud.bridge.service.exception.EC2ServiceException; + + +public class EC2AvailabilityZonesFilterSet { + protected List filterSet = new ArrayList(); + + private Map filterTypes = new HashMap(); + + public EC2AvailabilityZonesFilterSet() { + // -> use these values to check that the proper filter is passed to this type of filter set + filterTypes.put( "zone-name", "String" ); + } + + public void addFilter( EC2Filter param ) { + String filterName = param.getName(); + String value = (String) filterTypes.get( filterName ); + + if (null == value) + throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 ); + + if (null != value && value.equalsIgnoreCase( "null" )) + throw new EC2ServiceException( "Unsupported filter [" + filterName + "]", 501 ); + + filterSet.add( param ); + } + + public EC2Filter[] getFilterSet() { + return filterSet.toArray(new EC2Filter[0]); + } + + public List evaluate( EC2DescribeAvailabilityZonesResponse availabilityZones) throws ParseException { + List resultList = new ArrayList(); + + boolean matched; + + EC2Filter[] filterSet = getFilterSet(); + for ( String availableZone : availabilityZones.getZoneSet() ) { + matched = true; + if (filterSet != null) { + for (EC2Filter filter : filterSet) { + if (!filterMatched(availableZone, filter)) { + matched = false; + break; + } + } + } + if (matched == true) + resultList.add(availableZone); + } + return resultList; + } + + private boolean filterMatched( String availableZone, EC2Filter filter ) throws ParseException { + String filterName = filter.getName(); + String[] valueSet = filter.getValueSet(); + + if ( filterName.equalsIgnoreCase("zone-name")) { + return containsString(availableZone, valueSet); + } + return false; + } + + private boolean containsString( String lookingFor, String[] set ){ + if (lookingFor == null) + return false; + + for (String filter: set) { + if (lookingFor.matches( filter )) return true; + } + return false; + } + +} diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2DescribeAvailabilityZones.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2DescribeAvailabilityZones.java index ba445677d2a..d463b64402b 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2DescribeAvailabilityZones.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2DescribeAvailabilityZones.java @@ -21,6 +21,7 @@ import java.util.List; public class EC2DescribeAvailabilityZones { private List zoneSet = new ArrayList(); // a list of strings identifying zones + private EC2AvailabilityZonesFilterSet azfs = null; public EC2DescribeAvailabilityZones() { } @@ -32,4 +33,13 @@ public class EC2DescribeAvailabilityZones { public String[] getZoneSet() { return zoneSet.toArray(new String[0]); } + + public EC2AvailabilityZonesFilterSet getFilterSet() { + return azfs; + } + + public void setFilterSet( EC2AvailabilityZonesFilterSet param ) { + azfs = param; + } + } diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index b21940d23ee..3c14b893a9d 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -1120,10 +1120,16 @@ public class EC2Engine { */ public EC2DescribeAvailabilityZonesResponse handleRequest(EC2DescribeAvailabilityZones request) { try { - CloudStackAccount caller = getCurrentAccount(); - - return listZones(request.getZoneSet(), null); - + EC2DescribeAvailabilityZonesResponse availableZones = listZones(request.getZoneSet(), null); + EC2AvailabilityZonesFilterSet azfs = request.getFilterSet(); + if ( null == azfs ) + return availableZones; + else { + List matchedAvailableZones = azfs.evaluate(availableZones); + if (matchedAvailableZones.isEmpty()) + return new EC2DescribeAvailabilityZonesResponse(); + return listZones(matchedAvailableZones.toArray(new String[0]), null); + } } catch( EC2ServiceException error ) { logger.error( "EC2 DescribeAvailabilityZones - ", error); throw error; diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2SnapshotFilterSet.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2SnapshotFilterSet.java index c69191cba94..9e3e4ade943 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2SnapshotFilterSet.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2SnapshotFilterSet.java @@ -18,13 +18,16 @@ package com.cloud.bridge.service.core.ec2; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; import com.cloud.bridge.service.UserContext; import com.cloud.bridge.service.exception.EC2ServiceException; import com.cloud.bridge.util.DateHelper; +import com.cloud.bridge.util.EC2RestAuth; public class EC2SnapshotFilterSet { @@ -121,7 +124,12 @@ public class EC2SnapshotFilterSet { } else if (filterName.equalsIgnoreCase( "status" )) { - return containsString( "completed", valueSet ); + if ( snap.getState().equalsIgnoreCase("backedup")) + return containsString( "completed", valueSet ); + else if (snap.getState().equalsIgnoreCase("creating") || snap.getState().equalsIgnoreCase("backingup")) + return containsString( "pending", valueSet ); + else + return containsString( "error", valueSet ); } else if (filterName.equalsIgnoreCase( "volume-id" )) { @@ -160,11 +168,14 @@ public class EC2SnapshotFilterSet { private boolean containsTime( Calendar lookingFor, String[] set ) throws ParseException { + lookingFor.setTimeZone(TimeZone.getTimeZone("GMT")); + Date lookingForDate = lookingFor.getTime(); for (String s : set) { //System.out.println( "contsinsCalendar: " + lookingFor + " " + set[i] ); - Calendar toMatch = Calendar.getInstance(); - toMatch.setTime( DateHelper.parseISO8601DateString( s )); - if (0 == lookingFor.compareTo( toMatch )) return true; + Calendar toMatch = EC2RestAuth.parseDateString(s); + toMatch.setTimeZone(TimeZone.getTimeZone("GMT")); + Date toMatchDate = toMatch.getTime(); + if ( 0 == lookingForDate.compareTo(toMatchDate)) return true; } return false; } diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2VolumeFilterSet.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2VolumeFilterSet.java index 663544e0608..0b0520403ac 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2VolumeFilterSet.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2VolumeFilterSet.java @@ -21,9 +21,10 @@ import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; +import java.util.Date; import com.cloud.bridge.service.exception.EC2ServiceException; -import com.cloud.bridge.util.DateHelper; import com.cloud.bridge.util.EC2RestAuth; @@ -123,8 +124,14 @@ public class EC2VolumeFilterSet { return containsString(vol.getState(), valueSet ); else if (filterName.equalsIgnoreCase( "volume-id" )) return containsString(vol.getId().toString(), valueSet ); - else if (filterName.equalsIgnoreCase( "attachment.attach-time" )) - return containsTime(vol.getAttached(), valueSet ); + else if (filterName.equalsIgnoreCase( "attachment.attach-time" )) { + if (vol.getAttached() != null) + return containsTime(vol.getAttached(), valueSet ); + else if (vol.getInstanceId() != null) + return containsTime(vol.getCreated(), valueSet); + else + return false; + } else if (filterName.equalsIgnoreCase( "attachment.device" )) return containsDevice(vol.getDeviceId(), valueSet ); else if (filterName.equalsIgnoreCase( "attachment.instance-id" )) @@ -155,14 +162,17 @@ public class EC2VolumeFilterSet { private boolean containsTime(String lookingForDate, String[] set ) throws ParseException { - Calendar lookingFor = EC2RestAuth.parseDateString(lookingForDate); - for (String s : set) { - Calendar toMatch = Calendar.getInstance(); - toMatch.setTime( DateHelper.parseISO8601DateString( s )); - if (0 == lookingFor.compareTo( toMatch )) return true; - } - return false; - } + Calendar lookingFor = EC2RestAuth.parseDateString(lookingForDate); + lookingFor.setTimeZone(TimeZone.getTimeZone("GMT")); + Date lookForDate = lookingFor.getTime(); + for (String s : set) { + Calendar toMatch = EC2RestAuth.parseDateString(s); + toMatch.setTimeZone(TimeZone.getTimeZone("GMT")); + Date toMatchDate = toMatch.getTime(); + if ( 0 == lookForDate.compareTo(toMatchDate)) return true; + } + return false; + } private boolean containsDevice(String deviceId, String[] set ) diff --git a/build/build-marvin.xml b/build/build-marvin.xml index ed5cf565e26..91e959a1f17 100644 --- a/build/build-marvin.xml +++ b/build/build-marvin.xml @@ -42,4 +42,17 @@ file except in compliance with the License. Citrix Systems, Inc. --> + + + + + + + + + + + + + diff --git a/build/build-tests.xml b/build/build-tests.xml index fa375479a7a..4e31fda8b48 100755 --- a/build/build-tests.xml +++ b/build/build-tests.xml @@ -33,6 +33,9 @@ + + + @@ -88,6 +91,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index eda69df3ed6..a5c192389be 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -19,14 +19,14 @@ label.vcipaddress=vCenter IP Address label.vsmctrlvlanid=Control VLAN ID label.vsmpktvlanid=Packet VLAN ID label.vsmstoragevlanid=Storage VLAN ID -label.nexusVswitch=Nexus Vswitch -label.action.delete.nexusVswitch=Delete NexusVswitch -label.action.enable.nexusVswitch=Enable NexusVswitch -label.action.disable.nexusVswitch=Disable NexusVswitch -label.action.list.nexusVswitch=List NexusVswitch -message.action.delete.nexusVswitch=Please confirm that you want to delete this nexusVswitch. -message.action.enable.nexusVswitch=Please confirm that you want to enable this nexusVswitch. -message.action.disable.nexusVswitch=Please confirm that you want to disable this nexusVswitch. +label.nexusVswitch=Nexus 1000v +label.action.delete.nexusVswitch=Delete Nexus 1000v +label.action.enable.nexusVswitch=Enable Nexus 1000v +label.action.disable.nexusVswitch=Disable Nexus 1000v +label.action.list.nexusVswitch=List Nexus 1000v +message.action.delete.nexusVswitch=Please confirm that you want to delete this nexus 1000v +message.action.enable.nexusVswitch=Please confirm that you want to enable this nexus 1000v +message.action.disable.nexusVswitch=Please confirm that you want to disable this nexus 1000v message.specify.url=Please specify URL label.select.instance.to.attach.volume.to=Select instance to attach volume to label.upload=Upload diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 3a3571895e0..703957de4bf 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -328,7 +328,53 @@ deleteStorageNetworkIpRange=com.cloud.api.commands.DeleteStorageNetworkIpRangeCm listStorageNetworkIpRange=com.cloud.api.commands.listStorageNetworkIpRangeCmd;1 updateStorageNetworkIpRange=com.cloud.api.commands.UpdateStorageNetworkIpRangeCmd;1 -### Network Devices commands +#### Network Devices commands addNetworkDevice=com.cloud.api.commands.AddNetworkDeviceCmd;1 listNetworkDevice=com.cloud.api.commands.ListNetworkDeviceCmd;1 deleteNetworkDevice=com.cloud.api.commands.DeleteNetworkDeviceCmd;1 + +#### Tags commands +createTags=com.cloud.api.commands.CreateTagsCmd;15 +deleteTags=com.cloud.api.commands.DeleteTagsCmd;15 +listTags=com.cloud.api.commands.ListTagsCmd;15 + +### VPC commands +createVPC=com.cloud.api.commands.CreateVPCCmd;15 +listVPCs=com.cloud.api.commands.ListVPCsCmd;15 +deleteVPC=com.cloud.api.commands.DeleteVPCCmd;15 +updateVPC=com.cloud.api.commands.UpdateVPCCmd;15 +restartVPC=com.cloud.api.commands.RestartVPCCmd;15 + +#### VPC offering commands +createVPCOffering=com.cloud.api.commands.CreateVPCOfferingCmd;1 +updateVPCOffering=com.cloud.api.commands.UpdateVPCOfferingCmd;1 +deleteVPCOffering=com.cloud.api.commands.DeleteVPCOfferingCmd;1 +listVPCOfferings=com.cloud.api.commands.ListVPCOfferingsCmd;15 + +#### Private gateway commands +createPrivateGateway=com.cloud.api.commands.CreatePrivateGatewayCmd;1 +listPrivateGateways=com.cloud.api.commands.ListPrivateGatewaysCmd;15 +deletePrivateGateway=com.cloud.api.commands.DeletePrivateGatewayCmd;1 + +#### Network ACL commands +createNetworkACL=com.cloud.api.commands.CreateNetworkACLCmd;15 +deleteNetworkACL=com.cloud.api.commands.DeleteNetworkACLCmd;15 +listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15 + +#### Static route commands +createStaticRoute=com.cloud.api.commands.CreateStaticRouteCmd;15 +deleteStaticRoute=com.cloud.api.commands.DeleteStaticRouteCmd;15 +listStaticRoutes=com.cloud.api.commands.ListStaticRoutesCmd;15 + +### Site-to-site VPN commands +createVpnCustomerGateway=com.cloud.api.commands.CreateVpnCustomerGatewayCmd;1 +createVpnGateway=com.cloud.api.commands.CreateVpnGatewayCmd;1 +createVpnConnection=com.cloud.api.commands.CreateVpnConnectionCmd;1 +deleteVpnCustomerGateway=com.cloud.api.commands.DeleteVpnCustomerGatewayCmd;1 +deleteVpnGateway=com.cloud.api.commands.DeleteVpnGatewayCmd;1 +deleteVpnConnection=com.cloud.api.commands.DeleteVpnConnectionCmd;1 +updateVpnCustomerGateway=com.cloud.api.commands.UpdateVpnCustomerGatewayCmd;1 +resetVpnConnection=com.cloud.api.commands.ResetVpnConnectionCmd;1 +listVpnCustomerGateways=com.cloud.api.commands.ListVpnCustomerGatewaysCmd;1 +listVpnGateways=com.cloud.api.commands.ListVpnGatewaysCmd;1 +listVpnConnections=com.cloud.api.commands.ListVpnConnectionsCmd;1 diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 48869b5daee..2525e912f58 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -78,6 +78,7 @@ + @@ -142,6 +143,7 @@ + @@ -181,5 +183,8 @@ + + + diff --git a/cloud.spec b/cloud.spec index da6ad321e9a..9824b9ac776 100644 --- a/cloud.spec +++ b/cloud.spec @@ -432,8 +432,9 @@ if [ "$1" == "1" ] ; then root=/usr/share/cloud/bridge target=/usr/share/cloud/management/ - if [ ! -e $target/webapps/awsapi ]; then - ln -s $root/webapps/awsapi $target/webapps/awsapi + mkdir -p $target/webapps7080 + if [ ! -e $target/webapps7080/awsapi ]; then + ln -s $root/webapps/awsapi $target/webapps7080/awsapi fi jars=`ls $root/lib` diff --git a/console-proxy/js/ajaxviewer.js b/console-proxy/js/ajaxviewer.js index 579b9402bb6..dada4c2edfb 100644 --- a/console-proxy/js/ajaxviewer.js +++ b/console-proxy/js/ajaxviewer.js @@ -277,7 +277,11 @@ JsCookedKeyboardMapper.prototype.inputFeed = function(eventType, code, modifiers } else { this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); } - } + } else { + if((modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) { + this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers}); + } + } // special handling for ALT/CTRL key if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) @@ -321,8 +325,8 @@ function AjaxViewer(panelId, imageUrl, updateUrl, tileMap, width, height, tileWi // trouble-shooting g_logger = new Logger(); - //g_logger.enable(true); - //g_logger.open(); + // g_logger.enable(true); + // g_logger.open(); var ajaxViewer = this; this.imageLoaded = false; diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java index 0feb5f68dbb..2e6ac35f45d 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyVncClient.java @@ -14,7 +14,6 @@ package com.cloud.consoleproxy; import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.net.UnknownHostException; import org.apache.log4j.Logger; @@ -31,10 +30,23 @@ import com.cloud.consoleproxy.vnc.VncClient; */ public class ConsoleProxyVncClient extends ConsoleProxyClientBase { private static final Logger s_logger = Logger.getLogger(ConsoleProxyVncClient.class); + + private static final int SHIFT_KEY_MASK = 64; + private static final int CTRL_KEY_MASK = 128; + private static final int META_KEY_MASK = 256; + private static final int ALT_KEY_MASK = 512; + + private static final int X11_KEY_SHIFT = 0xffe1; + private static final int X11_KEY_CTRL = 0xffe3; + private static final int X11_KEY_ALT = 0xffe9; + private static final int X11_KEY_META = 0xffe7; private VncClient client; private Thread worker; - private boolean workerDone = false; + private boolean workerDone = false; + + private int lastModifierStates = 0; + private int lastPointerMask = 0; public ConsoleProxyVncClient() { } @@ -148,12 +160,14 @@ public class ConsoleProxyVncClient extends ConsoleProxyClientBase { updateFrontEndActivityTime(); switch(event) { - case KEY_DOWN : + case KEY_DOWN : + sendModifierEvents(modifiers); client.sendClientKeyboardEvent(RfbConstants.KEY_DOWN, code, 0); break; - case KEY_UP : - client.sendClientKeyboardEvent(RfbConstants.KEY_UP, code, 0); + case KEY_UP : + client.sendClientKeyboardEvent(RfbConstants.KEY_UP, code, 0); + sendModifierEvents(0); break; case KEY_PRESS : @@ -164,7 +178,7 @@ public class ConsoleProxyVncClient extends ConsoleProxyClientBase { break; } } - + public void sendClientMouseEvent(InputEventType event, int x, int y, int code, int modifiers) { if(client == null) return; @@ -174,12 +188,22 @@ public class ConsoleProxyVncClient extends ConsoleProxyClientBase { int pointerMask = 0; int mask = 1; if(code == 2) - mask = 4; - if(event == InputEventType.MOUSE_DOWN) { - pointerMask = mask; - } - - client.sendClientMouseEvent(pointerMask, x, y, code, modifiers); + mask = 4; + + if(event == InputEventType.MOUSE_DOWN) { + pointerMask = mask; + lastPointerMask = pointerMask; + } else if(event == InputEventType.MOUSE_UP) { + lastPointerMask = 0; + } else if(event == InputEventType.MOUSE_MOVE) { + if(lastPointerMask != 0) + pointerMask = lastPointerMask; + } + + sendModifierEvents(modifiers); + client.sendClientMouseEvent(pointerMask, x, y, code, modifiers); + if(pointerMask == 0) + sendModifierEvents(0); } @Override @@ -187,5 +211,21 @@ public class ConsoleProxyVncClient extends ConsoleProxyClientBase { if(client != null) return client.getFrameBufferCanvas(); return null; + } + + private void sendModifierEvents(int modifiers) { + if((modifiers & SHIFT_KEY_MASK) != (lastModifierStates & SHIFT_KEY_MASK)) + client.sendClientKeyboardEvent((modifiers & SHIFT_KEY_MASK) != 0 ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP, X11_KEY_SHIFT, 0); + + if((modifiers & CTRL_KEY_MASK) != (lastModifierStates & CTRL_KEY_MASK)) + client.sendClientKeyboardEvent((modifiers & CTRL_KEY_MASK) != 0 ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP, X11_KEY_CTRL, 0); + + if((modifiers & META_KEY_MASK) != (lastModifierStates & META_KEY_MASK)) + client.sendClientKeyboardEvent((modifiers & META_KEY_MASK) != 0 ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP, X11_KEY_META, 0); + + if((modifiers & ALT_KEY_MASK) != (lastModifierStates & ALT_KEY_MASK)) + client.sendClientKeyboardEvent((modifiers & ALT_KEY_MASK) != 0 ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP, X11_KEY_ALT, 0); + + lastModifierStates = modifiers; } } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 876e3fe4a2c..7c9deaead76 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -57,6 +57,7 @@ import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.IpAddressTO; @@ -82,7 +83,6 @@ import com.cloud.utils.script.Script; public class VirtualRoutingResource implements Manager { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); private String _savepasswordPath; // This script saves a random password to the DomR file system - private String _ipassocPath; private String _publicIpAddress; private String _firewallPath; private String _loadbPath; @@ -90,11 +90,8 @@ public class VirtualRoutingResource implements Manager { private String _vmDataPath; private String _publicEthIf; private String _privateEthIf; - private String _getRouterStatusPath; private String _bumpUpPriorityPath; - private String _l2tpVpnPath; - private String _getDomRVersionPath; - + private String _routerProxyPath; private int _timeout; private int _startTimeout; @@ -136,6 +133,8 @@ public class VirtualRoutingResource implements Manager { return execute((VpnUsersCfgCommand)cmd); } else if (cmd instanceof GetDomRVersionCmd) { return execute((GetDomRVersionCmd)cmd); + } else if (cmd instanceof Site2SiteVpnCfgCommand) { + return execute((Site2SiteVpnCfgCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); @@ -147,36 +146,40 @@ public class VirtualRoutingResource implements Manager { private Answer execute(VpnUsersCfgCommand cmd) { for (VpnUsersCfgCommand.UsernamePassword userpwd: cmd.getUserpwds()) { - Script command = new Script(_l2tpVpnPath, _timeout, s_logger); - command.add(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + String args = ""; if (!userpwd.isAdd()) { - command.add("-U ", userpwd.getUsername()); + args +="-U "; + args +=userpwd.getUsername(); } else { - command.add("-u ", userpwd.getUsernamePassword()); + args +="-u "; + args += userpwd.getUsernamePassword(); } - String result = command.execute(); + String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); if (result != null) { return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); } } - return new Answer(cmd); } private Answer execute(RemoteAccessVpnCfgCommand cmd) { - Script command = new Script(_l2tpVpnPath, _timeout, s_logger); - command.add(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + String args = ""; if (cmd.isCreate()) { - command.add("-r ", cmd.getIpRange()); - command.add("-p ", cmd.getPresharedKey()); - command.add("-s ", cmd.getVpnServerIp()); - command.add("-l ", cmd.getLocalIp()); - command.add("-c "); + args += "-r "; + args += cmd.getIpRange(); + args += " -p "; + args += cmd.getPresharedKey(); + args += " -s "; + args += cmd.getVpnServerIp(); + args += " -l "; + args += cmd.getLocalIp(); + args += " -c "; } else { - command.add("-d "); - command.add("-s ", cmd.getVpnServerIp()); + args +="-d "; + args += " -s "; + args += cmd.getVpnServerIp(); } - String result = command.execute(); + String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); if (result != null) { return new Answer(cmd, false, "Configure VPN failed"); } @@ -474,9 +477,18 @@ public class VirtualRoutingResource implements Manager { } public String getRouterStatus(String routerIP) { - final Script command = new Script(_getRouterStatusPath, _timeout, s_logger); + return routerProxy("checkrouter.sh", routerIP, null); + } + + + public String routerProxy(String script, String routerIP, String args) { + final Script command = new Script(_routerProxyPath, _timeout, s_logger); final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); + command.add(script); command.add(routerIP); + if ( args != null ) { + command.add(args); + } String result = command.execute(parser); if (result == null) { return parser.getLine(); @@ -507,14 +519,7 @@ public class VirtualRoutingResource implements Manager { } protected String getDomRVersion(String routerIP) { - final Script command = new Script(_getDomRVersionPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(routerIP); - String result = command.execute(parser); - if (result == null) { - return parser.getLine(); - } - return null; + return routerProxy("netusage.sh", routerIP, null); } protected Answer execute(GetDomRVersionCmd cmd) { @@ -538,6 +543,42 @@ public class VirtualRoutingResource implements Manager { protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); } + + protected Answer execute(Site2SiteVpnCfgCommand cmd) { + String args; + if (cmd.isCreate()) { + args = "-A"; + args += " -l "; + args += cmd.getLocalPublicIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -g "; + args += cmd.getLocalPublicGateway(); + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + args += " -e "; + args += cmd.getEspPolicy(); + args += " -i "; + args += cmd.getIkePolicy(); + args += " -t "; + args += Long.toString(cmd.getLifetime()); + args += " -s "; + args += cmd.getIpsecPsk(); + } else { + args = "-D"; + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + } + String result = routerProxy("ipsectunnel", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + if (result != null) { + return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); + } + return new Answer(cmd); + } private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { String result = null; @@ -592,48 +633,49 @@ public class VirtualRoutingResource implements Manager { public String assignPublicIpAddress(final String vmName, final long id, final String vnet, final String privateIpAddress, final String macAddress, final String publicIpAddress) { - - final Script command = new Script(_ipassocPath, _timeout, s_logger); - command.add("-A"); - command.add("-f"); //first ip is source nat ip - command.add("-r", vmName); - command.add("-i", privateIpAddress); - command.add("-a", macAddress); - command.add("-l", publicIpAddress); - - return command.execute(); + String args ="-A"; + args += " -f"; //first ip is source nat ip + args += " -r "; + args += vmName; + args += " -i "; + args += privateIpAddress; + args += " -a "; + args += macAddress; + args += " -l "; + args += publicIpAddress; + return routerProxy("ipassoc.sh", privateIpAddress, args); } + public String assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp, int nicNum){ - final Script command = new Script(_ipassocPath, _timeout, s_logger); - command.add( privateIpAddress); + String args = ""; if (add) { - command.add("-A"); + args += "-A"; } else { - command.add("-D"); - } - - if (sourceNat) { - command.add("-s"); - } - if (firstIP) { - command.add( "-f"); - + args += "-D"; } String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - command.add( "-l", publicIpAddress + "/" + cidrSize); - String publicNic = "eth" + nicNum; - command.add("-c", publicNic); - - command.add("-g", vlanGateway); - + if (sourceNat) { + args +=" -s"; + } + if (firstIP) { + args += " -f"; + } + args += " -l "; + args += publicIpAddress + "/" + cidrSize; - return command.execute(); + String publicNic = "eth" + nicNum; + args += " -c "; + args += publicNic; + + args +=" -g "; + args += vlanGateway; + return routerProxy("ipassoc.sh", privateIpAddress, args); } private void deletExitingLinkLocalRoutTable(String linkLocalBr) { @@ -801,12 +843,6 @@ public class VirtualRoutingResource implements Manager { value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); - _ipassocPath = findScript("ipassoc.sh"); - if (_ipassocPath == null) { - throw new ConfigurationException("Unable to find the ipassoc.sh"); - } - s_logger.info("ipassoc.sh found in " + _ipassocPath); - _publicIpAddress = (String)params.get("public.ip.address"); if (_publicIpAddress != null) { s_logger.warn("Incoming public ip address is overriden. Will always be using the same ip address: " + _publicIpAddress); @@ -837,11 +873,6 @@ public class VirtualRoutingResource implements Manager { throw new ConfigurationException("Unable to find user_data.sh"); } - _getRouterStatusPath = findScript("getRouterStatus.sh"); - if(_getRouterStatusPath == null) { - throw new ConfigurationException("Unable to find getRouterStatus.sh"); - } - _publicEthIf = (String)params.get("public.network.device"); if (_publicEthIf == null) { _publicEthIf = "xenbr1"; @@ -859,14 +890,9 @@ public class VirtualRoutingResource implements Manager { throw new ConfigurationException("Unable to find bumpUpPriority.sh"); } - _l2tpVpnPath = findScript("l2tp_vpn.sh"); - if (_l2tpVpnPath == null) { - throw new ConfigurationException("Unable to find l2tp_vpn.sh"); - } - - _getDomRVersionPath = findScript("getDomRVersion.sh"); - if(_getDomRVersionPath == null) { - throw new ConfigurationException("Unable to find getDomRVersion.sh"); + _routerProxyPath = findScript("routerProxy.sh"); + if (_routerProxyPath == null) { + throw new ConfigurationException("Unable to find routerProxy.sh"); } return true; diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index f87fd7d725f..671ab27da98 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Set; import java.util.TimeZone; import java.util.UUID; @@ -87,6 +88,8 @@ import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -95,8 +98,11 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SetSourceNatAnswer; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -105,6 +111,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.ValidateSnapshotAnswer; import com.cloud.agent.api.ValidateSnapshotCommand; @@ -114,14 +122,19 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -230,6 +243,9 @@ import com.vmware.vim25.VirtualMachineGuestOsIdentifier; import com.vmware.vim25.VirtualMachinePowerState; import com.vmware.vim25.VirtualMachineRuntimeInfo; import com.vmware.vim25.VirtualSCSISharing; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); @@ -409,6 +425,20 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((GetDomRVersionCmd)cmd); } else if (cmd instanceof CheckNetworkCommand) { answer = execute((CheckNetworkCommand) cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return execute((SetupGuestNetworkCommand) cmd); + } else if (cmd instanceof PlugNicCommand) { + return execute((PlugNicCommand) cmd); + } else if (cmd instanceof UnPlugNicCommand) { + return execute((UnPlugNicCommand) cmd); + } else if (cmd instanceof IpAssocVpcCommand) { + return execute((IpAssocVpcCommand) cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return execute((SetSourceNatCommand) cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return execute((SetNetworkACLCommand) cmd); + } else if (cmd instanceof SetPortForwardingRulesVpcCommand) { + return execute((SetPortForwardingRulesVpcCommand) cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -704,10 +734,429 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.error("Unexpected exception: " + e.toString(), e); return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e)); } - } - + } + + // + // list available ethx devices + // ls /proc/sys/net/ipv4/conf + // + private int allocRouterEthDeviceIndex(String domrName, String routerIp) throws Exception { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + if(result.first()) { + String[] tokens = result.second().split(" "); + HashMap deviceNames = new HashMap(); + for(String token: tokens) + deviceNames.put(token, token); + + for(int i = 1; ; i++) { + if(!deviceNames.containsKey("eth" + i)) + return i; + } + } + + return -1; + } + + // + // find mac address of a specified ethx device + // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 + // + // list IP with eth devices + // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' + // | awk -F: '{ print $1 ": " $3 }' + // + // returns + // eth0:xx.xx.xx.xx + // + // + private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + if(result.first()) { + String[] tokens = result.second().split(" "); + for(String token : tokens) { + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token)); + + if(result2.first() && result2.second().equalsIgnoreCase(mac)) + return Integer.parseInt(token.substring(3)); + } + } + + return -1; + } + + private VirtualDevice findVirtualNicDevice(VirtualMachineMO vmMo, String mac) throws Exception { + + VirtualDevice[] nics = vmMo.getNicDevices(); + for(VirtualDevice nic : nics) { + if(nic instanceof VirtualEthernetCard) { + if(((VirtualEthernetCard)nic).getMacAddress().equals(mac)) + return nic; + } + } + return null; + } + + private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + NicTO nic = cmd.getNic(); + String routerIp = getRouterSshControlIp(cmd); + String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));; + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2= cmd.getDefaultDns2(); + if ( dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + try { + int ethDeviceNum = allocRouterEthDeviceIndex(domrName, routerIp); + + String args = "-C "; + String dev = "eth" + ethDeviceNum; + args += " -d " + dev; + args += " -i " + domrGIP; + args += " -g " + gw; + args += " -m " + cidr; + args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); + if ( dns != null && !dns.isEmpty() ) { + args += " -s " + dns; + } + if ( domainName != null && !domainName.isEmpty() ) { + args += " -e " + domainName; + } + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_guestnw.sh " + args); + + if (!result.first()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("SetupGuestNetworkCommand on domain router " + routerIp + " completed"); + } + + return new SetupGuestNetworkAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + } + + protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + assignVPCPublicIpAddress(routerName, routerIp, ip); + results[i++] = ip.getPublicIp() + " - success"; + } + } catch (Exception e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + results[i++] = IpAssocAnswer.errorResult; + } + + return new IpAssocAnswer(cmd, results); + } + + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + IpAddressTO pubIp = cmd.getIpAddress(); + try { + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); + String args = ""; + args += " -A "; + args += " -l "; + args += pubIp.getPublicIp(); + + args += " -c "; + args += "eth" + ethDeviceNum; + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_snat.sh " + args); + + if (!result.first()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetSourceNatAnswer(cmd, false, msg); + } + + return new SetSourceNatAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = "Ip SNAT failure due to " + e.toString(); + s_logger.error(msg, e); + return new SetSourceNatAnswer(cmd, false, msg); + } + } + + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + String[] results = new String[cmd.getRules().length]; + try { + String [][] rules = cmd.generateFwRules(); + StringBuilder sb = new StringBuilder(); + String[] aclRules = rules[0]; + if (aclRules.length == 0) { + return new SetNetworkACLAnswer(cmd, true, results); + } + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + NicTO nic = cmd.getNic(); + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); + String args = ""; + args += " -d " + "eth" + ethDeviceNum; + args += " -i " + nic.getIp(); + args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + args += " -a " + sb.toString(); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_acl.sh " + args); + + if (!result.first()) { + String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); + s_logger.error(msg); + + return new SetNetworkACLAnswer(cmd, false, results); + } + + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); + } + } + + protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + String routerIp = getRouterSshControlIp(cmd); + + String[] results = new String[cmd.getRules().length]; + int i = 0; + + boolean endResult = true; + for (PortForwardingRuleTO rule : cmd.getRules()) { + String args =""; + args += rule.revoked() ? " -D" : " -A"; + args += " -P " + rule.getProtocol().toLowerCase(); + args += " -l " + rule.getSrcIp(); + args += " -p " + rule.getStringSrcPortRange().replace(":", "-"); + args += " -r " + rule.getDstIp(); + args += " -d " + rule.getStringDstPortRange().replace(":", "-"); + + try { + Pair sshResult = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_portforwarding " + args); + + if (!sshResult.first()) { + results[i++] = "Failed"; + endResult = false; + } else { + results[i++] = null; + } + } catch(Exception e) { + results[i++] = "Failed"; + endResult = false; + } + } + return new SetPortForwardingRulesAnswer(cmd, results, endResult); + } + + private PlugNicAnswer execute(PlugNicCommand cmd) { + + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + + String vmName = cmd.getVirtualMachine().getName(); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + + if(vmMo == null) { + if(hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), + ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(vmName); + } + } + + if (vmMo == null) { + String msg = "Router " + vmName + " no longer exists to execute PlugNic command"; + s_logger.error(msg); + throw new Exception(msg); + } + + // TODO need a way to specify the control of NIC device type + VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000; + + // find a usable device number in VMware environment + VirtualDevice[] nicDevices = vmMo.getNicDevices(); + int deviceNumber = -1; + for(VirtualDevice device : nicDevices) { + if(device.getUnitNumber() > deviceNumber) + deviceNumber = device.getUnitNumber(); + } + deviceNumber++; + + NicTO nicTo = cmd.getNic(); + VirtualDevice nic; + Pair networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo); + if (mgr.getNexusVSwitchGlobalParameter()) { + String dvSwitchUuid; + ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); + DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); + ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first()); + dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); + s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid); + nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), + dvSwitchUuid, nicTo.getMac(), deviceNumber, deviceNumber + 1, true, true); + } else { + s_logger.info("Preparing NIC device on network " + networkInfo.second()); + nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), + deviceNumber, deviceNumber + 1, true, true); + } + + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; + deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); + deviceConfigSpecArray[0].setDevice(nic); + deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.add); + + vmConfigSpec.setDeviceChange(deviceConfigSpecArray); + if(!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Failed to configure devices when running PlugNicCommand"); + } + + return new PlugNicAnswer(cmd, true, "success"); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString()); + } + } + + private UnPlugNicAnswer execute(UnPlugNicCommand cmd) { + + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + + String vmName = cmd.getVirtualMachine().getName(); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + + if(vmMo == null) { + if(hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), + ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(vmName); + } + } + + if (vmMo == null) { + String msg = "VM " + vmName + " no longer exists to execute UnPlugNic command"; + s_logger.error(msg); + throw new Exception(msg); + } + + VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac()); + + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; + deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); + deviceConfigSpecArray[0].setDevice(nic); + deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.remove); + + vmConfigSpec.setDeviceChange(deviceConfigSpecArray); + if(!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Failed to configure devices when running unplugNicCommand"); + } + + return new UnPlugNicAnswer(cmd, true, "success"); + } catch(Exception e) { + s_logger.error("Unexpected exception: ", e); + return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + e.toString()); + } + } + + protected void assignVPCPublicIpAddress(String domrName, String routerIp, IpAddressTO ip) throws Exception { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + + int ethDeviceNum = this.findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + String args = ""; + if (ip.isAdd()) { + args += " -A "; + } else { + args += " -D "; + } + + args += " -l "; + args += ip.getPublicIp(); + + args += " -c "; + args += "eth" + ethDeviceNum; + + args += " -g "; + args += ip.getVlanGateway(); + + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, + "/opt/cloud/bin/vpc_ipassoc.sh " + args); + + if (!result.first()) { + throw new InternalErrorException("Unable to assign public IP address"); + } + } + protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp) throws Exception { + final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp) throws Exception { String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); @@ -1021,7 +1470,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected Answer execute(CheckRouterCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/checkrouter.sh "); + s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkrouter.sh "); } Pair result; @@ -2025,17 +2474,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, "0"); if (getVmState(vmMo) != State.Stopped) { - Long bytesSent = 0L; - Long bytesRcvd = 0L; - - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - //Private IP is 0.0.0.0 for Direct Network virtual router and network usage is not metered for Direct network from Virtual Router - if (cmd.getPrivateRouterIpAddress() != null && !"0.0.0.0".equals(cmd.getPrivateRouterIpAddress())) { - long[] stats = getNetworkStats(cmd.getPrivateRouterIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - } // before we stop VM, remove all possible snapshots on the VM to let // disk chain be collapsed @@ -2043,11 +2481,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.removeAllSnapshots(); if (vmMo.safePowerOff(_shutdown_waitMs)) { state = State.Stopped; - return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, bytesSent, bytesRcvd); + return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, true); } else { String msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue"; s_logger.warn(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } } else { state = State.Stopped; @@ -2055,7 +2493,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is already in stopped state"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } finally { synchronized (_vms) { _vms.put(cmd.getVmName(), state); @@ -2068,7 +2506,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is no longer in vSphere"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } } catch (Exception e) { if (e instanceof RemoteException) { @@ -2078,7 +2516,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "StopCommand failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } } @@ -2087,17 +2525,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.info("Executing resource RebootRouterCommand: " + _gson.toJson(cmd)); } - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); if (answer.getResult()) { String connectResult = connect(cmd.getVmName(), cmd.getPrivateIpAddress()); @@ -2123,7 +2551,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmMo != null) { try { vmMo.rebootGuest(); - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } catch(ToolsUnavailable e) { s_logger.warn("VMware tools is not installed at guest OS, we will perform hard reset for reboot"); } catch(Exception e) { @@ -2132,16 +2560,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // continue to try with hard-reset if (vmMo.reset()) { - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } String msg = "Reboot failed in vSphere. vm: " + cmd.getVmName(); s_logger.warn(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } else { String msg = "Unable to find the VM in vSphere to reboot. vm: " + cmd.getVmName(); s_logger.warn(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } catch (Exception e) { if (e instanceof RemoteException) { @@ -2151,7 +2579,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "RebootCommand failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } @@ -3871,12 +4299,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /root/netusage.sh " + args + " on DomR " + privateIpAddress); + s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); } VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/netusage.sh " + args); + Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); if (!result.first()) { return null; diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4b8146b3be2..4a700cd9177 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -100,9 +100,12 @@ import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PingRoutingWithOvsCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -113,8 +116,11 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SetSourceNatAnswer; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -123,6 +129,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; @@ -134,16 +142,24 @@ import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.SetStaticRouteAnswer; +import com.cloud.agent.api.routing.SetStaticRouteCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; @@ -201,7 +217,6 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineName; import com.trilead.ssh2.SCPClient; import com.xensource.xenapi.Bond; import com.xensource.xenapi.Connection; @@ -512,12 +527,29 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((GetDomRVersionCmd)cmd); } else if (clazz == CheckNetworkCommand.class) { return execute((CheckNetworkCommand) cmd); + } else if (clazz == SetupGuestNetworkCommand.class) { + return execute((SetupGuestNetworkCommand) cmd); + } else if (clazz == PlugNicCommand.class) { + return execute((PlugNicCommand) cmd); + } else if (clazz == UnPlugNicCommand.class) { + return execute((UnPlugNicCommand) cmd); + } else if (clazz == IpAssocVpcCommand.class) { + return execute((IpAssocVpcCommand) cmd); + } else if (clazz == SetSourceNatCommand.class) { + return execute((SetSourceNatCommand) cmd); + } else if (clazz == SetNetworkACLCommand.class) { + return execute((SetNetworkACLCommand) cmd); + } else if (clazz == SetPortForwardingRulesVpcCommand.class) { + return execute((SetPortForwardingRulesVpcCommand) cmd); + } else if (clazz == SetStaticRouteCommand.class) { + return execute((SetStaticRouteCommand) cmd); + } else if (clazz == Site2SiteVpnCfgCommand.class) { + return execute((Site2SiteVpnCfgCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } - protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException { if (name != null) { if (s_logger.isDebugEnabled()) { @@ -756,7 +788,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (s_logger.isDebugEnabled()) { s_logger.debug("Creating VIF for " + vmName + " on nic " + nic); } - VIF.Record vifr = new VIF.Record(); vifr.VM = vm; vifr.device = Integer.toString(nic.getDeviceId()); @@ -937,7 +968,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (speed != null) { int cpuWeight = _maxWeight; //cpu_weight - int utilization = 0; // max CPU cap, default is unlimited + long utilization = 0; // max CPU cap, default is unlimited // weight based allocation cpuWeight = (int)((speed*0.99) / _host.speed * _maxWeight); @@ -946,12 +977,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (vmSpec.getLimitCpuUse()) { - utilization = (int)((speed*0.99) / _host.speed * 100); + utilization = (((long)speed * vmSpec.getCpus() * 100 ) / _host.speed); } vcpuParams.put("weight", Integer.toString(cpuWeight)); - vcpuParams.put("cap", Integer.toString(utilization)); - + vcpuParams.put("cap", Long.toString(utilization)); } if (vcpuParams.size() > 0) { @@ -1100,6 +1130,27 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return cdromVBD; } + protected void destroyPatchVbd(Connection conn, String vmName) throws XmlRpcException, XenAPIException { + try { + if( !vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-") ) { + return; + } + Set vms = VM.getByNameLabel(conn, vmName); + for ( VM vm : vms ) { + Set vbds = vm.getVBDs(conn); + for( VBD vbd : vbds ) { + if (vbd.getType(conn) == Types.VbdType.CD ) { + vbd.eject(conn); + vbd.destroy(conn); + break; + } + } + } + } catch (Exception e) { + s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e); + } + } + protected CheckSshAnswer execute(CheckSshCommand cmd) { Connection conn = getConnection(); String vmName = cmd.getName(); @@ -1115,6 +1166,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (result != null) { return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result); } + destroyPatchVbd(conn, vmName); } catch (Exception e) { return new CheckSshAnswer(cmd, e); } @@ -1334,8 +1386,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private CheckRouterAnswer execute(CheckRouterCommand cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "checkRouter", "args", args); + String args = "checkrouter.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); } @@ -1344,8 +1396,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "getDomRVersion", "args", args); + String args = "get_template_version.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); } @@ -1440,7 +1492,34 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new SetPortForwardingRulesAnswer(cmd, results, endResult); } + protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { + Connection conn = getConnection(); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + //String args = routerIp; + String[] results = new String[cmd.getRules().length]; + int i = 0; + boolean endResult = true; + for (StaticNatRuleTO rule : cmd.getRules()) { + String args = "vpc_staticnat.sh " + routerIp; + args += rule.revoked() ? " -D" : " -A"; + args += " -l " + rule.getSrcIp(); + args += " -r " + rule.getDstIp(); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args.toString()); + + if (result == null || result.isEmpty()) { + results[i++] = "Failed"; + endResult = false; + } else { + results[i++] = null; + } + } + return new SetStaticNatRulesAnswer(cmd, results, endResult); + } + protected SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { + if ( cmd.getVpcId() != null ) { + return SetVPCStaticNatRules(cmd); + } Connection conn = getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -1476,7 +1555,75 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new SetStaticNatRulesAnswer(cmd, results, endResult); } + protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) { + Connection conn = getConnection(); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + + if (routerIp == null) { + return new Answer(cmd); + } + + LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); + String[] config = cfgtr.generateConfiguration(cmd); + String tmpCfgFileContents = ""; + for (int i = 0; i < config.length; i++) { + tmpCfgFileContents += config[i]; + tmpCfgFileContents += "\n"; + } + String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; + String result = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", tmpCfgFilePath, "filecontents", tmpCfgFileContents); + + if (result == null || result.isEmpty()) { + return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file."); + } + + String[][] rules = cfgtr.generateFwRules(cmd); + + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; + + String args = "vpc_loadbalancer.sh " + routerIp; + + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); + } + + args += " -a " + sb.toString(); + } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + + if (result == null || result.isEmpty()) { + return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); + } + return new Answer(cmd); + } + protected Answer execute(final LoadBalancerConfigCommand cmd) { + if ( cmd.getVpcId() != null ) { + return VPCLoadBalancerConfig(cmd); + } Connection conn = getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -1573,7 +1720,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String args = "vpn_l2tp.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); if (cmd.isCreate()) { args += " -r " + cmd.getIpRange(); args += " -p " + cmd.getPresharedKey(); @@ -1585,7 +1732,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -d "; args += " -s " + cmd.getVpnServerIp(); } - String result = callHostPlugin(conn, "vmops", "lt2p_vpn", "args", args); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new Answer(cmd, false, "Configure VPN failed"); } @@ -1662,6 +1809,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd); } + protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, TrafficType trafficType, String name) throws InternalErrorException { @@ -1717,7 +1865,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); } - String args = privateIpAddress; + String args = "ipassoc.sh " + privateIpAddress; if (add) { args += " -A "; @@ -1743,7 +1891,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += vlanGateway; - String result = callHostPlugin(conn, "vmops", "ipassoc", "args", args); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); } @@ -1773,6 +1921,51 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + protected void assignVPCPublicIpAddress(Connection conn, String vmName, String routerIp, IpAddressTO ip) throws Exception { + + try { + VM router = getVM(conn, vmName); + + VIF correctVif = getCorrectVif(conn, router, ip); + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + String args = "vpc_ipassoc.sh " + routerIp; + + if (ip.isAdd()) { + args += " -A "; + } else { + args += " -D "; + } + + args += " -l "; + args += ip.getPublicIp(); + + args += " -c "; + args += "eth" + correctVif.getDevice(conn); + + args += " -g "; + args += ip.getVlanGateway(); + + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + + + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed."); + } + } catch (Exception e) { + String msg = "Unable to assign public IP address due to " + e.toString(); + s_logger.warn(msg, e); + throw new Exception(msg); + } + } + protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { if (option.equals("get")) { @@ -2679,7 +2872,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString()); setupLinkLocalNetwork(conn); - + // try to destroy CD-ROM device for all system VMs on this host + try { + Host host = Host.getByUuid(conn, _host.uuid); + Set vms = host.getResidentVMs(conn); + for ( VM vm : vms ) { + destroyPatchVbd(conn, vm.getNameLabel(conn)); + } + } catch (Exception e) { + } try { boolean result = cleanupHaltedVms(conn); if (!result) { @@ -2779,10 +2980,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vms = VM.getByNameLabel(conn, cmd.getVmName()); } catch (XenAPIException e0) { s_logger.debug("getByNameLabel failed " + e0.toString()); - return new RebootAnswer(cmd, "getByNameLabel failed " + e0.toString()); + return new RebootAnswer(cmd, "getByNameLabel failed " + e0.toString(), false); } catch (Exception e0) { s_logger.debug("getByNameLabel failed " + e0.getMessage()); - return new RebootAnswer(cmd, "getByNameLabel failed"); + return new RebootAnswer(cmd, "getByNameLabel failed", false); } for (VM vm : vms) { try { @@ -2790,10 +2991,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Exception e) { String msg = e.toString(); s_logger.warn(msg, e); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } finally { synchronized (_cluster.intern()) { s_vms.put(_cluster, _name, cmd.getVmName(), State.Running); @@ -2804,16 +3005,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected Answer execute(RebootRouterCommand cmd) { Connection conn = getConnection(); - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(conn, cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } RebootAnswer answer = execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); if (answer.getResult()) { String cnct = connect(conn, cmd.getVmName(), cmd.getPrivateIpAddress()); networkUsage(conn, cmd.getPrivateIpAddress(), "create", null); @@ -3276,23 +3468,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.info("VM does not exist on XenServer" + _host.uuid); s_vms.remove(_cluster, _name, vmName); } - return new StopAnswer(cmd, "VM does not exist", 0 , 0L, 0L); + return new StopAnswer(cmd, "VM does not exist", 0 , true); } - Long bytesSent = 0L; - Long bytesRcvd = 0L; for (VM vm : vms) { VM.Record vmr = vm.getRecord(conn); if (vmr.isControlDomain) { String msg = "Tring to Shutdown control domain"; s_logger.warn(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } if (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid)) { String msg = "Stop Vm " + vmName + " failed due to this vm is not running on this host: " + _host.uuid + " but host:" + vmr.residentOn.getUuid(conn); s_logger.warn(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } State state = s_vms.getState(_cluster, vmName); @@ -3306,13 +3496,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmr.powerState == VmPowerState.RUNNING) { /* when stop a vm, set affinity to current xenserver */ vm.setAffinity(conn, vm.getResidentOn(conn)); - if (VirtualMachineName.isValidRouterName(vmName)) { - if (cmd.getPrivateRouterIpAddress() != null) { - long[] stats = getNetworkStats(conn, cmd.getPrivateRouterIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - } + if (_canBridgeFirewall) { String result = callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", cmd .getVmName()); @@ -3327,7 +3511,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Exception e) { String msg = "Catch exception " + e.getClass().getName() + " when stop VM:" + cmd.getVmName() + " due to " + e.toString(); s_logger.debug(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } finally { try { @@ -3352,7 +3536,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe disableVlanNetwork(conn, network); } } - return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, bytesSent, bytesRcvd); + return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, true); } } catch (XenAPIException e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); @@ -3372,16 +3556,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (XenAPIException e) { String msg = "Stop Vm " + vmName + " fail due to " + e.toString(); s_logger.warn(msg, e); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } catch (XmlRpcException e) { String msg = "Stop Vm " + vmName + " fail due to " + e.getMessage(); s_logger.warn(msg, e); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } catch (Exception e) { s_logger.warn("Unable to stop " + vmName + " due to ", e); return new StopAnswer(cmd, e); } - return new StopAnswer(cmd, "Stop VM failed"); + return new StopAnswer(cmd, "Stop VM failed", false); } private List getVdis(Connection conn, VM vm) { @@ -3475,6 +3659,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe throw new CloudRuntimeException("Could not find an available slot in VM with name to attach a new disk."); } + + protected String getUnusedVIFNum(Connection conn, VM vm) { + String vmName = ""; + try { + vmName = vm.getNameLabel(conn); + Set allowedVIFDevices = vm.getAllowedVIFDevices(conn); + if (allowedVIFDevices.size() > 0) { + return allowedVIFDevices.iterator().next(); + } + } catch (Exception e) { + String msg = "getUnusedVIFNum failed due to " + e.toString(); + s_logger.warn(msg, e); + } + throw new CloudRuntimeException("Could not find available VIF slot in VM with name: " + vmName + " to plug a VIF"); + } + protected String callHostPlugin(Connection conn, String plugin, String cmd, String... params) { Map args = new HashMap(); String msg; @@ -3569,6 +3769,41 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return null; } + + protected VIF getCorrectVif(Connection conn, VM router, IpAddressTO ip) throws XmlRpcException, XenAPIException { + NicTO nic = new NicTO(); + nic.setType(ip.getTrafficType()); + nic.setName(ip.getNetworkName()); + if (ip.getVlanId() == null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + nic.setBroadcastType(BroadcastDomainType.Vlan); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanId())); + } + Network network = getNetwork(conn, nic); + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + Set routerVIFs = router.getVIFs(conn); + for (VIF vif : routerVIFs) { + Network vifNetwork = vif.getNetwork(conn); + if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) { + return vif; + } + } + return null; + } + + protected VIF getVifByMac(Connection conn, VM router, String mac) throws XmlRpcException, XenAPIException { + Set routerVIFs = router.getVIFs(conn); + mac = mac.trim(); + for (VIF vif : routerVIFs) { + String lmac = vif.getMAC(conn); + if (lmac.trim().equals(mac)) { + return vif; + } + } + return null; + } protected String getLowestAvailableVIFDeviceNum(Connection conn, VM vm) { try { @@ -3936,10 +4171,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } Connection conn = getConnection(); - /**if (!_canBridgeFirewall && !_isOvs) { + if (!_canBridgeFirewall && !_isOvs) { return new PingRoutingCommand(getType(), id, null); - } else**/ - if (_isOvs) { + } else if (_isOvs) { List>ovsStates = ovsFullSyncStates(); return new PingRoutingWithOvsCommand(getType(), id, null, ovsStates); }else { @@ -6954,7 +7188,294 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return changes; } + /** + * @param cmd + * @return + */ + private UnPlugNicAnswer execute(UnPlugNicCommand cmd) { + Connection conn = getConnection(); + VirtualMachineTO vmto = cmd.getVirtualMachine(); + String vmName = vmto.getName(); + try { + Set vms = VM.getByNameLabel(conn, vmName); + if ( vms == null || vms.isEmpty() ) { + return new UnPlugNicAnswer(cmd, false, "Can not find VM " + vmName); + } + VM vm = vms.iterator().next(); + NicTO nic = cmd.getNic(); + String mac = nic.getMac(); + for ( VIF vif : vm.getVIFs(conn)) { + String lmac = vif.getMAC(conn); + if ( lmac.equals(mac) ) { + vif.unplug(conn); + vif.destroy(conn); + break; + } + } + return new UnPlugNicAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new UnPlugNicAnswer(cmd, false, msg); + } + } + /** + * @param cmd + * @return + */ + private PlugNicAnswer execute(PlugNicCommand cmd) { + Connection conn = getConnection(); + VirtualMachineTO vmto = cmd.getVirtualMachine(); + String vmName = vmto.getName(); + try { + Set vms = VM.getByNameLabel(conn, vmName); + if ( vms == null || vms.isEmpty() ) { + return new PlugNicAnswer(cmd, false, "Can not find VM " + vmName); + } + VM vm = vms.iterator().next(); + NicTO nic = cmd.getNic(); + String deviceId = getUnusedVIFNum(conn, vm); + nic.setDeviceId(Integer.parseInt(deviceId)); + VIF vif = createVif(conn, vmName, vm, nic); + vif.plug(conn); + return new PlugNicAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " Plug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new PlugNicAnswer(cmd, false, msg); + } + } + /** + * @param cmd + * @return + */ + private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + Connection conn = getConnection(); + NicTO nic = cmd.getNic(); + String domrIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));; + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2= cmd.getDefaultDns2(); + if ( dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + try { + Set vms = VM.getByNameLabel(conn, domrName); + if ( vms == null || vms.isEmpty() ) { + return new SetupGuestNetworkAnswer(cmd, false, "Can not find VM " + domrName); + } + VM vm = vms.iterator().next(); + String mac = nic.getMac(); + VIF domrVif = null; + for ( VIF vif : vm.getVIFs(conn)) { + String lmac = vif.getMAC(conn); + if ( lmac.equals(mac) ) { + domrVif = vif; + break; + } + } + if ( domrVif == null ) { + return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); + } + String args = "vpc_guestnw.sh " + domrIP + " -C"; + String dev = "eth" + domrVif.getDevice(conn); + args += " -d " + dev; + args += " -i " + domrGIP; + args += " -g " + gw; + args += " -m " + cidr; + args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); + if ( dns != null && !dns.isEmpty() ) { + args += " -s " + dns; + } + if ( domainName != null && !domainName.isEmpty() ) { + args += " -e " + domainName; + } + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + ((result == null)? "null":result)); + } + return new SetupGuestNetworkAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + } + + protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + Connection conn = getConnection(); + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + assignVPCPublicIpAddress(conn, routerName, routerIp, ip); + results[i++] = ip.getPublicIp() + " - success"; + } + } catch (Exception e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + results[i++] = IpAssocAnswer.errorResult; + } + + return new IpAssocAnswer(cmd, results); + } + + protected Answer execute(Site2SiteVpnCfgCommand cmd) { + Connection conn = getConnection(); + String args = "ipsectunnel.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + if (cmd.isCreate()) { + args += " -A"; + args += " -l "; + args += cmd.getLocalPublicIp(); + args += " -n "; + args += cmd.getLocalGuestCidr(); + args += " -g "; + args += cmd.getLocalPublicGateway(); + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + args += " -e "; + args += cmd.getEspPolicy(); + args += " -i "; + args += cmd.getIkePolicy(); + args += " -t "; + args += Long.toString(cmd.getLifetime()); + args += " -s "; + args += cmd.getIpsecPsk(); + } else { + args += " -D"; + args += " -r "; + args += cmd.getPeerGatewayIp(); + args += " -N "; + args += cmd.getPeerGuestCidrList(); + } + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + return new Answer(cmd, false, "Configure site to site VPN failed! "); + } + return new Answer(cmd); + } + + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + Connection conn = getConnection(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + IpAddressTO pubIp = cmd.getIpAddress(); + try { + VM router = getVM(conn, routerName); + + VIF correctVif = getCorrectVif(conn, router, pubIp); + + String args = "vpc_snat.sh " + routerIp; + + args += " -A "; + args += " -l "; + args += pubIp.getPublicIp(); + + args += " -c "; + args += "eth" + correctVif.getDevice(conn); + + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + throw new InternalErrorException("Xen plugin \"vpc_snat\" failed."); + } + return new SetSourceNatAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = "Ip SNAT failure due to " + e.toString(); + s_logger.error(msg, e); + return new SetSourceNatAnswer(cmd, false, msg); + } + } + + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + String[] results = new String[cmd.getRules().length]; + String callResult; + Connection conn = getConnection(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + try { + VM router = getVM(conn, routerName); + String [][] rules = cmd.generateFwRules(); + StringBuilder sb = new StringBuilder(); + String[] aclRules = rules[0]; + if (aclRules.length == 0) { + return new SetNetworkACLAnswer(cmd, true, results); + } + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + NicTO nic = cmd.getNic(); + VIF vif = getVifByMac(conn, router, nic.getMac()); + String args = "vpc_acl.sh " + routerIp; + args += " -d " + "eth" + vif.getDevice(conn); + args += " -i " + nic.getIp(); + args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + args += " -a " + sb.toString(); + callResult = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (callResult == null || callResult.isEmpty()) { + //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails + for (int i=0; i < results.length; i++) { + results[i] = "Failed"; + } + return new SetNetworkACLAnswer(cmd, false, results); + } + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); + } + } + + protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { + Connection conn = getConnection(); + + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String[] results = new String[cmd.getRules().length]; + int i = 0; + + boolean endResult = true; + for (PortForwardingRuleTO rule : cmd.getRules()) { + String args ="vpc_portforwarding.sh " + routerIp; + args += rule.revoked() ? " -D" : " -A"; + args += " -P " + rule.getProtocol().toLowerCase(); + args += " -l " + rule.getSrcIp(); + args += " -p " + rule.getStringSrcPortRange(); + args += " -r " + rule.getDstIp(); + args += " -d " + rule.getStringDstPortRange().replace(":", "-"); + + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args.toString()); + + if (result == null || result.isEmpty()) { + results[i++] = "Failed"; + endResult = false; + } else { + results[i++] = null; + } + } + return new SetPortForwardingRulesAnswer(cmd, results, endResult); + } + + + private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { + // TODO Auto-generated method stub + return new SetStaticRouteAnswer(cmd, true, null); + } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index ff0c5d7b87c..7edc74212c5 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -142,27 +142,70 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - String args = null; + String args = "netusage.sh " + privateIpAddress + " "; if (option.equals("get")) { - args = "-g"; + args += "-g"; } else if (option.equals("create")) { - args = "-c"; + args += "-c"; } else if (option.equals("reset")) { - args = "-r"; + args += "-r"; } else if (option.equals("addVif")) { - args = "-a"; + args += "-a "; args += vif; } else if (option.equals("deleteVif")) { - args = "-d"; + args += "-d "; args += vif; } - args += " -i "; - args += privateIpAddress; - return callHostPlugin(conn, "vmops", "networkUsage", "args", args); + return callHostPlugin(conn, "vmops", "routerProxy", "args", args); + } + + protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { + try { + Connection conn = getConnection(); + String option = cmd.getOption(); + String guestIp = cmd.getGuestNic().getIp(); + + String args = "vpc_netusage.sh " + cmd.getPrivateIP() + " "; + if (option.equals("get")) { + args += "-g"; + args += " -l " + guestIp; + } else if (option.equals("create")) { + args += "-c"; + } else if (option.equals("reset")) { + args += "-r"; + args += " -l " + guestIp; + } else { + return new NetworkUsageAnswer(cmd, "success", 0L, 0L); + } + + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (option.equals("get")) { + long[] stats = new long[2]; + if (result != null) { + String[] splitResult = result.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += (new Long(splitResult[i++])).longValue(); + stats[1] += (new Long(splitResult[i++])).longValue(); + } + return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); + } + } + if (result == null || result.isEmpty()) { + throw new Exception(" vpc network usage plugin call failed "); + } + return new NetworkUsageAnswer(cmd, "success", 0L, 0L); + } catch (Exception ex) { + s_logger.warn("Failed to get network usage stats due to ", ex); + return new NetworkUsageAnswer(cmd, ex); + } } protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { + if ( cmd.isForVpc() ) { + return VPCNetworkUsage(cmd); + } try { Connection conn = getConnection(); if(cmd.getOption()!=null && cmd.getOption().equals("create") ){ diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index b9fc038dca6..3cfed1f24c8 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -293,7 +293,7 @@ public class DownloadManagerImpl implements DownloadManager { } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); - checksum = String.format("%032x",bigInt.toString(16)); + checksum = String.format("%032x",bigInt); return checksum; }catch(IOException e) { return null; diff --git a/core/src/com/cloud/vm/DomainRouterVO.java b/core/src/com/cloud/vm/DomainRouterVO.java index 42c14c64e1a..463d68ebb07 100755 --- a/core/src/com/cloud/vm/DomainRouterVO.java +++ b/core/src/com/cloud/vm/DomainRouterVO.java @@ -41,12 +41,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Column(name="public_netmask") private String publicNetmask; - - @Column(name="guest_ip_address") - private String guestIpAddress; - - @Column(name="network_id") - long networkId; @Column(name="is_redundant_router") boolean isRedundantRouter; @@ -74,6 +68,9 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Column(name="scripts_version") private String scriptsVersion; + @Column(name="vpc_id") + private Long vpcId; + public DomainRouterVO(long id, long serviceOfferingId, long elementId, @@ -83,20 +80,20 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { long guestOSId, long domainId, long accountId, - long networkId, boolean isRedundantRouter, int priority, boolean isPriorityBumpUp, RedundantState redundantState, - boolean haEnabled, boolean stopPending) { + boolean haEnabled, + boolean stopPending, Long vpcId) { super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); this.elementId = elementId; - this.networkId = networkId; this.isRedundantRouter = isRedundantRouter; this.priority = priority; this.redundantState = redundantState; this.isPriorityBumpUp = isPriorityBumpUp; this.stopPending = stopPending; + this.vpcId = vpcId; } public DomainRouterVO(long id, @@ -108,21 +105,21 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { long guestOSId, long domainId, long accountId, - long networkId, boolean isRedundantRouter, int priority, boolean isPriorityBumpUp, RedundantState redundantState, boolean haEnabled, - boolean stopPending, VirtualMachine.Type vmType) { + boolean stopPending, + VirtualMachine.Type vmType, Long vpcId) { super(id, serviceOfferingId, name, name, vmType, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); this.elementId = elementId; - this.networkId = networkId; this.isRedundantRouter = isRedundantRouter; this.priority = priority; this.redundantState = redundantState; this.isPriorityBumpUp = isPriorityBumpUp; this.stopPending = stopPending; + this.vpcId = vpcId; } public long getElementId() { @@ -141,14 +138,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { this.publicNetmask = publicNetmask; } - public long getNetworkId() { - return networkId; - } - - public void setGuestIpAddress(String routerIpAddress) { - this.guestIpAddress = routerIpAddress; - } - @Override public long getDataCenterIdToDeployIn() { return dataCenterIdToDeployIn; @@ -162,11 +151,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { return publicMacAddress; } - @Override - public String getGuestIpAddress() { - return guestIpAddress; - } - protected DomainRouterVO() { super(); } @@ -249,4 +233,14 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { public void setScriptsVersion(String scriptsVersion) { this.scriptsVersion = scriptsVersion; } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public boolean canPlugNics() { + return true; + } } diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index f9c57f5931e..2d9eeb6a00d 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -458,5 +458,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject res = OvmVm.reboot(_conn, vmName); Integer vncPort = Integer.parseInt(res.get("vncPort")); - return new RebootAnswer(cmd, null, null, null, vncPort); + return new RebootAnswer(cmd, null, vncPort); } catch (Exception e) { s_logger.debug("Reboot " + vmName + " failed", e); - return new RebootAnswer(cmd, e.getMessage()); + return new RebootAnswer(cmd, e.getMessage(), false); } finally { synchronized(_vms) { _vms.put(cmd.getVmName(), State.Running); diff --git a/patches/systemvm/debian/config/etc/cloud-nic.rules b/patches/systemvm/debian/config/etc/cloud-nic.rules new file mode 100644 index 00000000000..56e74ec4e9d --- /dev/null +++ b/patches/systemvm/debian/config/etc/cloud-nic.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="net" KERNEL=="eth*" RUN+="/opt/cloud/bin/cloud-nic.sh $env{ACTION} %k" + diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 19f87c23e04..d46a1e733e8 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -550,6 +550,79 @@ setup_router() { cp /etc/iptables/iptables-router /etc/iptables/rules } + + +setup_vpcrouter() { + log_it "Setting up VPC virtual router system vm" + + if [ "$hyp" == "vmware" ]; then + setup_vmware_extra_nics + fi + + cat > /etc/network/interfaces << EOF +auto lo $1 +iface lo inet loopback +EOF + setup_interface "0" $ETH0_IP $ETH0_MASK $GW + + echo $NAME > /etc/hostname + echo 'AVAHI_DAEMON_DETECT_LOCAL=0' > /etc/default/avahi-daemon + hostname $NAME + + #Nameserver + sed -i -e "/^nameserver.*$/d" /etc/resolv.conf # remove previous entries + sed -i -e "/^nameserver.*$/d" /etc/dnsmasq-resolv.conf # remove previous entries + if [ -n "$internalNS1" ] + then + echo "nameserver $internalNS1" > /etc/dnsmasq-resolv.conf + echo "nameserver $internalNS1" > /etc/resolv.conf + fi + + if [ -n "$internalNS2" ] + then + echo "nameserver $internalNS2" >> /etc/dnsmasq-resolv.conf + echo "nameserver $internalNS2" >> /etc/resolv.conf + fi + if [ -n "$NS1" ] + then + echo "nameserver $NS1" >> /etc/dnsmasq-resolv.conf + echo "nameserver $NS1" >> /etc/resolv.conf + fi + + if [ -n "$NS2" ] + then + echo "nameserver $NS2" >> /etc/dnsmasq-resolv.conf + echo "nameserver $NS2" >> /etc/resolv.conf + fi + if [ -n "$MGMTNET" -a -n "$LOCAL_GW" ] + then + ip route add $MGMTNET via $LOCAL_GW dev eth1 + fi + + ip route delete default + + + sed -i /gateway/d /etc/hosts + + echo "$ETH0_IP $NAME" >> /etc/hosts + setup_sshd $ETH0_IP + + enable_svc dnsmasq 1 + enable_svc haproxy 1 + enable_svc cloud-passwd-srvr 1 + enable_svc cloud 0 + disable_rpfilter_domR + enable_fwding 1 + chkconfig nfs-common off + cp /etc/iptables/iptables-vpcrouter /etc/iptables/rules + cp /etc/vpcdnsmasq.conf /etc/dnsmasq.conf + cp /etc/cloud-nic.rules /etc/udev/rules.d/cloud-nic.rules + echo "" > /etc/dnsmasq.d/dhcphosts.txt + echo "dhcp-hostsfile=/etc/dhcphosts.txt" > /etc/dnsmasq.d/cloud.conf +} + + + setup_dhcpsrvr() { log_it "Setting up dhcp server system vm" setup_common eth0 eth1 @@ -721,6 +794,10 @@ start() { [ "$NAME" == "" ] && NAME=router setup_router ;; + vpcrouter) + [ "$NAME" == "" ] && NAME=vpcrouter + setup_vpcrouter + ;; dhcpsrvr) [ "$NAME" == "" ] && NAME=dhcpsrvr setup_dhcpsrvr diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter new file mode 100644 index 00000000000..8e3069bc033 --- /dev/null +++ b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter @@ -0,0 +1,24 @@ +*nat +:PREROUTING ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +COMMIT +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -d 224.0.0.18/32 -j ACCEPT +-A INPUT -d 225.0.0.50/32 -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -i eth0 -p tcp --dport 3922 -j ACCEPT +-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT +COMMIT +*mangle +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +-A OUTPUT -p udp --dport bootpc -j CHECKSUM --checksum-fill +COMMIT diff --git a/patches/systemvm/debian/config/etc/vpcdnsmasq.conf b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf new file mode 100644 index 00000000000..3717fc8a80c --- /dev/null +++ b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf @@ -0,0 +1,465 @@ +# Configuration file for dnsmasq. +# +# Format is one option per line, legal options are the same +# as the long options legal on the command line. See +# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. + +# The following two options make you a better netizen, since they +# tell dnsmasq to filter out queries which the public DNS cannot +# answer, and which load the servers (especially the root servers) +# uneccessarily. If you have a dial-on-demand link they also stop +# these requests from bringing up the link uneccessarily. + +# Never forward plain names (without a dot or domain part) +domain-needed +# Never forward addresses in the non-routed address spaces. +bogus-priv + + +# Uncomment this to filter useless windows-originated DNS requests +# which can trigger dial-on-demand links needlessly. +# Note that (amongst other things) this blocks all SRV requests, +# so don't use it if you use eg Kerberos. +# This option only affects forwarding, SRV records originating for +# dnsmasq (via srv-host= lines) are not suppressed by it. +#filterwin2k + +# Change this line if you want dns to get its upstream servers from +# somewhere other that /etc/resolv.conf +resolv-file=/etc/dnsmasq-resolv.conf + +# By default, dnsmasq will send queries to any of the upstream +# servers it knows about and tries to favour servers to are known +# to be up. Uncommenting this forces dnsmasq to try each query +# with each server strictly in the order they appear in +# /etc/resolv.conf +#strict-order + +# If you don't want dnsmasq to read /etc/resolv.conf or any other +# file, getting its servers from this file instead (see below), then +# uncomment this. +#no-resolv + +# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv +# files for changes and re-read them then uncomment this. +#no-poll + +# Add other name servers here, with domain specs if they are for +# non-public domains. +#server=/localnet/192.168.0.1 + +# Example of routing PTR queries to nameservers: this will send all +# address->name queries for 192.168.3/24 to nameserver 10.1.2.3 +#server=/3.168.192.in-addr.arpa/10.1.2.3 + +# Add local-only domains here, queries in these domains are answered +# from /etc/hosts or DHCP only. +local=/2.vmops-test.vmops.com/ + +# Add domains which you want to force to an IP address here. +# The example below send any host in doubleclick.net to a local +# webserver. +#address=/doubleclick.net/127.0.0.1 + +# If you want dnsmasq to change uid and gid to something other +# than the default, edit the following lines. +#user= +#group= + +# If you want dnsmasq to listen for DHCP and DNS requests only on +# specified interfaces (and the loopback) give the name of the +# interface (eg eth0) here. +# Repeat the line for more than one interface. +#interface=eth0 + +# Or you can specify which interface _not_ to listen on +except-interface=lo + +# Or which to listen on by address (remember to include 127.0.0.1 if +# you use this.) +#listen-address= +# If you want dnsmasq to provide only DNS service on an interface, +# configure it as shown above, and then use the following line to +# disable DHCP on it. +#no-dhcp-interface=eth1 + +# On systems which support it, dnsmasq binds the wildcard address, +# even when it is listening on only some interfaces. It then discards +# requests that it shouldn't reply to. This has the advantage of +# working even when interfaces come and go and change address. If you +# want dnsmasq to really bind only the interfaces it is listening on, +# uncomment this option. About the only time you may need this is when +# running another nameserver on the same machine. +bind-interfaces + +# If you don't want dnsmasq to read /etc/hosts, uncomment the +# following line. +#no-hosts +# or if you want it to read another file, as well as /etc/hosts, use +# this. +#addn-hosts=/etc/banner_add_hosts + +# Set this (and domain: see below) if you want to have a domain +# automatically added to simple names in a hosts-file. +expand-hosts + +# Set the domain for dnsmasq. this is optional, but if it is set, it +# does the following things. +# 1) Allows DHCP hosts to have fully qualified domain names, as long +# as the domain part matches this setting. +# 2) Sets the "domain" DHCP option thereby potentially setting the +# domain of all systems configured by DHCP +# 3) Provides the domain part for "expand-hosts" +#domain=2.vmops-test.vmops.com + +# Uncomment this to enable the integrated DHCP server, you need +# to supply the range of addresses available for lease and optionally +# a lease time. If you have more than one network, you will need to +# repeat this for each network on which you want to supply DHCP +# service. +#dhcp-range=10.1.1.1,static +#dhcp-range=10.0.0.1,10.255.255.255 +#dhcp-hostsfile=/etc/dhcphosts.txt + +# This is an example of a DHCP range where the netmask is given. This +# is needed for networks we reach the dnsmasq DHCP server via a relay +# agent. If you don't know what a DHCP relay agent is, you probably +# don't need to worry about this. +#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h + +# This is an example of a DHCP range with a network-id, so that +# some DHCP options may be set only for this network. +#dhcp-range=red,192.168.0.50,192.168.0.150 + +# Supply parameters for specified hosts using DHCP. There are lots +# of valid alternatives, so we will give examples of each. Note that +# IP addresses DO NOT have to be in the range given above, they just +# need to be on the same network. The order of the parameters in these +# do not matter, it's permissble to give name,adddress and MAC in any order + +# Always allocate the host with ethernet address 11:22:33:44:55:66 +# The IP address 192.168.0.60 +#dhcp-host=11:22:33:44:55:66,192.168.0.60 + +# Always set the name of the host with hardware address +# 11:22:33:44:55:66 to be "fred" +#dhcp-host=11:22:33:44:55:66,fred + +# Always give the host with ethernet address 11:22:33:44:55:66 +# the name fred and IP address 192.168.0.60 and lease time 45 minutes +#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m + +# Give the machine which says it's name is "bert" IP address +# 192.168.0.70 and an infinite lease +#dhcp-host=bert,192.168.0.70,infinite + +# Always give the host with client identifier 01:02:02:04 +# the IP address 192.168.0.60 +#dhcp-host=id:01:02:02:04,192.168.0.60 + +# Always give the host with client identifier "marjorie" +# the IP address 192.168.0.60 +#dhcp-host=id:marjorie,192.168.0.60 + +# Enable the address given for "judge" in /etc/hosts +# to be given to a machine presenting the name "judge" when +# it asks for a DHCP lease. +#dhcp-host=judge + +# Never offer DHCP service to a machine whose ethernet +# address is 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,ignore + +# Ignore any client-id presented by the machine with ethernet +# address 11:22:33:44:55:66. This is useful to prevent a machine +# being treated differently when running under different OS's or +# between PXE boot and OS boot. +#dhcp-host=11:22:33:44:55:66,id:* + +# Send extra options which are tagged as "red" to +# the machine with ethernet address 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,net:red + +# Send extra options which are tagged as "red" to +# any machine with ethernet address starting 11:22:33: +#dhcp-host=11:22:33:*:*:*,net:red + +# Ignore any clients which are specified in dhcp-host lines +# or /etc/ethers. Equivalent to ISC "deny unkown-clients". +# This relies on the special "known" tag which is set when +# a host is matched. +#dhcp-ignore=#known + +# Send extra options which are tagged as "red" to any machine whose +# DHCP vendorclass string includes the substring "Linux" +#dhcp-vendorclass=red,Linux + +# Send extra options which are tagged as "red" to any machine one +# of whose DHCP userclass strings includes the substring "accounts" +#dhcp-userclass=red,accounts + +# Send extra options which are tagged as "red" to any machine whose +# MAC address matches the pattern. +#dhcp-mac=red,00:60:8C:*:*:* + +# If this line is uncommented, dnsmasq will read /etc/ethers and act +# on the ethernet-address/IP pairs found there just as if they had +# been given as --dhcp-host options. Useful if you keep +# MAC-address/host mappings there for other purposes. +#read-ethers + +# Send options to hosts which ask for a DHCP lease. +# See RFC 2132 for details of available options. +# Common options can be given to dnsmasq by name: +# run "dnsmasq --help dhcp" to get a list. +# Note that all the common settings, such as netmask and +# broadcast address, DNS server and default route, are given +# sane defaults by dnsmasq. You very likely will not need +# any dhcp-options. If you use Windows clients and Samba, there +# are some options which are recommended, they are detailed at the +# end of this section. + +# Override the default route supplied by dnsmasq, which assumes the +# router is the same machine as the one running dnsmasq. +#dhcp-option=3,1.2.3.4 + +# Do the same thing, but using the option name +#dhcp-option=option:router,1.2.3.4 + +# Override the default route supplied by dnsmasq and send no default +# route at all. Note that this only works for the options sent by +# default (1, 3, 6, 12, 28) the same line will send a zero-length option +# for all other option numbers. +#dhcp-option=3 + +# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 +#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5 + +# Set the NTP time server address to be the same machine as +# is running dnsmasq +#dhcp-option=42,0.0.0.0 + +# Set the NIS domain name to "welly" +#dhcp-option=40,welly + +# Set the default time-to-live to 50 +#dhcp-option=23,50 + +# Set the "all subnets are local" flag +#dhcp-option=27,1 + +# Set the domain +dhcp-option=15,"2.vmops-test.vmops.com" + +# Send the etherboot magic flag and then etherboot options (a string). +#dhcp-option=128,e4:45:74:68:00:00 +#dhcp-option=129,NIC=eepro100 + +# Specify an option which will only be sent to the "red" network +# (see dhcp-range for the declaration of the "red" network) +# Note that the net: part must precede the option: part. +#dhcp-option = net:red, option:ntp-server, 192.168.1.1 + +# The following DHCP options set up dnsmasq in the same way as is specified +# for the ISC dhcpcd in +# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt +# adapted for a typical dnsmasq installation where the host running +# dnsmasq is also the host running samba. +# you may want to uncomment them if you use Windows clients and Samba. +#dhcp-option=19,0 # option ip-forwarding off +#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s) +#dhcp-option=45,0.0.0.0 # netbios datagram distribution server +#dhcp-option=46,8 # netbios node type +#dhcp-option=47 # empty netbios scope. + +# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client +# probably doesn't support this...... +#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com + +# Send RFC-3442 classless static routes (note the netmask encoding) +#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8 + +# Send vendor-class specific options encapsulated in DHCP option 43. +# The meaning of the options is defined by the vendor-class so +# options are sent only when the client supplied vendor class +# matches the class given here. (A substring match is OK, so "MSFT" +# matches "MSFT" and "MSFT 5.0"). This example sets the +# mtftp address to 0.0.0.0 for PXEClients. +#dhcp-option=vendor:PXEClient,1,0.0.0.0 + +# Send microsoft-specific option to tell windows to release the DHCP lease +# when it shuts down. Note the "i" flag, to tell dnsmasq to send the +# value as a four-byte integer - that's what microsoft wants. See +# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true +dhcp-option=vendor:MSFT,2,1i + +# Send the Encapsulated-vendor-class ID needed by some configurations of +# Etherboot to allow is to recognise the DHCP server. +#dhcp-option=vendor:Etherboot,60,"Etherboot" + +# Send options to PXELinux. Note that we need to send the options even +# though they don't appear in the parameter request list, so we need +# to use dhcp-option-force here. +# See http://syslinux.zytor.com/pxe.php#special for details. +# Magic number - needed before anything else is recognised +#dhcp-option-force=208,f1:00:74:7e +# Configuration file name +#dhcp-option-force=209,configs/common +# Path prefix +#dhcp-option-force=210,/tftpboot/pxelinux/files/ +# Reboot time. (Note 'i' to send 32-bit value) +#dhcp-option-force=211,30i + +# Set the boot filename for BOOTP. You will only need +# this is you want to boot machines over the network and you will need +# a TFTP server; either dnsmasq's built in TFTP server or an +# external one. (See below for how to enable the TFTP server.) +#dhcp-boot=pxelinux.0 + +# Enable dnsmasq's built-in TFTP server +#enable-tftp + +# Set the root directory for files availble via FTP. +#tftp-root=/var/ftpd + +# Make the TFTP server more secure: with this set, only files owned by +# the user dnsmasq is running as will be send over the net. +#tftp-secure + +# Set the boot file name only when the "red" tag is set. +#dhcp-boot=net:red,pxelinux.red-net + +# An example of dhcp-boot with an external server: the name and IP +# address of the server are given after the filename. +#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3 + +# Set the limit on DHCP leases, the default is 150 +#dhcp-lease-max=150 + +# The DHCP server needs somewhere on disk to keep its lease database. +# This defaults to a sane location, but if you want to change it, use +# the line below. +#dhcp-leasefile=/var/lib/misc/dnsmasq.leases +leasefile-ro + +# Set the DHCP server to authoritative mode. In this mode it will barge in +# and take over the lease for any client which broadcasts on the network, +# whether it has a record of the lease or not. This avoids long timeouts +# when a machine wakes up on a new network. DO NOT enable this if there's +# the slighest chance that you might end up accidentally configuring a DHCP +# server for your campus/company accidentally. The ISC server uses +# the same option, and this URL provides more information: +# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php +#dhcp-authoritative + +# Run an executable when a DHCP lease is created or destroyed. +# The arguments sent to the script are "add" or "del", +# then the MAC address, the IP address and finally the hostname +# if there is one. +#dhcp-script=/bin/echo + +# Set the cachesize here. +#cache-size=150 + +# If you want to disable negative caching, uncomment this. +#no-negcache + +# Normally responses which come form /etc/hosts and the DHCP lease +# file have Time-To-Live set as zero, which conventionally means +# do not cache further. If you are happy to trade lower load on the +# server for potentially stale date, you can set a time-to-live (in +# seconds) here. +#local-ttl= + +# If you want dnsmasq to detect attempts by Verisign to send queries +# to unregistered .com and .net hosts to its sitefinder service and +# have dnsmasq instead return the correct NXDOMAIN response, uncomment +# this line. You can add similar lines to do the same for other +# registries which have implemented wildcard A records. +#bogus-nxdomain=64.94.110.11 + +# If you want to fix up DNS results from upstream servers, use the +# alias option. This only works for IPv4. +# This alias makes a result of 1.2.3.4 appear as 5.6.7.8 +#alias=1.2.3.4,5.6.7.8 +# and this maps 1.2.3.x to 5.6.7.x +#alias=1.2.3.0,5.6.7.0,255.255.255.0 + + +# Change these lines if you want dnsmasq to serve MX records. + +# Return an MX record named "maildomain.com" with target +# servermachine.com and preference 50 +#mx-host=maildomain.com,servermachine.com,50 + +# Set the default target for MX records created using the localmx option. +#mx-target=servermachine.com + +# Return an MX record pointing to the mx-target for all local +# machines. +#localmx + +# Return an MX record pointing to itself for all local machines. +#selfmx + +# Change the following lines if you want dnsmasq to serve SRV +# records. These are useful if you want to serve ldap requests for +# Active Directory and other windows-originated DNS requests. +# See RFC 2782. +# You may add multiple srv-host lines. +# The fields are ,,,, +# If the domain part if missing from the name (so that is just has the +# service and protocol sections) then the domain given by the domain= +# config option is used. (Note that expand-hosts does not need to be +# set for this to work.) + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 289 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389 + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 289 (using domain=) +###domain=example.com +#srv-host=_ldap._tcp,ldapserver.example.com,389 + +# Two SRV records for LDAP, each with different priorities +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2 + +# A SRV record indicating that there is no LDAP server for the domain +# example.com +#srv-host=_ldap._tcp.example.com + +# The following line shows how to make dnsmasq serve an arbitrary PTR +# record. This is useful for DNS-SD. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for PTR records.) +#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services" + +# Change the following lines to enable dnsmasq to serve TXT records. +# These are used for things like SPF and zeroconf. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for TXT records.) + +#Example SPF. +#txt-record=example.com,"v=spf1 a -all" + +#Example zeroconf +#txt-record=_http._tcp.example.com,name=value,paper=A4 + + +# For debugging purposes, log each DNS query as it passes through +# dnsmasq. +#log-queries + +# Log lots of extra information about DHCP transactions. +#log-dhcp + +log-facility=/var/log/dnsmasq.log + +# Include a another lot of configuration options. +#conf-file=/etc/dnsmasq.more.conf +conf-dir=/etc/dnsmasq.d + +# Don't reply Windows's periodical DNS request +filterwin2k diff --git a/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh b/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh new file mode 100755 index 00000000000..3198824bc1b --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +if [ -z $1 ] +then + echo "Fail to find VPN peer address!" + exit 1 +fi + +ipsec auto --status | grep vpn-$1 > /tmp/vpn-$1.status + +cat /tmp/vpn-$1.status | grep "ISAKMP SA established" > /dev/null +isakmpok=$? +if [ $isakmpok -ne 0 ] +then + echo "ISAKMP SA not found" + echo "Site-to-site VPN have not connected" + exit 12 +fi +echo "ISAKMP SA found" + +cat /tmp/vpn-$1.status | grep "IPsec SA established" > /dev/null +ipsecok=$? +if [ $ipsecok -ne 0 ] +then + echo "IPsec SA not found" + echo "Site-to-site VPN have not connected" + exit 11 +fi +echo "IPsec SA found" +echo "Site-to-site VPN have connected" +exit 0 diff --git a/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh b/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh new file mode 100755 index 00000000000..3d8de19ba5f --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + + +plug_nic() { + sudo echo "$tableNo $tableName" >> /etc/iproute2/rt_tables 2>/dev/null + sudo ip rule add fwmark $tableNo table $tableName 2>/dev/null + sudo ip route flush table $tableName + sudo ip route flush cache +} + + +unplug_nic() { + sudo iptables -t mangle -D PREROUTING -i $dev -m state --state NEW -j CONNMARK --set-mark $tableNo 2>/dev/null + + sudo ip rule del fwmark $tableNo 2>/dev/null + sudo ip route flush table $tableName + sudo sed -i /"$tableNo $tableName"/d /etc/iproute2/rt_tables 2>/dev/null + sudo ip route flush cache + # remove usage + sudo iptables -t mangle -F NETWORK_STATS_$dev 2>/dev/null + iptables-save | grep NETWORK_STATS_$dev | grep "\-A" | while read rule + do + rule=$(echo $rule | sed 's/\-A/\-D/') + sudo iptables -t mangle $rule + done + sudo iptables -t mangle -X NETWORK_STATS_$dev 2>/dev/null +} + +action=$1 +dev=$2 +tableNo=${dev:3} +tableName="Table_$dev" + +if [ $action == 'add' ] +then + plug_nic +else + unplug_nic +fi diff --git a/patches/systemvm/debian/config/root/ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh old mode 100644 new mode 100755 similarity index 100% rename from patches/systemvm/debian/config/root/ipassoc.sh rename to patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh diff --git a/patches/systemvm/debian/config/opt/cloud/bin/ipsectunnel.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipsectunnel.sh new file mode 100755 index 00000000000..7426d4b6166 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/ipsectunnel.sh @@ -0,0 +1,221 @@ +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. + +#!/usr/bin/env bash +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +vpnconfdir="/etc/ipsec.d" +vpnoutmark="0x525" + +usage() { + printf "Usage: %s: (-A|-D) -l -n -g -r -N -e -i -t -s \n" $(basename $0) >&2 +} + +#set -x + +start_ipsec() { + service ipsec status > /dev/null + if [ $? -ne 0 ] + then + service ipsec start > /dev/null + fi +} + +enable_iptable() { + sudo iptables -A INPUT -i $outIf -p udp -m udp --dport 500 -j ACCEPT + for net in $rightnets + do + sudo iptables -A PREROUTING -t mangle -s $leftnet -d $net -j MARK --set-mark $vpnoutmark + done +} + +disable_iptable() { + sudo iptables -D INPUT -i $outIf -p udp -m udp --dport 500 -j ACCEPT + for net in $rightnets + do + sudo iptables -D PREROUTING -t mangle -s $leftnet -d $net -j MARK --set-mark $vpnoutmark + done +} + +ipsec_tunnel_del() { + disable_iptable + sudo ipsec auto --down vpn-$rightpeer + sudo ipsec auto --delete vpn-$rightpeer + outIp=$leftpeer + local vpnconffile=$vpnconfdir/ipsec.vpn-$rightpeer.conf + local vpnsecretsfile=$vpnconfdir/ipsec.vpn-$rightpeer.secrets + logger -t cloud "$(basename $0): removing configuration for ipsec tunnel to $rightpeer" + sudo rm -f $vpnconffile + sudo rm -f $vpnsecretsfile + sudo ipsec auto --rereadall +} + +ipsec_tunnel_add() { + #need to unify with remote access VPN + start_ipsec + + outIp=$leftpeer + sudo mkdir -p $vpnconfdir + local vpnconffile=$vpnconfdir/ipsec.vpn-$rightpeer.conf + local vpnsecretsfile=$vpnconfdir/ipsec.vpn-$rightpeer.secrets + + logger -t cloud "$(basename $0): creating configuration for ipsec tunnel: left peer=$leftpeer \ + left net=$leftnet left gateway=$leftgw right peer=$rightpeer right network=$rightnets phase1 policy=$ikepolicy \ + phase2 policy=$esppolicy lifetime=$time secret=$secret" + + [ "$op" == "-A" ] && ipsec_tunnel_del $rightpeer $rightnets "-D" + sudo echo "conn vpn-$rightpeer" > $vpnconffile && + sudo echo " left=$leftpeer" >> $vpnconffile && + sudo echo " leftsubnet=$leftnet" >> $vpnconffile && + sudo echo " leftnexthop=$leftgw" >> $vpnconffile && + sudo echo " right=$rightpeer" >> $vpnconffile && + sudo echo " rightsubnets={$rightnets}" >> $vpnconffile && + sudo echo " type=tunnel" >> $vpnconffile && + sudo echo " authby=secret" >> $vpnconffile && + sudo echo " keyexchange=ike" >> $vpnconffile && + sudo echo " pfs=no" >> $vpnconffile && + sudo echo " esp=$esppolicy" >> $vpnconffile && + sudo echo " salifetime=${time}s" >> $vpnconffile && + sudo echo " ike=$ikepolicy" >> $vpnconffile && + sudo echo " ikelifetime=${time}s" >> $vpnconffile && + sudo echo " keyingtries=3" >> $vpnconffile && + sudo echo " dpddelay=30" >> $vpnconffile && + sudo echo " dpdtimeout=120" >> $vpnconffile && + sudo echo " dpdaction=restart" >> $vpnconffile && + sudo echo " auto=add" >> $vpnconffile && + sudo echo "$leftpeer $rightpeer: PSK \"$secret\"" > $vpnsecretsfile && + + sudo chmod 0400 $vpnsecretsfile + + enable_iptable + + sudo ipsec auto --rereadall + sudo ipsec auto --add vpn-$rightpeer + sudo ipsec auto --up vpn-$rightpeer + # Prevent NAT on "marked" VPN traffic + sudo iptables -D POSTROUTING -t nat -o $outIf -j SNAT --to-source $outIp + sudo iptables -D POSTROUTING -t nat -o $outIf -m mark ! --mark $vpnoutmark -j SNAT --to-source $outIp + sudo iptables -A POSTROUTING -t nat -o $outIf -m mark ! --mark $vpnoutmark -j SNAT --to-source $outIp + + logger -t cloud "$(basename $0): done ipsec tunnel entry for right peer=$rightpeer right networks=$rightnets" + + #20 seconds for checking if it's ready + for i in {1..4} + do + logger -t cloud "$(basename $0): checking connection status..." + ./checks2svpn.sh $rightpeer + result=$? + if [ $result -eq 0 ] + then + break + fi + sleep 5 + done + if [ $result -eq 0 ] + then + logger -t cloud "$(basename $0): connect to remote successful" + else + logger -t cloud "$(basename $0): fail to connect to remote, status code: $result" + logger -t cloud "$(basename $0): would stop site-to-site VPN connection" + ipsec_tunnel_del + fi + return $result +} + +rflag= +pflag= +eflag= +Eflag= +lflag= +iflag= +Iflag= +sflag= +op="" + +while getopts 'ADl:n:g:r:N:e:i:t:s:' OPTION +do + case $OPTION in + A) opflag=1 + op="-A" + ;; + D) opflag=2 + op="-D" + ;; + l) lflag=1 + leftpeer="$OPTARG" + ;; + n) nflag=1 + leftnet="$OPTARG" + ;; + g) gflag=1 + leftgw="$OPTARG" + ;; + r) rflag=1 + rightpeer="$OPTARG" + ;; + N) Nflag=1 + rightnets="$OPTARG" + ;; + e) eflag=1 + esppolicy="$OPTARG" + ;; + i) iflag=1 + ikepolicy="$OPTARG" + ;; + t) tflag=1 + time="$OPTARG" + ;; + s) sflag=1 + secret="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +# get interface for public ip +ip link|grep BROADCAST|grep -v eth0|cut -d ":" -f 2 > /tmp/iflist +while read i +do + ip addr show $i|grep "$leftpeer" + if [ $? -eq 0 ] + then + outIf=$i + break + fi +done < /tmp/iflist + +rightnets=${rightnets//,/ } + +ret=0 +#Firewall ports for one-to-one/static NAT +if [ "$opflag" == "1" ] +then + ipsec_tunnel_add + ret=$? +elif [ "$opflag" == "2" ] +then + ipsec_tunnel_del + ret=$? +else + printf "Invalid action specified, must choose -A or -D to add/del tunnels\n" >&2 + unlock_exit 5 $lock $locked +fi + +unlock_exit $ret $lock $locked diff --git a/tools/testClient/pymysql/times.py b/patches/systemvm/debian/config/opt/cloud/bin/listeth.sh old mode 100644 new mode 100755 similarity index 67% rename from tools/testClient/pymysql/times.py rename to patches/systemvm/debian/config/opt/cloud/bin/listeth.sh index f0aba818b01..79a049b31fd --- a/tools/testClient/pymysql/times.py +++ b/patches/systemvm/debian/config/opt/cloud/bin/listeth.sh @@ -1,3 +1,4 @@ +#!/usr/bin/env bash # Copyright 2012 Citrix Systems, Inc. Licensed under the # Apache License, Version 2.0 (the "License"); you may not use this # file except in compliance with the License. Citrix Systems, Inc. @@ -10,19 +11,27 @@ # limitations under the License. # # Automatically generated by addcopyright.py at 04/03/2012 -from time import localtime -from datetime import date, datetime, time, timedelta -Date = date -Time = time -TimeDelta = timedelta -Timestamp = datetime +# @VERSION@ -def DateFromTicks(ticks): - return date(*localtime(ticks)[:3]) +source /root/func.sh -def TimeFromTicks(ticks): - return time(*localtime(ticks)[3:6]) +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi -def TimestampFromTicks(ticks): - return datetime(*localtime(ticks)[:6]) +usage() { + printf "Usage:\n %s (basename $0), return list of eth device" >&2 +} + +ethlist="" +for i in `ls -1 /sys/class/net/ | grep eth` +do + ethlist=$ethlist","$i +done +echo ${ethlist:1} + +unlock_exit 1 $lock $locked diff --git a/patches/systemvm/debian/config/root/netusage.sh b/patches/systemvm/debian/config/opt/cloud/bin/netusage.sh old mode 100644 new mode 100755 similarity index 100% rename from patches/systemvm/debian/config/root/netusage.sh rename to patches/systemvm/debian/config/opt/cloud/bin/netusage.sh diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh new file mode 100755 index 00000000000..7ef648d5232 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 +# firewall_rule.sh -- allow some ports / protocols to vm instances +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: -a \n" $(basename $0) >&2 + printf "sourcecidrs format: cidr1-cidr2-cidr3-...\n" +} +#set -x +#FIXME: eating up the error code during execution of iptables +acl_remove_backup() { + sudo iptables -F _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -o $dev -d $gcidr -j _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -X _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -F _ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $gcidr -j _ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -X _ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_remove() { + sudo iptables -F ACL_INBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -o $dev -d $gcidr -j ACL_INBOUND_$ip 2>/dev/null + sudo iptables -X ACL_INBOUND_$ip 2>/dev/null + sudo iptables -F ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $gcidr -j ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -X ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_restore() { + acl_remove + sudo iptables -E _ACL_INBOUND_$ip ACL_INBOUND_$ip 2>/dev/null + sudo iptables -E _ACL_OUTBOUND_$ip ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_save() { + acl_remove_backup + sudo iptables -E ACL_INBOUND_$ip _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -E ACL_OUTBOUND_$ip _ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_chain_for_guest_network () { + acl_save + # inbound + sudo iptables -N ACL_INBOUND_$ip 2>/dev/null + # drop if no rules match (this will be the last rule in the chain) + sudo iptables -A ACL_INBOUND_$ip -j DROP 2>/dev/null + sudo iptables -A FORWARD -o $dev -d $gcidr -j ACL_INBOUND_$ip 2>/dev/null + # outbound + sudo iptables -N ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -A ACL_OUTBOUND_$ip -j DROP 2>/dev/null + sudo iptables -A FORWARD -i $dev -s $gcidr -j ACL_OUTBOUND_$ip 2>/dev/null +} + + + +acl_entry_for_guest_network() { + local rule=$1 + + local ttype=$(echo $rule | cut -d: -f1) + local prot=$(echo $rule | cut -d: -f2) + local sport=$(echo $rule | cut -d: -f3) + local eport=$(echo $rule | cut -d: -f4) + local cidrs=$(echo $rule | cut -d: -f5 | sed 's/-/ /g') + if [ "$sport" == "0" -a "$eport" == "0" ] + then + DPORT="" + else + DPORT="--dport $sport:$eport" + fi + logger -t cloud "$(basename $0): enter apply acl rules for guest network: $gcidr, inbound:$inbound:$prot:$sport:$eport:$cidrs" + + # note that rules are inserted after the RELATED,ESTABLISHED rule + # but before the DROP rule + for lcidr in $cidrs + do + [ "$prot" == "reverted" ] && continue; + if [ "$prot" == "icmp" ] + then + typecode="$sport/$eport" + [ "$eport" == "-1" ] && typecode="$sport" + [ "$sport" == "-1" ] && typecode="any" + if [ "$ttype" == "Ingress" ] + then + sudo iptables -I ACL_INBOUND_$ip -p $prot -s $lcidr \ + --icmp-type $typecode -j ACCEPT + else + sudo iptables -I ACL_OUTBOUND_$ip -p $prot -d $lcidr \ + --icmp-type $typecode -j ACCEPT + fi + else + if [ "$ttype" == "Ingress" ] + then + sudo iptables -I ACL_INBOUND_$ip -p $prot -s $lcidr \ + $DPORT -j ACCEPT + else + sudo iptables -I ACL_OUTBOUND_$ip -p $prot -d $lcidr \ + $DPORT -j ACCEPT + fi + fi + result=$? + [ $result -gt 0 ] && + logger -t cloud "Error adding iptables entry for guest network : $gcidr,inbound:$inbound:$prot:$sport:$eport:$cidrs" && + break + done + + logger -t cloud "$(basename $0): exit apply acl rules for guest network : $gcidr" + return $result +} + + +dflag=0 +gflag=0 +aflag=0 +rules="" +rules_list="" +ip="" +dev="" +while getopts 'd:i:m:a:' OPTION +do + case $OPTION in + d) dflag=1 + dev="$OPTARG" + ;; + i) iflag=1 + ip="$OPTARG" + ;; + m) mflag=1 + mask="$OPTARG" + ;; + a) aflag=1 + rules="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +if [ "$dflag$iflag$mflag$aflag" != "1111" ] +then + usage + unlock_exit 2 $lock $locked +fi + +gcidr="$ip/$mask" +if [ -n "$rules" ] +then + rules_list=$(echo $rules | cut -d, -f1- --output-delimiter=" ") +fi + +# rule format +# protocal:sport:eport:cidr +#-a tcp:80:80:0.0.0.0/0::tcp:220:220:0.0.0.0/0:,172.16.92.44:tcp:222:222:192.168.10.0/24-75.57.23.0/22-88.100.33.1/32 +# if any entry is reverted , entry will be in the format :reverted:0:0:0 +# example : 172.16.92.44:tcp:80:80:0.0.0.0/0:,172.16.92.44:tcp:220:220:0.0.0.0/0:,200.1.1.2:reverted:0:0:0 + +success=0 + +acl_chain_for_guest_network + +for r in $rules_list +do + acl_entry_for_guest_network $r + success=$? + if [ $success -gt 0 ] + then + logger -t cloud "$(basename $0): failure to apply fw rules for guest network: $gcidr" + break + else + logger -t cloud "$(basename $0): successful in applying fw rules for guest network: $gcidr" + fi +done + +if [ $success -gt 0 ] +then + logger -t cloud "$(basename $0): restoring from backup for guest network: $gcidr" + acl_restore +else + logger -t cloud "$(basename $0): deleting backup for guest network: $gcidr" + acl_remove_backup +fi +unlock_exit $success $lock $locked + diff --git a/scripts/network/domr/getDomRVersion.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh similarity index 56% rename from scripts/network/domr/getDomRVersion.sh rename to patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh index e11e052f7a1..79bebf7df03 100755 --- a/scripts/network/domr/getDomRVersion.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_func.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright 2012 Citrix Systems, Inc. Licensed under the # Apache License, Version 2.0 (the "License"); you may not use this # file except in compliance with the License. Citrix Systems, Inc. @@ -12,31 +12,34 @@ # # Automatically generated by addcopyright.py at 04/03/2012 -usage() { - printf "Usage:\n %s \n" $(basename $0) >&2 - printf " %s \n" $(basename $0) >&2 +# @VERSION@ + +getEthByIp (){ + local ip=$1 + for dev in `ls -1 /sys/class/net | grep eth` + do + sudo ip addr show dev $dev | grep $ip > /dev/null + if [ $? -eq 0 ] + then + echo $dev + return 0 + fi + done + return 1 +} + +getVPCcidr () { + CMDLINE=$(cat /var/cache/cloud/cmdline) + for i in $CMDLINE + do + # search for foo=bar pattern and cut out foo + KEY=$(echo $i | cut -d= -f1) + VALUE=$(echo $i | cut -d= -f2) + if [ "$KEY" == "vpccidr" ] + then + echo "$VALUE" + return 0 + fi + done + return 1 } - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/opt/cloud/bin/get_template_version.sh" -exit $? diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh new file mode 100755 index 00000000000..56e59813266 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +# guestnw.sh -- create/destroy guest network +# @VERSION@ + +source /root/func.sh +source /opt/cloud/bin/vpc_func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage:\n %s -A -d -i -g -m -s -e < domain> [-f] \n" $(basename $0) >&2 + printf " %s -D -d -i \n" $(basename $0) >&2 +} + + +setup_dnsmasq() { + logger -t cloud "Setting up dnsmasq for network $ip/$mask " + # setup static + sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf + echo "dhcp-range=interface:$dev,set:interface-$dev,$ip,static" >> /etc/dnsmasq.d/cloud.conf + # setup gateway + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$gw" ] + then + echo "dhcp-option=tag:interface-$dev,option:router,$gw" >> /etc/dnsmasq.d/cloud.conf + fi + # setup DNS + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$DNS" ] + then + echo "dhcp-option=tag:interface-$dev,6,$DNS" >> /etc/dnsmasq.d/cloud.conf + fi + # setup DOMAIN + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,15.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$DOMAIN" ] + then + echo "dhcp-option=tag:interface-$dev,15,$DOMAIN" >> /etc/dnsmasq.d/cloud.conf + fi + service dnsmasq restart + sleep 1 +} + +desetup_dnsmasq() { + logger -t cloud "Setting up dnsmasq for network $ip/$mask " + + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf + sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf + service dnsmasq restart + sleep 1 +} + +setup_usage() { + sudo iptables -t mangle -N NETWORK_STATS_$dev + sudo iptables -t mangle -A NETWORK_STATS_$dev -s $subnet/$mask ! -d $vpccidr + sudo iptables -t mangle -A NETWORK_STATS_$dev -o $dev ! -s $vpccidr + sudo iptables -t mangle -A POSTROUTING -s $subnet/$mask -j NETWORK_STATS_$dev + sudo iptables -t mangle -A POSTROUTING -o $dev -j NETWORK_STATS_$dev +} + +create_guest_network() { + logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " + # setup ip configuration + sudo ip addr add dev $dev $ip/$mask + sudo ip link set $dev up + sudo arping -c 3 -I $dev -A -U -s $ip $ip + # setup rules to allow dhcp/dns request + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -A INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + local tableName="Table_$dev" + sudo ip route add $subnet/$mask dev $dev table $tableName proto static + sudo iptables -t mangle -A PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark + setup_usage + setup_dnsmasq +} + +destroy_guest_network() { + logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " + + sudo ip addr del dev $dev $ip/$mask + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark + desetup_dnsmasq +} + +#set -x +iflag=0 +mflag=0 +nflag=0 +dflag= +gflag= +Cflag= +Dflag= + +op="" + + +while getopts 'CDn:m:d:i:g:s:e:' OPTION +do + case $OPTION in + C) Cflag=1 + op="-C" + ;; + D) Dflag=1 + op="-D" + ;; + n) nflag=1 + subnet="$OPTARG" + ;; + m) mflag=1 + mask="$OPTARG" + ;; + d) dflag=1 + dev="$OPTARG" + ;; + i) iflag=1 + ip="$OPTARG" + ;; + g) gflag=1 + gw="$OPTARG" + ;; + s) sflag=1 + DNS="$OPTARG" + ;; + e) eflag=1 + DOMAIN="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +vpccidr=$(getVPCcidr) + +if [ "$Cflag$Dflag$dflag" != "11" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$Cflag" == "1" ] && [ "$iflag$gflag$mflag" != "111" ] +then + usage + unlock_exit 2 $lock $locked +fi + + +if [ "$Cflag" == "1" ] +then + create_guest_network +fi + + +if [ "$Dflag" == "1" ] +then + destroy_guest_network +fi + +unlock_exit 0 $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh new file mode 100755 index 00000000000..40c1e4d996a --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + +# ipassoc.sh -- associate/disassociate a public ip with an instance +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage:\n %s -A -l -c [-f] \n" $(basename $0) >&2 + printf " %s -D -l -c [-f] \n" $(basename $0) >&2 +} + +add_routing() { + logger -t cloud "$(basename $0):Add routing $pubIp on interface $ethDev" + + local tableName="Table_$ethDev" + sudo ip route add $subnet/$mask dev $ethDev table $tableName proto static + sudo ip route add default via $defaultGwIP table $tableName proto static + sudo ip route flush cache + sudo ip route | grep default + if [ $? -gt 0 ] + then + sudo ip route add default via $defaultGwIP + fi + return 0 +} + + +remove_routing() { + return 0 +} + +add_an_ip () { + logger -t cloud "$(basename $0):Adding ip $pubIp on interface $ethDev" + sudo ip link show $ethDev | grep "state DOWN" > /dev/null + local old_state=$? + + sudo ip addr add dev $ethDev $pubIp/$mask + if [ $old_state -eq 0 ] + then + sudo ip link set $ethDev up + sudo arping -c 3 -I $ethDev -A -U -s $pubIp $pubIp + fi + local tableNo=${ethDev:3} + sudo iptables-save -t mangle | grep "PREROUTING -i $ethDev -m state --state NEW -j CONNMARK --set-xmark" 2>/dev/null + if [ $? -gt 0 ] + then + sudo iptables -t mangle -A PREROUTING -i $ethDev -m state --state NEW -j CONNMARK --set-mark $tableNo 2>/dev/null + fi + add_routing + return $? +} + +remove_an_ip () { + logger -t cloud "$(basename $0):Removing ip $pubIp on interface $ethDev" + local existingIpMask=$(sudo ip addr show dev $ethDev | grep "inet " | awk '{print $2}') + + sudo ip addr del dev $ethDev $pubIp/$mask + # reapply IPs in this interface + for ipMask in $existingIpMask + do + if [ "$ipMask" == "$pubIp/$mask" ] + then + continue + fi + sudo ip addr add dev $ethDev $ipMask + done + + remove_routing + return 0 +} + +#set -x +lflag=0 +cflag=0 +gflag=0 +mflag=0 +nflag=0 +op="" + + +while getopts 'ADl:c:g:m:n:' OPTION +do + case $OPTION in + A) Aflag=1 + op="-A" + ;; + D) Dflag=1 + op="-D" + ;; + l) lflag=1 + pubIp="$OPTARG" + ;; + c) cflag=1 + ethDev="$OPTARG" + ;; + g) gflag=1 + defaultGwIP="$OPTARG" + ;; + m) mflag=1 + mask="$OPTARG" + ;; + n) nflag=1 + subnet="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + + +if [ "$Aflag$Dflag" != "1" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$lflag$cflag$gflag$mflag$nflag" != "11111" ] +then + usage + unlock_exit 2 $lock $locked +fi + + +if [ "$Aflag" == "1" ] +then + add_an_ip $publicIp && + unlock_exit $? $lock $locked +fi + + +if [ "$Dflag" == "1" ] +then + remove_an_ip $publicIp && + unlock_exit $? $lock $locked +fi + + +unlock_exit 1 $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh new file mode 100755 index 00000000000..18de1065992 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_loadbalancer.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: -i -a -d -f -s \n" $(basename $0) >&2 +} + +# set -x + +fw_remove_backup() { + sudo iptables -F back_load_balancer 2> /dev/null + sudo iptables -D INPUT -p tcp -j back_load_balancer 2> /dev/null + sudo iptables -X back_load_balancer 2> /dev/null + sudo iptables -F back_lb_stats 2> /dev/null + sudo iptables -D INPUT -p tcp -j back_lb_stats 2> /dev/null + sudo iptables -X back_lb_stats 2> /dev/null +} + +fw_remove() { + sudo iptables -F load_balancer 2> /dev/null + sudo iptables -D INPUT -p tcp -j load_balancer 2> /dev/null + sudo iptables -X load_balancer 2> /dev/null + sudo iptables -F lb_stats 2> /dev/null + sudo iptables -D INPUT -p tcp -j lb_stats 2> /dev/null + sudo iptables -X lb_stats 2> /dev/null +} + +fw_backup() { + fw_remove_backup + sudo iptables -E load_balancer back_load_balancer 2> /dev/null + sudo iptables -E lb_stats back_lb_stats 2> /dev/null +} + +fw_restore() { + fw_remove + sudo iptables -E back_load_balancer load_balancer 2> /dev/null + sudo iptables -E back_lb_stats lb_stats 2> /dev/null +} + +fw_chain_create () { + fw_backup + sudo iptables -N load_balancer 2> /dev/null + sudo iptables -A INPUT -p tcp -j load_balancer 2> /dev/null + sudo iptables -N lb_stats 2> /dev/null + sudo iptables -A INPUT -p tcp -j lb_stats 2> /dev/null +} + +# firewall entry to ensure that haproxy can receive on specified port +fw_entry() { + local added=$1 + local removed=$2 + local stats=$3 + if [ "$added" == "none" ] + then + added="" + fi + if [ "$removed" == "none" ] + then + removed="" + fi + local a=$(echo $added | cut -d, -f1- --output-delimiter=" ") + local r=$(echo $removed | cut -d, -f1- --output-delimiter=" ") + fw_chain_create + success=0 + while [ 1 ] + do + for i in $a + do + local pubIp=$(echo $i | cut -d: -f1) + local dport=$(echo $i | cut -d: -f2) + sudo iptables -A load_balancer -p tcp -d $pubIp --dport $dport -j ACCEPT 2>/dev/null + success=$? + if [ $success -gt 0 ] + then + break + fi + done + if [ "$stats" != "none" ] + then + local pubIp=$(echo $stats | cut -d: -f1) + local dport=$(echo $stats | cut -d: -f2) + local cidrs=$(echo $stats | cut -d: -f3 | sed 's/-/,/') + sudo iptables -A lb_stats -s $cidrs -p tcp -d $pubIp --dport $dport -j ACCEPT 2>/dev/null + success=$? + fi + break + done + if [ $success -gt 0 ] + then + fw_restore + else + fw_remove_backup + fi + return $success +} + +#Hot reconfigure HA Proxy in the routing domain +reconfig_lb() { + /root/reconfigLB.sh + return $? +} + +# Restore the HA Proxy to its previous state, and revert iptables rules on DomR +restore_lb() { + logger -t cloud "Restoring HA Proxy to previous state" + # Copy the old version of haproxy.cfg into the file that reconfigLB.sh uses + cp /etc/haproxy/haproxy.cfg.old /etc/haproxy/haproxy.cfg.new + + if [ $? -eq 0 ] + then + # Run reconfigLB.sh again + /root/reconfigLB.sh + fi +} + +mflag= +iflag= +aflag= +dflag= +fflag= +sflag= + +while getopts 'i:a:d:s:' OPTION +do + case $OPTION in + i) iflag=1 + domRIp="$OPTARG" + ;; + a) aflag=1 + addedIps="$OPTARG" + ;; + d) dflag=1 + removedIps="$OPTARG" + ;; + s) sflag=1 + statsIp="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +if [ "$addedIps" == "" ] +then + addedIps="none" +fi + +if [ "$removedIps" == "" ] +then + removedIps="none" +fi + +# hot reconfigure haproxy +reconfig_lb + +if [ $? -gt 0 ] +then + logger -t cloud "Reconfiguring loadbalancer failed" + unlock_exit 1 $lock $locked +fi + +# iptables entry to ensure that haproxy receives traffic +fw_entry $addedIps $removedIps $statsIp + +if [ $? -gt 0 ] +then + logger -t cloud "Failed to apply firewall rules for load balancing, reverting HA Proxy config" + # Restore the LB + restore_lb +fi + +unlock_exit 0 $lock $locked + + diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_netusage.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_netusage.sh new file mode 100755 index 00000000000..54c6b55f5dc --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_netusage.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +source /root/func.sh +source /opt/cloud/bin/vpc_func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s -[c|g|r] [-[a|d] ]\n" $(basename $0) >&2 +} + +create_usage_rules () { + iptables-save|grep "NETWORK_STATS_$guestIp -i $ethDev" > /dev/null + if [ $? -gt 0 ] + then + iptables -A NETWORK_STATS_$guestIp -i $ethDev -s ! zcidr > /dev/null + fi + iptables-save|grep "NETWORK_STATS_$guestIp -o $ethDev" > /dev/null + if [ $? -gt 0 ] + then + iptables -A NETWORK_STATS_$guestIp -o $ethDev -d ! zcidr > /dev/null + fi + return $? +} + +get_usage () { + iptables -t mangle -L NETWORK_STATS_$ethDev -n -v -x | awk '$1 ~ /^[0-9]+$/ { printf "%s:", $2}'; > /dev/null + if [ $? -gt 0 ] + then + printf $? + return 1 + fi +} + +reset_usage () { + iptables -t mangle -Z NETWORK_STATS_$ethDev > /dev/null + if [ $? -gt 0 -a $? -ne 2 ] + then + return 1 + fi +} + +#set -x + +cflag= +gflag= +rflag= +lflag= + + +while getopts 'cgrl:' OPTION +do + case $OPTION in + c) cflag=1 + ;; + g) gflag=1 + ;; + r) rflag=1 + ;; + l) lflag=1 + guestIp="$OPTARG" + ;; + i) #Do nothing, since it's parameter for host script + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +if [ "$cflag" == "1" ] +then + unlock_exit 0 $lock $locked +fi + +ethDev=$(getEthByIp $guestIp) +if [ "$gflag" == "1" ] +then + get_usage + unlock_exit $? $lock $locked +fi + +if [ "$rflag" == "1" ] +then + reset_usage + unlock_exit $? $lock $locked +fi + + +unlock_exit 0 $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_portforwarding.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_portforwarding.sh new file mode 100755 index 00000000000..f8bee33442a --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_portforwarding.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: (-A|-D) -r -P protocol (-p port_range | -t icmp_type_code) -l -d -s [-G] \n" $(basename $0) >&2 +} + +#set -x + +#Port (address translation) forwarding for tcp or udp +tcp_or_udp_nat() { + local op=$1 + local proto=$2 + local publicIp=$3 + local ports=$4 + local instIp=$5 + local dports=$6 + + logger -t cloud "$(basename $0): creating port fwd entry for PAT: public ip=$publicIp \ + instance ip=$instIp proto=$proto port=$port dport=$dport op=$op" + + #if adding, this might be a duplicate, so delete the old one first + [ "$op" == "-A" ] && tcp_or_udp_nat "-D" $proto $publicIp $ports $instIp $dports + # the delete operation may have errored out but the only possible reason is + # that the rules didn't exist in the first place + # shortcircuit the process if error and it is an append operation + # continue if it is delete + local PROTO="" + if [ "$proto" != "any" ] + then + PROTO="--proto $proto" + fi + + local DEST_PORT="" + if [ "$ports" != "any" ] + then + DEST_PORT="--destination-port $ports" + fi + + local TO_DEST="--to-destination $instIp" + if [ "$dports" != "any" ] + then + TO_DEST="--to-destination $instIp:$dports" + fi + + sudo iptables -t nat $op PREROUTING $PROTO -d $publicIp $DEST_PORT -j DNAT \ + $TO_DEST &>> $OUTFILE + + local result=$? + logger -t cloud "$(basename $0): done port fwd entry for PAT: public ip=$publicIp op=$op result=$result" + # the rule may not exist + if [ "$op" == "-D" ] + then + return 0 + fi + return $result +} + + +rflag= +Pflag= +pflag= +lflag= +dflag= +op="" +protocal="any" +ports="any" +dports="any" +while getopts 'ADr:P:p:l:d:' OPTION +do + case $OPTION in + A) op="-A" + ;; + D) op="-D" + ;; + r) rflag=1 + instanceIp="$OPTARG" + ;; + P) Pflag=1 + protocol="$OPTARG" + ;; + p) pflag=1 + ports="$OPTARG" + ;; + l) lflag=1 + publicIp="$OPTARG" + ;; + d) dflag=1 + dports="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +OUTFILE=$(mktemp) + +tcp_or_udp_nat $op $protocol $publicIp $ports $instanceIp $dports +result=$? +unlock_exit $result $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_snat.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_snat.sh new file mode 100755 index 00000000000..0fe803ed8ab --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_snat.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage:\n %s -A -l \n" $(basename $0) >&2 + printf " %s -D -l \n" $(basename $0) >&2 +} + + +add_snat() { + logger -t cloud "$(basename $0):Added SourceNAT $pubIp on interface $ethDev" + sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $pubIp + sudo iptables -t nat -A POSTROUTING -j SNAT -o $ethDev --to-source $pubIp + return $? +} +remove_snat() { + logger -t cloud "$(basename $0):Removing SourceNAT $pubIp on interface $ethDev" + sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $pubIp + return $? +} + +#set -x +lflag=0 +cflag=0 +op="" + +while getopts 'ADl:c:' OPTION +do + case $OPTION in + A) Aflag=1 + op="-A" + ;; + D) Dflag=1 + op="-D" + ;; + l) lflag=1 + pubIp="$OPTARG" + ;; + c) cflag=1 + ethDev="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +if [ "$Aflag$Dflag" != "1" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$lflag$cflag" != "11" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$Aflag" == "1" ] +then + add_snat $publicIp + unlock_exit $? $lock $locked +fi + +if [ "$Dflag" == "1" ] +then + remove_sat $publicIp + unlock_exit $? $lock $locked +fi + +unlock_exit 1 $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticnat.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticnat.sh new file mode 100755 index 00000000000..f25dfd8b477 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticnat.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 +# @VERSION@ + +source /root/func.sh +source /opt/cloud/bin/vpc_func.sh +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: (-A|-D) -r -l -d < eth device> \n" $(basename $0) >&2 +} + +#set -x + +static_nat() { + local op=$1 + local publicIp=$2 + local instIp=$3 + local op2="-D" + local tableNo=${ethDev:3} + + logger -t cloud "$(basename $0): static nat: public ip=$publicIp \ + instance ip=$instIp op=$op" + #if adding, this might be a duplicate, so delete the old one first + [ "$op" == "-A" ] && static_nat "-D" $publicIp $instIp + # the delete operation may have errored out but the only possible reason is + # that the rules didn't exist in the first place + [ "$op" == "-A" ] && rulenum=1 + [ "$op" == "-A" ] && op2="-I" + + # shortcircuit the process if error and it is an append operation + # continue if it is delete + (sudo iptables -t nat $op PREROUTING -i $ethDev -d $publicIp -j DNAT \ + --to-destination $instIp &>> $OUTFILE || [ "$op" == "-D" ]) && + # add mark to force the package go out through the eth the public IP is on + (sudo iptables -t mangle $op PREROUTING -s $instIp -j MARK \ + --set-mark $tableNo &> $OUTFILE || [ "$op" == "-D" ]) && + (sudo iptables -t nat $op2 POSTROUTING -o $ethDev -s $instIp -j SNAT \ + --to-source $publicIp &>> $OUTFILE ) + result=$? + logger -t cloud "$(basename $0): done static nat entry public ip=$publicIp op=$op result=$result" + if [ "$op" == "-D" ] + then + return 0 + fi + return $result +} + + + +rflag= +lflag= +dflag= +op="" +while getopts 'ADr:l:' OPTION + +do + case $OPTION in + A) op="-A" + ;; + D) op="-D" + ;; + r) rflag=1 + instanceIp="$OPTARG" + ;; + l) lflag=1 + publicIp="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +ethDev=$(getEthByIp $publicIp) +result=$? +if [ $result -gt 0 ] +then + unlock_exit $result $lock $locked +fi +OUTFILE=$(mktemp) + +static_nat $op $publicIp $instanceIp +result=$? +unlock_exit $result $lock $locked diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh new file mode 100755 index 00000000000..2a4593c7603 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_staticroute.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 +# @VERSION@ + +source /root/func.sh +source /opt/cloud/bin/vpc_func.sh +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: (-A|-D) -c < cidr > -l -g < gateway> \n" $(basename $0) >&2 +} + +#set -x + +static_route() { + local op=$1 + local publicIp=$2 + local gateway=$3 + local cidr=$4 + + logger -t cloud "$(basename $0): static route: public ip=$publicIp \ + gateway=$gateway cidr=$cidr op=$op" + #if adding, this might be a duplicate, so delete the old one first + [ "$op" == "add" ] && static_routet "del" $publicIp $gateway $cidr + + sudo ip route $op $cidr dev $ethDev via $gateway &>> $OUTFILE + result=$? + logger -t cloud "$(basename $0): done static route: public ip=$publicIp \ + gateway=$gateway cidr=$cidr op=$op" + + if [ "$op" == "del" ] + then + return 0 + fi + return $result +} + + + +gflag= +lflag= +cflag= +op="" +while getopts 'ADg:l:c:' OPTION + +do + case $OPTION in + A) op="add" + ;; + D) op="del" + ;; + g) gflag=1 + gateway="$OPTARG" + ;; + l) lflag=1 + publicIp="$OPTARG" + ;; + c) cflag=1 + cidr="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +ethDev=$(getEthByIp $publicIp) +result=$? +if [ $result -gt 0 ] +then + unlock_exit $result $lock $locked +fi +OUTFILE=$(mktemp) + +static_route $op $publicIp $gateway $cidr +result=$? +unlock_exit $result $lock $locked diff --git a/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh b/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh new file mode 100755 index 00000000000..574fd69e794 --- /dev/null +++ b/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh @@ -0,0 +1,174 @@ +#!/bin/bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + + +#set -x +usage() { + printf "Usage:\n" + printf "Create VPN : %s -c -r -l -p -s -D -z < zone cidr> \n" $(basename $0) + printf "Delete VPN : %s -d -l -s -D -z < zone cidr> \n" $(basename $0) + printf "Add VPN User : %s -u \n" $(basename $0) + printf "Remote VPN User: %s -U /etc/ipsec.d/ipsec.any.secrets + sed -i -e "s/^ip range = .*$/ip range = $client_range/" /etc/xl2tpd/xl2tpd.conf + sed -i -e "s/^local ip = .*$/local ip = $local_ip/" /etc/xl2tpd/xl2tpd.conf + + sed -i -e "s/^ms-dns.*$/ms-dns $local_ip/" /etc/ppp/options.xl2tpd + + iptables_ "-D" $public_ip + iptables_ "-I" $public_ip + + ipsec_server "restart" + + ipsec auto --rereadsecrets + ipsec auto --replace L2TP-PSK +} + +destroy_l2tp_ipsec_vpn_server() { + local public_ip=$1 + + ipsec auto --down L2TP-PSK + + iptables_ "-D" $public_ip + + ipsec_server "stop" +} + +remove_l2tp_ipsec_user() { + local u=$1 + sed -i -e "/^$u .*$/d" /etc/ppp/chap-secrets + if [ -x /usr/bin/tdbdump ]; then + pid=$(tdbdump /var/run/pppd2.tdb | grep -w $u | awk -F';' '{print $4}' | awk -F= '{print $2}') + [ "$pid" != "" ] && kill -9 $pid + fi + return 0 +} + +add_l2tp_ipsec_user() { + local u=$1 + local passwd=$2 + + remove_l2tp_ipsec_user $u + echo "$u * $passwd *" >> /etc/ppp/chap-secrets +} + +rflag= +pflag= +lflag= +sflag= +create= +destroy= +useradd= +userdel= + +while getopts 'cdl:p:r:s:u:U:D:z' OPTION +do + case $OPTION in + c) create=1 + ;; + d) destroy=1 + ;; + u) useradd=1 + user_pwd="$OPTARG" + ;; + U) userdel=1 + user="$OPTARG" + ;; + r) rflag=1 + client_range="$OPTARG" + ;; + p) pflag=1 + ipsec_psk="$OPTARG" + ;; + l) lflag=1 + local_ip="$OPTARG" + ;; + s) sflag=1 + server_ip="$OPTARG" + ;; + D) dev="$OPTARG" + ;; + z) zcidr="$OPTARG" + ;; + ?) usage + exit 2 + ;; + esac +done + +[ "$create$destroy" == "11" ] || [ "$create$destroy$useradd$userdel" == "" ] && usage && exit 2 +[ "$create" == "1" ] && [ "$lflag$pflag$rflag$sflag" != "1111" ] && usage && exit 2 + +if [ "$create" == "1" ]; then + create_l2tp_ipsec_vpn_server $ipsec_psk $server_ip $client_range $local_ip + exit $? +fi + +if [ "$destroy" == "1" ]; then + destroy_l2tp_ipsec_vpn_server $server_ip + exit $? +fi + +if [ "$useradd" == "1" ]; then + u=$(echo $user_pwd | awk -F',' '{print $1}') + pwd=$(echo $user_pwd | awk -F',' '{print $2}') + add_l2tp_ipsec_user $u $pwd + exit $? +fi +if [ "$userdel" == "1" ]; then + remove_l2tp_ipsec_user $user + exit $? +fi diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh deleted file mode 100755 index 592b56c97f7..00000000000 --- a/scripts/network/domr/ipassoc.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - - - - - -# $Id: ipassoc.sh 9804 2010-06-22 18:36:49Z alex $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/network/domr/ipassoc.sh $ -# ipassoc.sh -- associate/disassociate a public ip with an instance -# 2.1.4 -usage() { - printf "Usage:\n %s -A -i -l -r [-f] \n" $(basename $0) >&2 - printf " %s -D -i -l -r [-f] \n" $(basename $0) >&2 -} - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/ipassoc.sh $*" -exit $? - diff --git a/scripts/network/domr/networkUsage.sh b/scripts/network/domr/networkUsage.sh deleted file mode 100755 index 3b1450ad902..00000000000 --- a/scripts/network/domr/networkUsage.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - - - - - -# $Id: networkUsage.sh 9879 2010-06-24 02:41:46Z anthony $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/vm/hypervisor/xenserver/networkUsage.sh $ -# networkUsage.sh -- create iptable rules to gather network stats -usage() { - printf "Usage: %s -[c|g|r] -i [-[a|d] ]\n" $(basename $0) >&2 -} - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - -cert="/root/.ssh/id_rsa.cloud" - -while getopts 'cgri:a:d:' OPTION -do - case $OPTION in - i) iflag=1 - domRIp="$OPTARG" - ;; - esac -done - -if ! check_gw "$domRIp" -then - printf "Unable to ping the routing domain, exiting\n" >&2 - exit 3 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/netusage.sh $*" -exit $? diff --git a/scripts/network/domr/getRouterStatus.sh b/scripts/network/domr/router_proxy.sh similarity index 82% rename from scripts/network/domr/getRouterStatus.sh rename to scripts/network/domr/router_proxy.sh index 04511b6a6f3..ac0c9cb8df3 100755 --- a/scripts/network/domr/getRouterStatus.sh +++ b/scripts/network/domr/router_proxy.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright 2012 Citrix Systems, Inc. Licensed under the # Apache License, Version 2.0 (the "License"); you may not use this # file except in compliance with the License. Citrix Systems, Inc. @@ -12,14 +12,11 @@ # # Automatically generated by addcopyright.py at 04/03/2012 -usage() { - printf "Usage:\n %s \n" $(basename $0) >&2 - printf " %s \n" $(basename $0) >&2 -} -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift + +# used as a proxy to call script inside virtual router + +#set -x check_gw() { ping -c 1 -n -q $1 > /dev/null @@ -28,15 +25,30 @@ check_gw() { sleep 1 ping -c 1 -n -q $1 > /dev/null fi - return $?; + if [ $? -gt 0 ] + then + exit 1 + fi } +cert="/root/.ssh/id_rsa.cloud" + +script=$1 +shift + +domRIp=$1 +shift check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/checkrouter.sh" +ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/opt/cloud/bin/$script $*" exit $? + + + + + + + + + diff --git a/scripts/network/domr/l2tp_vpn.sh b/scripts/network/domr/s2s_vpn.sh similarity index 95% rename from scripts/network/domr/l2tp_vpn.sh rename to scripts/network/domr/s2s_vpn.sh index 87d9a033c0e..0bdccc4f7b7 100755 --- a/scripts/network/domr/l2tp_vpn.sh +++ b/scripts/network/domr/s2s_vpn.sh @@ -21,6 +21,6 @@ cert="/root/.ssh/id_rsa.cloud" domr=$1 shift -ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/vpn_l2tp.sh $*" >/dev/null +ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/ipsectunnel.sh $*" >/dev/null exit $? diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index edef61906b5..7025622dc99 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -139,21 +139,6 @@ def pingxenserver(session, args): txt = 'success' return txt -@echo -def ipassoc(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/ipassoc.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" ip associate failed " ) - txt = '' - - return txt - @echo def vm_data(session, args): router_ip = args.pop('routerIP') @@ -247,21 +232,6 @@ def saveDhcpEntry(session, args): return txt -@echo -def lt2p_vpn(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/l2tp_vpn.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog("l2tp vpn failed " ) - txt = '' - - return txt - @echo def setLinkLocalIP(session, args): brName = args['brName'] @@ -307,6 +277,8 @@ def setLinkLocalIP(session, args): txt = 'success' return txt + + @echo def setFirewallRule(session, args): sargs = args['args'] @@ -322,6 +294,24 @@ def setFirewallRule(session, args): return txt +@echo +def routerProxy(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/xensource/bin/router_proxy.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + if txt is None or len(txt) == 0 : + txt = 'success' + except: + util.SMlog("routerProxy command " + sargs + " failed " ) + txt = '' + + return txt + + + @echo def setLoadBalancerRule(session, args): sargs = args['args'] @@ -353,6 +343,28 @@ def createFile(session, args): return txt + +@echo +def createFileInDomr(session, args): + file_path = args['filepath'] + file_contents = args['filecontents'] + domrip = args['domrip'] + try: + tmpfile = util.pread2(['mktemp']).strip() + f = open(tmpfile, "w") + f.write(file_contents) + f.close() + target = "root@" + domrip + ":" + file_path + util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + util.pread2(['rm',tmpfile]) + txt = 'success' + except: + util.SMlog(" failed to create HA proxy cfg file ") + txt = '' + + return txt + + @echo def deleteFile(session, args): file_path = args["filepath"] @@ -368,19 +380,6 @@ def deleteFile(session, args): return txt -@echo -def networkUsage(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/networkUsage.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" network usage error " ) - txt = '' - - return txt def get_private_nic(session, args): vms = session.xenapi.VM.get_all() @@ -1418,20 +1417,6 @@ def network_rules(session, args): except: util.SMlog("Failed to network rule !") -@echo -def checkRouter(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/getRouterStatus.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" check router status fail! ") - txt = '' - - return txt - @echo def bumpUpPriority(session, args): sargs = args['args'] @@ -1447,33 +1432,21 @@ def bumpUpPriority(session, args): return txt -@echo -def getDomRVersion(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/getDomRVersion.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" get domR version fail! ") - txt = '' - - return txt if __name__ == "__main__": XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, "getvncport": getvncport, "getgateway": getgateway, "preparemigration": preparemigration, "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, - "ipassoc": ipassoc, "vm_data": vm_data, "savePassword": savePassword, - "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, + "vm_data": vm_data, "savePassword": savePassword, + "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, "routerProxy": routerProxy, "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, - "networkUsage": networkUsage, "network_rules":network_rules, + "network_rules":network_rules, "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, "destroy_network_rules_for_vm":destroy_network_rules_for_vm, "default_network_rules_systemvm":default_network_rules_systemvm, "get_rule_logs_for_vms":get_rule_logs_for_vms, - "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn, - "cleanup_rules":cleanup_rules, "checkRouter":checkRouter, - "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion, + "setLinkLocalIP":setLinkLocalIP, + "cleanup_rules":cleanup_rules, + "createFileInDomr":createFileInDomr, + "bumpUpPriority":bumpUpPriority, "kill_copy_process":kill_copy_process}) diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index 74338f76835..7171635be16 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -1,4 +1,5 @@ # This file specifies the files that need +# # to be transferred over to the XenServer. # The format of this file is as follows: # [Name of file]=[source path],[file permission],[destination path] @@ -11,7 +12,6 @@ # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. NFSSR.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins -ovsgre=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm @@ -23,13 +23,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index b06f0ea3d3b..37d4290f1c3 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -22,13 +22,11 @@ setup_iscsi.sh=..,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin kill_copy_process.sh=..,0755,/opt/xensource/bin @@ -44,8 +42,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch index dbc65817e65..5e6aac1f697 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch @@ -21,13 +21,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin @@ -43,8 +41,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch index 88d33c8b2df..fdbfbbef050 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver60/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch @@ -15,7 +15,6 @@ xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins cloudstack_plugins.conf=..,0644,/etc/xensource cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins -ovsgre=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm @@ -27,13 +26,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin @@ -49,8 +46,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 9074bfba10e..a274803872b 100755 --- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -491,7 +491,9 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust } } if (agent == null) { - throw new AgentUnavailableException("Host is not in the right state: " + host.getStatus() , hostId); + AgentUnavailableException ex = new AgentUnavailableException("Host with specified id is not in the right state: " + host.getStatus(), hostId); + ex.addProxyObject(host, hostId, "hostId"); + throw ex; } return agent; diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index f4948860183..64c7fef6792 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -49,6 +49,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -68,6 +69,7 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.VpcManager; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -76,7 +78,9 @@ import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; import com.cloud.server.ManagementServer; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.StatsCollector; +import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -84,6 +88,7 @@ import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.StorageStats; @@ -91,9 +96,8 @@ import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSCategoryDao; @@ -188,6 +192,8 @@ public class ApiDBUtils { private static AccountDetailsDao _accountDetailsDao; private static NetworkDomainDao _networkDomainDao; private static HighAvailabilityManager _haMgr; + private static TaggedResourceService _taggedResourceService; + private static VpcManager _vpcMgr; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); @@ -241,6 +247,8 @@ public class ApiDBUtils { _accountDetailsDao = locator.getDao(AccountDetailsDao.class); _networkDomainDao = locator.getDao(NetworkDomainDao.class); _haMgr = locator.getManager(HighAvailabilityManager.class); + _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcMgr = locator.getManager(VpcManager.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -733,7 +741,7 @@ public class ApiDBUtils { } public static long countFreePublicIps() { - return _ipAddressDao.countFreeIPs(); + return _ipAddressDao.countFreePublicIPs(); } public static long findDefaultRouterServiceOffering() { @@ -748,4 +756,20 @@ public class ApiDBUtils { public static String getHaTag() { return _haMgr.getHaTag(); } + + public static String getUuid(String resourceId, TaggedResourceType resourceType) { + return _taggedResourceService.getUuid(resourceId, resourceType); + } + + public static Map> listVpcOffServices(long vpcOffId) { + return _vpcMgr.getVpcOffSvcProvidersMap(vpcOffId); + } + + public static List listVpcNetworks(long vpcId) { + return _networkMgr.listNetworksByVpc(vpcId); + } + + public static boolean canUseForDeploy(Network network) { + return _networkMgr.canUseForDeploy(network); + } } diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 0079830e53b..901a5dca539 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -35,11 +35,11 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.utils.IdentityProxy; import com.cloud.server.ManagementServer; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.DateUtil; +import com.cloud.utils.IdentityProxy; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.PluggableService; import com.cloud.utils.exception.CSExceptionErrorCode; @@ -79,24 +79,122 @@ public class ApiDispatcher { ctx.setAccountId(cmd.getEntityOwnerId()); cmd.create(); } catch (Throwable t) { - if (t instanceof InvalidParameterValueException || t instanceof IllegalArgumentException) { + if (t instanceof InvalidParameterValueException) { + InvalidParameterValueException ref = (InvalidParameterValueException) t; + ServerApiException ex = new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + " db_id: " + id.getValue()); + } + } else { + s_logger.info(t.getMessage()); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; + } else if(t instanceof IllegalArgumentException) { s_logger.info(t.getMessage()); throw new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); } else if (t instanceof PermissionDeniedException) { s_logger.info("PermissionDenied: " + t.getMessage()); - throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); + PermissionDeniedException ref = (PermissionDeniedException)t; + ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info("PermissionDenied: " + t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.info("PermissionDenied: " + t.getMessage()); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; } else if (t instanceof AccountLimitException) { s_logger.info(t.getMessage()); - throw new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); + AccountLimitException ref = (AccountLimitException)t; + ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.info(t.getMessage()); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; } else if (t instanceof InsufficientCapacityException) { s_logger.info(t.getMessage()); - throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); + InsufficientCapacityException ref = (InsufficientCapacityException)t; + ServerApiException ex = new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.info(t.getMessage()); + } + // Also copy over the cserror code + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; } else if (t instanceof ResourceAllocationException) { s_logger.info(t.getMessage()); - throw new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, t.getMessage()); + ResourceAllocationException ref = (ResourceAllocationException)t; + ServerApiException ex = new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.warn("Exception: ", t); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; } else if (t instanceof ResourceUnavailableException) { s_logger.warn("Exception: ", t); - throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, t.getMessage()); + ResourceUnavailableException ref = (ResourceUnavailableException)t; + ServerApiException ex = new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.warn("Exception: ", t); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; } else if (t instanceof AsyncCommandQueued) { throw (AsyncCommandQueued) t; } else if (t instanceof ServerApiException) { @@ -104,11 +202,14 @@ public class ApiDispatcher { throw (ServerApiException) t; } else { s_logger.error("Exception while executing " + cmd.getClass().getSimpleName() + ":", t); + ServerApiException ex; if (UserContext.current().getCaller().getType() == Account.ACCOUNT_TYPE_ADMIN) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); + ex = new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); } else { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, BaseCmd.USER_ERROR_MESSAGE); + ex = new ServerApiException(BaseCmd.INTERNAL_ERROR, BaseCmd.USER_ERROR_MESSAGE); } + ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName())); + throw ex; } } } @@ -135,117 +236,117 @@ public class ApiDispatcher { } catch (Throwable t) { if (t instanceof InvalidParameterValueException) { - // earlier, we'd log the db id as part of the log message, but now since we've pushed - // the id into a IdentityProxy object, we would need to dump that object alongwith the - // message. - InvalidParameterValueException ref = (InvalidParameterValueException) t; - ServerApiException ex = new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); + // earlier, we'd log the db id as part of the log message, but now since we've pushed + // the id into a IdentityProxy object, we would need to dump that object alongwith the + // message. + InvalidParameterValueException ref = (InvalidParameterValueException) t; + ServerApiException ex = new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); // copy over the IdentityProxy information as well and throw the serverapiexception. ArrayList idList = ref.getIdProxyList(); if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.info(t.getMessage() + " db_id: " + id.getValue()); - } + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + " db_id: " + id.getValue()); + } } else { - s_logger.info(t.getMessage()); + s_logger.info(t.getMessage()); } // Also copy over the cserror code. - ex.setCSErrorCode(ref.getCSErrorCode()); + ex.setCSErrorCode(ref.getCSErrorCode()); throw ex; } else if(t instanceof IllegalArgumentException) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); + throw new ServerApiException(BaseCmd.PARAM_ERROR, t.getMessage()); } else if (t instanceof PermissionDeniedException) { - PermissionDeniedException ref = (PermissionDeniedException)t; - ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); + PermissionDeniedException ref = (PermissionDeniedException)t; + ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_ERROR, t.getMessage()); // copy over the IdentityProxy information as well and throw the serverapiexception. - ArrayList idList = ref.getIdProxyList(); + ArrayList idList = ref.getIdProxyList(); if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.info("PermissionDenied: " + t.getMessage() + "db_id: " + id.getValue()); - } - } else { - s_logger.info("PermissionDenied: " + t.getMessage()); - } - // Also copy over the cserror code. - ex.setCSErrorCode(ref.getCSErrorCode()); - throw ex; - } else if (t instanceof AccountLimitException) { - AccountLimitException ref = (AccountLimitException)t; - ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); - // copy over the IdentityProxy information as well and throw the serverapiexception. - ArrayList idList = ref.getIdProxyList(); - if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.info(t.getMessage() + "db_id: " + id.getValue()); - } + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info("PermissionDenied: " + t.getMessage() + "db_id: " + id.getValue()); + } } else { - s_logger.info(t.getMessage()); + s_logger.info("PermissionDenied: " + t.getMessage()); } // Also copy over the cserror code. - ex.setCSErrorCode(ref.getCSErrorCode()); + ex.setCSErrorCode(ref.getCSErrorCode()); + throw ex; + } else if (t instanceof AccountLimitException) { + AccountLimitException ref = (AccountLimitException)t; + ServerApiException ex = new ServerApiException(BaseCmd.ACCOUNT_RESOURCE_LIMIT_ERROR, t.getMessage()); + // copy over the IdentityProxy information as well and throw the serverapiexception. + ArrayList idList = ref.getIdProxyList(); + if (idList != null) { + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + "db_id: " + id.getValue()); + } + } else { + s_logger.info(t.getMessage()); + } + // Also copy over the cserror code. + ex.setCSErrorCode(ref.getCSErrorCode()); throw ex; } else if (t instanceof InsufficientCapacityException) { - InsufficientCapacityException ref = (InsufficientCapacityException)t; - ServerApiException ex = new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); + InsufficientCapacityException ref = (InsufficientCapacityException)t; + ServerApiException ex = new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, t.getMessage()); // copy over the IdentityProxy information as well and throw the serverapiexception. - ArrayList idList = ref.getIdProxyList(); + ArrayList idList = ref.getIdProxyList(); if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.info(t.getMessage() + "db_id: " + id.getValue()); - } + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.info(t.getMessage() + "db_id: " + id.getValue()); + } } else { - s_logger.info(t.getMessage()); + s_logger.info(t.getMessage()); } // Also copy over the cserror code - ex.setCSErrorCode(ref.getCSErrorCode()); + ex.setCSErrorCode(ref.getCSErrorCode()); throw ex; } else if (t instanceof ResourceAllocationException) { - ResourceAllocationException ref = (ResourceAllocationException)t; + ResourceAllocationException ref = (ResourceAllocationException)t; ServerApiException ex = new ServerApiException(BaseCmd.RESOURCE_ALLOCATION_ERROR, t.getMessage()); // copy over the IdentityProxy information as well and throw the serverapiexception. ArrayList idList = ref.getIdProxyList(); if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); - } + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); + } } else { - s_logger.warn("Exception: ", t); + s_logger.warn("Exception: ", t); } // Also copy over the cserror code. - ex.setCSErrorCode(ref.getCSErrorCode()); + ex.setCSErrorCode(ref.getCSErrorCode()); throw ex; } else if (t instanceof ResourceUnavailableException) { - ResourceUnavailableException ref = (ResourceUnavailableException)t; + ResourceUnavailableException ref = (ResourceUnavailableException)t; ServerApiException ex = new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, t.getMessage()); // copy over the IdentityProxy information as well and throw the serverapiexception. ArrayList idList = ref.getIdProxyList(); if (idList != null) { - // Iterate through entire arraylist and copy over each proxy id. - for (int i = 0 ; i < idList.size(); i++) { - IdentityProxy id = idList.get(i); - ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); - s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); - } + // Iterate through entire arraylist and copy over each proxy id. + for (int i = 0 ; i < idList.size(); i++) { + IdentityProxy id = idList.get(i); + ex.addProxyObject(id.getTableName(), id.getValue(), id.getidFieldName()); + s_logger.warn("Exception: " + t.getMessage() + "db_id: " + id.getValue()); + } } else { - s_logger.warn("Exception: ", t); + s_logger.warn("Exception: ", t); } // Also copy over the cserror code. - ex.setCSErrorCode(ref.getCSErrorCode()); + ex.setCSErrorCode(ref.getCSErrorCode()); throw ex; } else if (t instanceof AsyncCommandQueued) { throw (AsyncCommandQueued) t; @@ -256,12 +357,12 @@ public class ApiDispatcher { s_logger.error("Exception while executing " + cmd.getClass().getSimpleName() + ":", t); ServerApiException ex; if (UserContext.current().getCaller().getType() == Account.ACCOUNT_TYPE_ADMIN) { - ex = new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); + ex = new ServerApiException(BaseCmd.INTERNAL_ERROR, t.getMessage()); } else { ex = new ServerApiException(BaseCmd.INTERNAL_ERROR, BaseCmd.USER_ERROR_MESSAGE); } ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName())); - throw ex; + throw ex; } } } @@ -279,7 +380,7 @@ public class ApiDispatcher { if ((unpackedParams.get(ApiConstants.PAGE) == null) && (pageSize != null && pageSize != BaseListCmd.PAGESIZE_UNLIMITED)) { ServerApiException ex = new ServerApiException(BaseCmd.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified"); ex.setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ex.getClass().getName())); - throw ex; + throw ex; } else if (pageSize == null && (unpackedParams.get(ApiConstants.PAGE) != null)) { throw new ServerApiException(BaseCmd.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified"); } @@ -408,7 +509,7 @@ public class ApiDispatcher { listParam.add(val); } - break; + break; case SHORT: listParam.add(Short.valueOf(token)); case STRING: @@ -500,8 +601,8 @@ public class ApiDispatcher { clazz = clazz.getSuperclass(); } while (clazz != Object.class && clazz != null); } - - + + public static Long getIdentiyId(String tableName, String token) { return s_instance._identityDao.getIdentityId(tableName, token); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 73a9f927e03..6477e536842 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -58,11 +58,13 @@ import com.cloud.api.response.LBStickinessResponse; import com.cloud.api.response.LDAPConfigResponse; import com.cloud.api.response.ListResponse; import com.cloud.api.response.LoadBalancerResponse; +import com.cloud.api.response.NetworkACLResponse; import com.cloud.api.response.NetworkOfferingResponse; import com.cloud.api.response.NetworkResponse; import com.cloud.api.response.NicResponse; import com.cloud.api.response.PhysicalNetworkResponse; import com.cloud.api.response.PodResponse; +import com.cloud.api.response.PrivateGatewayResponse; import com.cloud.api.response.ProjectAccountResponse; import com.cloud.api.response.ProjectInvitationResponse; import com.cloud.api.response.ProjectResponse; @@ -70,14 +72,19 @@ import com.cloud.api.response.ProviderResponse; import com.cloud.api.response.RemoteAccessVpnResponse; import com.cloud.api.response.ResourceCountResponse; import com.cloud.api.response.ResourceLimitResponse; +import com.cloud.api.response.ResourceTagResponse; import com.cloud.api.response.SecurityGroupResponse; import com.cloud.api.response.SecurityGroupResultObject; import com.cloud.api.response.SecurityGroupRuleResponse; import com.cloud.api.response.SecurityGroupRuleResultObject; import com.cloud.api.response.ServiceOfferingResponse; import com.cloud.api.response.ServiceResponse; +import com.cloud.api.response.Site2SiteCustomerGatewayResponse; +import com.cloud.api.response.Site2SiteVpnConnectionResponse; +import com.cloud.api.response.Site2SiteVpnGatewayResponse; import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; import com.cloud.api.response.StorageNetworkIpRangeResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.api.response.SwiftResponse; @@ -91,6 +98,8 @@ import com.cloud.api.response.UserVmResponse; import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; import com.cloud.api.response.VpnUsersResponse; import com.cloud.api.response.ZoneResponse; import com.cloud.async.AsyncJob; @@ -130,11 +139,15 @@ import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VpnUser; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.NetworkACL; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StickinessPolicy; @@ -143,6 +156,10 @@ import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -151,6 +168,7 @@ import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.server.Criteria; +import com.cloud.server.ResourceTag; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; @@ -727,30 +745,30 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public IPAddressResponse createIPAddressResponse(IpAddress ipAddress) { - VlanVO vlan = ApiDBUtils.findVlanById(ipAddress.getVlanId()); + public IPAddressResponse createIPAddressResponse(IpAddress ipAddr) { + VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId()); boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork); - long zoneId = ipAddress.getDataCenterId(); + long zoneId = ipAddr.getDataCenterId(); IPAddressResponse ipResponse = new IPAddressResponse(); - ipResponse.setId(ipAddress.getId()); - ipResponse.setIpAddress(ipAddress.getAddress().toString()); - if (ipAddress.getAllocatedTime() != null) { - ipResponse.setAllocated(ipAddress.getAllocatedTime()); + ipResponse.setId(ipAddr.getId()); + ipResponse.setIpAddress(ipAddr.getAddress().toString()); + if (ipAddr.getAllocatedTime() != null) { + ipResponse.setAllocated(ipAddr.getAllocatedTime()); } ipResponse.setZoneId(zoneId); - ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddress.getDataCenterId()).getName()); - ipResponse.setSourceNat(ipAddress.isSourceNat()); - ipResponse.setIsSystem(ipAddress.getSystem()); + ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddr.getDataCenterId()).getName()); + ipResponse.setSourceNat(ipAddr.isSourceNat()); + ipResponse.setIsSystem(ipAddr.getSystem()); // get account information - populateOwner(ipResponse, ipAddress); + populateOwner(ipResponse, ipAddr); ipResponse.setForVirtualNetwork(forVirtualNetworks); - ipResponse.setStaticNat(ipAddress.isOneToOneNat()); + ipResponse.setStaticNat(ipAddr.isOneToOneNat()); - if (ipAddress.getAssociatedWithVmId() != null) { - UserVm vm = ApiDBUtils.findUserVmById(ipAddress.getAssociatedWithVmId()); + if (ipAddr.getAssociatedWithVmId() != null) { + UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId()); ipResponse.setVirtualMachineId(vm.getId()); ipResponse.setVirtualMachineName(vm.getHostName()); if (vm.getDisplayName() != null) { @@ -760,11 +778,12 @@ public class ApiResponseHelper implements ResponseGenerator { } } - ipResponse.setAssociatedNetworkId(ipAddress.getAssociatedWithNetworkId()); + ipResponse.setAssociatedNetworkId(ipAddr.getAssociatedWithNetworkId()); + ipResponse.setVpcId(ipAddr.getVpcId()); // Network id the ip is associated withif associated networkId is null, try to get this information from vlan - Long associatedNetworkId = ipAddress.getAssociatedWithNetworkId(); - Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddress.getVlanId()); + Long associatedNetworkId = ipAddr.getAssociatedWithNetworkId(); + Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId()); if (associatedNetworkId == null) { associatedNetworkId = vlanNetworkId; } @@ -780,18 +799,18 @@ public class ApiResponseHelper implements ResponseGenerator { } ipResponse.setNetworkId(networkId); - ipResponse.setState(ipAddress.getState().toString()); - ipResponse.setPhysicalNetworkId(ipAddress.getPhysicalNetworkId()); + ipResponse.setState(ipAddr.getState().toString()); + ipResponse.setPhysicalNetworkId(ipAddr.getPhysicalNetworkId()); // show this info to admin only Account account = UserContext.current().getCaller(); if ((account == null) || account.getType() == Account.ACCOUNT_TYPE_ADMIN) { - ipResponse.setVlanId(ipAddress.getVlanId()); - ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddress.getVlanId()).getVlanTag()); + ipResponse.setVlanId(ipAddr.getVlanId()); + ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); } - if (ipAddress.getSystem()) { - if (ipAddress.isOneToOneNat()) { + if (ipAddr.getSystem()) { + if (ipAddr.isOneToOneNat()) { ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString()); } else { ipResponse.setPurpose(IpAddress.Purpose.Lb.toString()); @@ -1022,7 +1041,7 @@ public class ApiResponseHelper implements ResponseGenerator { volResponse.setCreated(volume.getCreated()); volResponse.setState(volume.getState().toString()); if(volume.getState() == Volume.State.UploadOp){ - com.cloud.storage.VolumeHostVO volumeHostRef = ApiDBUtils.findVolumeHostRef(volume.getId(), volume.getDataCenterId()); + com.cloud.storage.VolumeHostVO volumeHostRef = ApiDBUtils.findVolumeHostRef(volume.getId(), volume.getDataCenterId()); volResponse.setSize(volumeHostRef.getSize()); volResponse.setCreated(volumeHostRef.getCreated()); Account caller = UserContext.current().getCaller(); @@ -1040,17 +1059,17 @@ public class ApiResponseHelper implements ResponseGenerator { } else { volumeStatus = volumeHostRef.getErrorString(); if(volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.NOT_DOWNLOADED){ - volResponse.setState("UploadNotStarted"); + volResponse.setState("UploadNotStarted"); }else { - volResponse.setState("UploadError"); + volResponse.setState("UploadError"); } } volResponse.setStatus(volumeStatus); } else if (volumeHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { - volResponse.setStatus("Upload Complete"); - volResponse.setState("Uploaded"); + volResponse.setStatus("Upload Complete"); + volResponse.setState("Uploaded"); } else { - volResponse.setStatus("Successfully Installed"); + volResponse.setStatus("Successfully Installed"); } } @@ -1100,7 +1119,7 @@ public class ApiResponseHelper implements ResponseGenerator { // return hypervisor for ROOT and Resource domain only Account caller = UserContext.current().getCaller(); if ((caller.getType() == Account.ACCOUNT_TYPE_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) && volume.getState() != Volume.State.UploadOp) { - volResponse.setHypervisor(ApiDBUtils.getVolumeHyperType(volume.getId()).toString()); + volResponse.setHypervisor(ApiDBUtils.getVolumeHyperType(volume.getId()).toString()); } volResponse.setAttached(volume.getAttached()); @@ -1657,6 +1676,8 @@ public class ApiResponseHelper implements ResponseGenerator { routerResponse.setDns2(zone.getDns2()); } + routerResponse.setVpcId(router.getVpcId()); + routerResponse.setObjectName("domainrouter"); return routerResponse; } @@ -2306,10 +2327,11 @@ public class ApiResponseHelper implements ResponseGenerator { boolean savedValue = SerializationContext.current().getUuidTranslation(); SerializationContext.current().setUuidTranslation(false); - jobResponse.setJobResult((ResponseObject) ApiSerializerHelper.fromSerializedString(job.getResult())); - SerializationContext.current().setUuidTranslation(savedValue); - + Object resultObject = ApiSerializerHelper.fromSerializedString(job.getResult()); + jobResponse.setJobResult((ResponseObject) resultObject); + SerializationContext.current().setUuidTranslation(savedValue); + if (resultObject != null) { Class clz = resultObject.getClass(); if (clz.isPrimitive() || clz.getSuperclass() == Number.class || clz == String.class || clz == Date.class) { @@ -2805,7 +2827,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setBroadcastUri(broadcastUri); String vlan="N/A"; if (broadcastUri.startsWith("vlan")) { - vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); + vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); } response.setVlan(vlan); } @@ -2885,6 +2907,8 @@ public class ApiResponseHelper implements ResponseGenerator { } response.setSpecifyIpRanges(network.getSpecifyIpRanges()); + response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); + response.setVpcId(network.getVpcId()); response.setObjectName("network"); return response; @@ -2952,6 +2976,39 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("firewallrule"); return response; } + + @Override + public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) { + NetworkACLResponse response = new NetworkACLResponse(); + + response.setId(networkACL.getId()); + response.setProtocol(networkACL.getProtocol()); + if (networkACL.getSourcePortStart() != null) { + response.setStartPort(Integer.toString(networkACL.getSourcePortStart())); + } + + if (networkACL.getSourcePortEnd() != null) { + response.setEndPort(Integer.toString(networkACL.getSourcePortEnd())); + } + + List cidrs = ApiDBUtils.findFirewallSourceCidrs(networkACL.getId()); + response.setCidrList(StringUtils.join(cidrs, ",")); + + response.setTrafficType(networkACL.getTrafficType().toString()); + + FirewallRule.State state = networkACL.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + + response.setIcmpCode(networkACL.getIcmpCode()); + response.setIcmpType(networkACL.getIcmpType()); + + response.setState(stateToSet); + response.setObjectName("networkacl"); + return response; + } public UserVmData newUserVmData(UserVm userVm) { UserVmData userVmData = new UserVmData(); @@ -3399,5 +3456,198 @@ public class ApiResponseHelper implements ResponseGenerator { public Long getIdentiyId(String tableName, String token) { return ApiDispatcher.getIdentiyId(tableName, token); } + + @Override + public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag) { + ResourceTagResponse response = new ResourceTagResponse(); + response.setKey(resourceTag.getKey()); + response.setValue(resourceTag.getValue()); + response.setResourceType(resourceTag.getResourceType().toString()); + response.setId(ApiDBUtils.getUuid(String.valueOf(resourceTag.getResourceId()),resourceTag.getResourceType())); + Long accountId = resourceTag.getAccountId(); + Long domainId = resourceTag.getDomainId(); + if (accountId != null) { + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(resourceTag.getAccountId()); + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId()); + response.setProjectId(project.getId()); + response.setProjectName(project.getName()); + } else { + response.setAccountName(account.getAccountName()); + } + } + + if (domainId != null) { + response.setDomainId(domainId); + response.setDomainName(ApiDBUtils.findDomainById(domainId).getName()); + } + + response.setCustomer(resourceTag.getCustomer()); + + response.setObjectName("tag"); + + return response; + } + + @Override + public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { + VpcOfferingResponse response = new VpcOfferingResponse(); + response.setId(offering.getId()); + response.setName(offering.getName()); + response.setDisplayText(offering.getDisplayText()); + response.setIsDefault(offering.isDefault()); + response.setState(offering.getState().name()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + response.setServices(serviceResponses); + response.setObjectName("vpcoffering"); + return response; + } + + + @Override + public VpcResponse createVpcResponse(Vpc vpc) { + VpcResponse response = new VpcResponse(); + response.setId(vpc.getId()); + response.setName(vpc.getName()); + response.setDisplayText(vpc.getDisplayText()); + response.setState(vpc.getState().name()); + response.setVpcOfferingId(vpc.getVpcOfferingId()); + response.setCidr(vpc.getCidr()); + response.setZoneId(vpc.getZoneId()); + response.setRestartRequired(vpc.isRestartRequired()); + response.setNetworkDomain(vpc.getNetworkDomain()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + + List networkResponses = new ArrayList(); + List networks = ApiDBUtils.listVpcNetworks(vpc.getId()); + for (Network network : networks) { + NetworkResponse ntwkRsp = createNetworkResponse(network); + networkResponses.add(ntwkRsp); + } + + response.setNetworks(networkResponses); + response.setServices(serviceResponses); + response.setObjectName("vpcoffering"); + return response; + } + + @Override + public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) { + PrivateGatewayResponse response = new PrivateGatewayResponse(); + response.setId(result.getId()); + response.setVlan(result.getVlanTag()); + response.setGateway(result.getGateway()); + response.setNetmask(result.getNetmask()); + response.setVpcId(result.getVpcId()); + response.setZoneId(result.getZoneId()); + DataCenter zone = ApiDBUtils.findZoneById(result.getZoneId()); + response.setZoneName(zone.getName()); + response.setAddress(result.getIp4Address()); + response.setPhysicalNetworkId(result.getPhysicalNetworkId()); + + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + + response.setObjectName("privategateway"); + + return response; + } + + @Override + public StaticRouteResponse createStaticRouteResponse(StaticRoute result) { + StaticRouteResponse response = new StaticRouteResponse(); + response.setId(result.getId()); + response.setVpcId(result.getVpcId()); + response.setCidr(result.getCidr()); + + StaticRoute.State state = result.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + response.setState(stateToSet); + populateAccount(response, result.getAccountId()); + populateDomain(response, result.getDomainId()); + response.setObjectName("staticroute"); + + return response; + } + + @Override + public Site2SiteVpnGatewayResponse createSite2SiteVpnGatewayResponse(Site2SiteVpnGateway result) { + Site2SiteVpnGatewayResponse response = new Site2SiteVpnGatewayResponse(); + response.setId(result.getId()); + response.setIp(ApiDBUtils.findIpAddressById(result.getAddrId()).getAddress().toString()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpngateway"); + return response; + } + + @Override + public Site2SiteCustomerGatewayResponse createSite2SiteCustomerGatewayResponse(Site2SiteCustomerGateway result) { + Site2SiteCustomerGatewayResponse response = new Site2SiteCustomerGatewayResponse(); + response.setId(result.getId()); + response.setGatewayIp(result.getGatewayIp()); + response.setGuestCidrList(result.getGuestCidrList()); + response.setIpsecPsk(result.getIpsecPsk()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpncustomergateway"); + return response; + } + + @Override + public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) { + Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse(); + response.setId(result.getId()); + response.setVpnGatewayId(result.getVpnGatewayId()); + response.setCustomerGatewayId(result.getCustomerGatewayId()); + response.setCreated(result.getCreated()); + response.setRemoved(result.getRemoved()); + response.setObjectName("vpnconnection"); + return response; + } } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index d13e67ae301..a840fac90ab 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -500,7 +500,8 @@ public class ApiServer implements HttpRequestHandler { asyncCmd.setStartEventId(startEventId); // save the scheduled event - Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), + Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, + asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), startEventId); if (startEventId == 0) { // There was no create event before, set current event id as start eventId @@ -774,7 +775,7 @@ public class ApiServer implements HttpRequestHandler { } } - public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, Map requestParameters) throws CloudAuthenticationException { + public void loginUser(HttpSession session, String username, String password, Long domainId, String domainPath, String loginIpAddress ,Map requestParameters) throws CloudAuthenticationException { // We will always use domainId first. If that does not exist, we will use domain name. If THAT doesn't exist // we will default to ROOT if (domainId == null) { @@ -790,7 +791,7 @@ public class ApiServer implements HttpRequestHandler { } } - UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, requestParameters); + UserAccount userAcct = _accountMgr.authenticateUser(username, password, domainId, loginIpAddress, requestParameters); if (userAcct != null) { String timezone = userAcct.getTimezone(); float offsetInHrs = 0f; diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index b7b7fff8cb0..a0da6573b43 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -203,7 +203,7 @@ public class ApiServlet extends HttpServlet { if (username != null) { String pwd = ((password == null) ? null : password[0]); try { - _apiServer.loginUser(session, username[0], pwd, domainId, domain, params); + _apiServer.loginUser(session, username[0], pwd, domainId, domain, req.getRemoteAddr(), params); auditTrailSb.insert(0, "(userId=" + session.getAttribute("userid") + " accountId=" + ((Account) session.getAttribute("accountobj")).getId() + " sessionId=" + session.getId() + ")"); String loginResponse = getLoginSuccessResponse(session, responseType); diff --git a/server/src/com/cloud/baremetal/BareMetalPingServiceImpl.java b/server/src/com/cloud/baremetal/BareMetalPingServiceImpl.java index 71e02494800..58ece593548 100755 --- a/server/src/com/cloud/baremetal/BareMetalPingServiceImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalPingServiceImpl.java @@ -60,7 +60,9 @@ public class BareMetalPingServiceImpl extends BareMetalPxeServiceBase implements List pxeServers = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.PxeServer, null, podId, zoneId); if (pxeServers.size() != 0) { - throw new InvalidParameterValueException("Already had a PXE server in Pod: " + podId + " zone: " + zoneId); + InvalidParameterValueException ex = new InvalidParameterValueException("Already had a PXE server in Pod with specified podId and zone with specified zoneId"); + ex.addProxyObject("pod", podId, "podId"); + ex.addProxyObject(zone, zoneId, "zoneId"); } diff --git a/server/src/com/cloud/baremetal/BareMetalResourceBase.java b/server/src/com/cloud/baremetal/BareMetalResourceBase.java index 7b4556c4f1b..76ba08cb3ce 100755 --- a/server/src/com/cloud/baremetal/BareMetalResourceBase.java +++ b/server/src/com/cloud/baremetal/BareMetalResourceBase.java @@ -425,10 +425,10 @@ public class BareMetalResourceBase implements ServerResource { protected RebootAnswer execute(final RebootCommand cmd) { if (!doScript(_rebootCommand)) { - return new RebootAnswer(cmd, "IPMI reboot failed"); + return new RebootAnswer(cmd, "IPMI reboot failed", false); } - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } protected StopAnswer execute(final StopCommand cmd) { @@ -463,7 +463,7 @@ public class BareMetalResourceBase implements ServerResource { count++; } - return success ? new StopAnswer(cmd, "Success", null, Long.valueOf(0), Long.valueOf(0)) : new StopAnswer(cmd, "IPMI power off failed"); + return success ? new StopAnswer(cmd, "Success", null, true) : new StopAnswer(cmd, "IPMI power off failed", false); } protected StartAnswer execute(StartCommand cmd) { diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java index bac191bd310..2677e5ce384 100755 --- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java @@ -163,7 +163,9 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet } if (pxes.size() > 1) { - throw new CloudRuntimeException("Multiple PXE servers found in Pod " + host.getPodId() + " Zone " + host.getDataCenterId()); + CloudRuntimeException ex = new CloudRuntimeException("Multiple PXE servers found in Pod " + host.getPodId() + " in Zone with specified id"); + ex.addProxyObject("data_center", host.getDataCenterId(), "zoneId"); + throw ex; } HostVO pxe = pxes.get(0); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index dea61399a17..37da9d8561e 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -337,7 +337,8 @@ public enum Config { CustomDiskOfferingMaxSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering", null), ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Service offering used by console proxy; if NULL - system offering will be used", null), SecondaryStorageServiceOffering("Advanced", ManagementServer.class, Long.class, "secstorage.service.offering", null, "Service offering used by secondary storage; if NULL - system offering will be used", null), - HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null); + HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null), + VpcCleanupInterval("Advanced", ManagementServer.class, Integer.class, "vpc.cleanup.interval", "3600", "The interval (in seconds) between cleanup for Inactive VPCs", null); private final String _category; diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 85cdf34cf24..29de7bf4ba2 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -164,11 +164,12 @@ public interface ConfigurationManager extends ConfigurationService, Manager { /** * Creates a new network offering - * * @param name * @param displayText * @param trafficType * @param tags + * @param specifyVlan + * ; * @param networkRate * TODO * @param serviceProviderMap @@ -180,19 +181,18 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param systemOnly * TODO * @param serviceOfferingId + * @param conserveMode + * ; * @param specifyIpRanges * TODO * @param id - * @param specifyVlan - * ; - * @param conserveMode - * ; + * * @return network offering object */ - NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, - Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, - Map> serviceCapabilityMap, boolean specifyIpRanges); + NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, + boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, + boolean specifyIpRanges); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; @@ -226,4 +226,10 @@ public interface ConfigurationManager extends ConfigurationService, Manager { AllocationState findClusterAllocationState(ClusterVO cluster); + /** + * @param tags + * @return + */ + String cleanupTags(String tags); + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 09d53139d34..86a047c407a 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -283,14 +283,15 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura // As it is so common for people to forget about configuring // management.network.cidr, - String mgtCidr = _configDao.getValue(Config.ManagementNetwork.key()); + ConfigurationVO mgmtNetwork = _configDao.findByName(Config.ManagementNetwork.key()); + String mgtCidr = mgmtNetwork.getValue(); if (mgtCidr == null || mgtCidr.trim().isEmpty()) { String[] localCidrs = NetUtils.getLocalCidrs(); if (localCidrs.length > 0) { s_logger.warn("Management network CIDR is not configured originally. Set it default to " + localCidrs[0]); _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not configured originally. Set it default to " + localCidrs[0], ""); - _configDao.update(Config.ManagementNetwork.key(), Config.ManagementNetwork.getCategory(), localCidrs[0]); + _configDao.update(Config.ManagementNetwork.key(), mgmtNetwork.getCategory(), localCidrs[0]); } else { s_logger.warn("Management network CIDR is not properly configured and we are not able to find a default setting"); _alertMgr.sendAlert(AlertManager.ALERT_TYPE_MANAGMENT_NODE, 0, new Long(0), "Management network CIDR is not properly configured and we are not able to find a default setting", ""); @@ -1427,6 +1428,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura internalDns1 = zone.getInternalDns1(); } + if (internalDns2 == null) { + internalDns2 = zone.getInternalDns2(); + } + if (guestCidr == null) { guestCidr = zone.getGuestNetworkCidr(); } @@ -1608,11 +1613,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } else { continue; } + } else if (offering.getTrafficType() == TrafficType.Guest) { + continue; } userNetwork.setBroadcastDomainType(broadcastDomainType); userNetwork.setNetworkDomain(networkDomain); - _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, Domain.ROOT_DOMAIN, null, null); + _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, + Domain.ROOT_DOMAIN, null, null, null); } } } @@ -2476,7 +2484,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura " as ip " + ip + " belonging to the range has firewall rules applied. Cleanup the rules first"); } //release public ip address here - success = success && _networkMgr.releasePublicIpAddress(ip.getId(), userId, caller); + success = success && _networkMgr.disassociatePublicIpAddress(ip.getId(), userId, caller); } if (!success) { s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal"); @@ -2531,7 +2539,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return tags; } - private String cleanupTags(String tags) { + @Override + public String cleanupTags(String tags) { if (tags != null) { String[] tokens = tags.split(","); StringBuilder t = new StringBuilder(); @@ -2864,7 +2873,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_CREATE, eventDescription = "creating network offering") public NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd) { - Long userId = UserContext.current().getCallerUserId(); String name = cmd.getNetworkOfferingName(); String displayText = cmd.getDisplayText(); String tags = cmd.getTags(); @@ -2971,7 +2979,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Set providers = new HashSet(); // in Acton, don't allow to specify more than 1 provider per service if (svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) { - throw new InvalidParameterValueException("In the current release only one provider can be specified for the service"); + throw new InvalidParameterValueException("In the current release only one provider can be " + + "specified for the service"); } for (String prvNameStr : svcPrv.get(serviceStr)) { // check if provider is supported @@ -3002,7 +3011,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } serviceProviderMap.put(service, providers); } else { - throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network offering, can't add a provider to it"); + throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network " + + "offering, can't add a provider to it"); } } } @@ -3036,8 +3046,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap); serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap); - // if Firewall service is missing, and Juniper is a provider for any other service or VR is StaticNat/PF provider, add Firewall - // service/provider combination + // if Firewall service is missing, add Firewall service/provider combination if (firewallProvider != null) { s_logger.debug("Adding Firewall service with provider " + firewallProvider.getName()); Set firewallProviderSet = new HashSet(); @@ -3045,8 +3054,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura serviceProviderMap.put(Service.Firewall, firewallProviderSet); } - return createNetworkOffering(userId, name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, - false, serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges); + return createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, + serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges); } void validateLoadBalancerServiceCapabilities(Map lbServiceCapabilityMap) { @@ -3126,9 +3135,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override @DB - public NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, - Integer networkRate, Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, - Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges) { + public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, + Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, + boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges) { String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); @@ -3190,13 +3199,15 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if ((sourceNatServiceCapabilityMap != null) && (!sourceNatServiceCapabilityMap.isEmpty())) { String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes); if (sourceNatType != null) { - _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType); + _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + Capability.SupportedSourceNatTypes, sourceNatType); sharedSourceNat = sourceNatType.contains("perzone"); } String param = sourceNatServiceCapabilityMap.get(Capability.RedundantRouter); if (param != null) { - _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.RedundantRouter, param); + _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + Capability.RedundantRouter, param); redundantRouter = param.contains("true"); } } @@ -3210,7 +3221,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } - NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, + NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, + networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges); if (serviceOfferingId != null) { @@ -3549,19 +3561,23 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } if (availability == null) { - throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional); + throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + + Availability.Required + ", " + Availability.Optional); } else { if (availability == NetworkOffering.Availability.Required) { - boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated && _networkMgr.areServicesSupportedByNetworkOffering(offeringToUpdate.getId(), Service.SourceNat)); + boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated + && _networkMgr.areServicesSupportedByNetworkOffering(offeringToUpdate.getId(), Service.SourceNat)); if (!canOffBeRequired) { - throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + throw new InvalidParameterValueException("Availability can be " + + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled"); } // only one network offering in the system can be Required List offerings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) { - throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required); + throw new InvalidParameterValueException("System already has network offering id=" + + offerings.get(0).getId() + " with availability " + Availability.Required); } } offering.setAvailability(availability); @@ -3576,7 +3592,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } @Override - @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the default zone", async=true) + @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + + "default zone", async=true) public AccountVO markDefaultZone(String accountName, long domainId, long defaultZoneId) { // Check if the account exists diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index f9d74ceaa72..f367175dfd8 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -45,6 +45,7 @@ import com.cloud.dao.EntityManagerImpl; import com.cloud.dc.ClusterDetailsDaoImpl; import com.cloud.dc.dao.AccountVlanMapDaoImpl; import com.cloud.dc.dao.ClusterDaoImpl; +import com.cloud.dc.dao.ClusterVSMMapDaoImpl; import com.cloud.dc.dao.DataCenterDaoImpl; import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DcDetailsDaoImpl; @@ -70,11 +71,9 @@ import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.ExternalLoadBalancerUsageManagerImpl; import com.cloud.network.NetworkManagerImpl; import com.cloud.network.StorageNetworkManagerImpl; +import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl; import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; -import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl; -import com.cloud.dc.dao.ClusterVSMMapDaoImpl; -import com.cloud.network.dao.PortProfileDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; import com.cloud.network.dao.IPAddressDaoImpl; @@ -91,16 +90,20 @@ import com.cloud.network.dao.NetworkServiceMapDaoImpl; import com.cloud.network.dao.PhysicalNetworkDaoImpl; import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl; import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl; +import com.cloud.network.dao.PortProfileDaoImpl; import com.cloud.network.dao.RemoteAccessVpnDaoImpl; +import com.cloud.network.dao.Site2SiteCustomerGatewayDaoImpl; +import com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl; +import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; import com.cloud.network.dao.VirtualRouterProviderDaoImpl; import com.cloud.network.dao.VpnUserDaoImpl; +import com.cloud.network.element.CiscoNexusVSMElement; +import com.cloud.network.element.CiscoNexusVSMElementService; import com.cloud.network.element.F5ExternalLoadBalancerElement; import com.cloud.network.element.F5ExternalLoadBalancerElementService; import com.cloud.network.element.JuniperSRXExternalFirewallElement; import com.cloud.network.element.JuniperSRXFirewallElementService; import com.cloud.network.element.NetscalerElement; -import com.cloud.network.element.CiscoNexusVSMElement; -import com.cloud.network.element.CiscoNexusVSMElementService; import com.cloud.network.element.NetscalerLoadBalancerElementService; import com.cloud.network.element.VirtualRouterElement; import com.cloud.network.element.VirtualRouterElementService; @@ -112,6 +115,7 @@ import com.cloud.network.ovs.OvsTunnelManagerImpl; import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl; import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl; import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; +import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; @@ -121,7 +125,16 @@ import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl; import com.cloud.network.security.dao.VmRulesetLogDaoImpl; +import com.cloud.network.vpc.NetworkACLManagerImpl; +import com.cloud.network.vpc.VpcManagerImpl; +import com.cloud.network.vpc.Dao.PrivateIpDaoImpl; +import com.cloud.network.vpc.Dao.StaticRouteDaoImpl; +import com.cloud.network.vpc.Dao.VpcDaoImpl; +import com.cloud.network.vpc.Dao.VpcGatewayDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDaoImpl; import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; +import com.cloud.network.vpn.Site2SiteVpnManagerImpl; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl; import com.cloud.projects.ProjectManagerImpl; @@ -159,6 +172,8 @@ import com.cloud.storage.snapshot.SnapshotManagerImpl; import com.cloud.storage.snapshot.SnapshotSchedulerImpl; import com.cloud.storage.swift.SwiftManagerImpl; import com.cloud.storage.upload.UploadMonitorImpl; +import com.cloud.tags.TaggedResourceManagerImpl; +import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.template.HyervisorTemplateAdapter; import com.cloud.template.TemplateAdapter; import com.cloud.template.TemplateAdapter.TemplateAdapterType; @@ -327,6 +342,16 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class); addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class); + addDao("TagsDao", ResourceTagsDaoImpl.class); + addDao("VpcDao", VpcDaoImpl.class); + addDao("VpcOfferingDao", VpcOfferingDaoImpl.class); + addDao("VpcOfferingServiceMapDao", VpcOfferingServiceMapDaoImpl.class); + addDao("PrivateIpDao", PrivateIpDaoImpl.class); + addDao("VpcGatewayDao", VpcGatewayDaoImpl.class); + addDao("StaticRouteDao", StaticRouteDaoImpl.class); + addDao("Site2SiteVpnGatewayDao", Site2SiteVpnGatewayDaoImpl.class); + addDao("Site2SiteCustomerGatewayDao", Site2SiteCustomerGatewayDaoImpl.class); + addDao("Site2SiteVpnConnnectionDao", Site2SiteVpnConnectionDaoImpl.class); } @Override @@ -383,6 +408,11 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("StorageNetworkManager", StorageNetworkManagerImpl.class); addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class); addManager("HA Manager", HighAvailabilityManagerImpl.class); + addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class); + addManager("VPC Manager", VpcManagerImpl.class); + addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class); + addManager("NetworkACLManager", NetworkACLManagerImpl.class); + addManager("Site2SiteVpnManager", Site2SiteVpnManagerImpl.class); } @Override diff --git a/server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java b/server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java index a34bfd39229..35e584c2c96 100644 --- a/server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java +++ b/server/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java @@ -163,14 +163,15 @@ public class ConfigurationDaoImpl extends GenericDaoBase profile) { + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index b6c1057a61a..61d6cd4c920 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -43,6 +43,8 @@ import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.api.ServerApiException; import com.cloud.api.commands.DestroyConsoleProxyCmd; @@ -82,6 +84,7 @@ import com.cloud.keystore.KeystoreDao; import com.cloud.keystore.KeystoreManager; import com.cloud.keystore.KeystoreVO; import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; @@ -95,7 +98,6 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; @@ -133,7 +135,6 @@ import com.cloud.uuididentity.dao.IdentityDao; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; -import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.SystemVmLoadScanHandler; import com.cloud.vm.SystemVmLoadScanner; import com.cloud.vm.SystemVmLoadScanner.AfterScanAction; @@ -1989,4 +1990,24 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } return _hashKey; } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/dc/DataCenterVO.java b/server/src/com/cloud/dc/DataCenterVO.java index 4a4142d8f66..14cb40fe2fe 100644 --- a/server/src/com/cloud/dc/DataCenterVO.java +++ b/server/src/com/cloud/dc/DataCenterVO.java @@ -97,7 +97,7 @@ public class DataCenterVO implements DataCenter, Identity { @Column(name="firewall_provider") private String firewallProvider; - @Column(name="mac_address", updatable = false, nullable=false) + @Column(name="mac_address", nullable=false) @TableGenerator(name="mac_address_sq", table="data_center", pkColumnName="id", valueColumnName="mac_address", allocationSize=1) private long macAddress = 1; @@ -406,4 +406,12 @@ public class DataCenterVO implements DataCenter, Identity { public void setUuid(String uuid) { this.uuid = uuid; } + + public long getMacAddress() { + return macAddress; + } + + public void setMacAddress(long macAddress) { + this.macAddress = macAddress; + } } diff --git a/server/src/com/cloud/domain/DomainVO.java b/server/src/com/cloud/domain/DomainVO.java index fbce2e5dd6f..f48b86138fe 100644 --- a/server/src/com/cloud/domain/DomainVO.java +++ b/server/src/com/cloud/domain/DomainVO.java @@ -22,12 +22,16 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import org.apache.log4j.Logger; + import com.cloud.api.Identity; import com.cloud.utils.db.GenericDao; @Entity @Table(name="domain") -public class DomainVO implements Domain, Identity { +public class DomainVO implements Domain, Identity { + public static final Logger s_logger = Logger.getLogger(DomainVO.class.getName()); + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d62e3800542..2c3348427b7 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -35,7 +35,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis super(); } - protected NicTO toNicTO(NicProfile profile) { + @Override + public NicTO toNicTO(NicProfile profile) { NicTO to = new NicTO(); to.setDeviceId(profile.getDeviceId()); to.setBroadcastType(profile.getBroadcastType()); diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java index 6a300a5170e..932b17920bd 100644 --- a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java @@ -379,11 +379,13 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl IPAddressVO sourceNatIp = null; if (!sharedSourceNat) { - // Get the source NAT IP address for this network - List sourceNatIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(network.getAccountId(), zoneId, true, null); + // Get the source NAT IP address for this account + List sourceNatIps = _networkMgr.listPublicIpsAssignedToAccount(network.getAccountId(), + zoneId, true); if (sourceNatIps.size() != 1) { - String errorMsg = "External firewall was unable to find the source NAT IP address for account " + account.getAccountName(); + String errorMsg = "External firewall was unable to find the source NAT IP address for account " + + account.getAccountName(); s_logger.error(errorMsg); return true; } else { @@ -490,7 +492,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl protected void applyStaticNatRules(List staticNatRules, DataCenter zone, long externalFirewallId) throws ResourceUnavailableException { if (!staticNatRules.isEmpty()) { - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules); + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null); Answer answer = _agentMgr.easySend(externalFirewallId, cmd); if (answer == null || !answer.getResult()) { String details = (answer != null) ? answer.getDetails() : "details unavailable"; diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 3ad8c339350..409970d8d92 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -512,7 +512,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // release the public & private IP back to dc pool, as the load balancer // appliance is now destroyed _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); - _networkMgr.releasePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + _networkMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } } catch (Exception e) { s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage()); @@ -664,7 +664,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // release the public IP allocated for this LB appliance DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip"); IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString()); - _networkMgr.releasePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + _networkMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } else { deviceMapLock.unlock(); } @@ -732,7 +732,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase List staticNatRules = new ArrayList(); IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0); VlanVO vlan = _vlanDao.findById(ipVO.getVlanId()); - FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null); + FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null, null); FirewallRule.State state = !revoked ? FirewallRule.State.Add : FirewallRule.State.Revoke; fwRule.setState(state); StaticNatRule rule = new StaticNatRuleImpl(fwRule, privateIp); @@ -744,7 +744,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase protected void applyStaticNatRules(List staticNatRules, Network network, long firewallHostId) throws ResourceUnavailableException { if (!staticNatRules.isEmpty()) { - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules); + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(staticNatRules, null); Answer answer = _agentMgr.easySend(firewallHostId, cmd); if (answer == null || !answer.getResult()) { String details = (answer != null) ? answer.getDetails() : "details unavailable"; @@ -869,7 +869,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (loadBalancersToApply.size() > 0) { int numLoadBalancersForCommand = loadBalancersToApply.size(); LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); long guestVlanTag = Integer.parseInt(network.getBroadcastUri().getHost()); cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); diff --git a/server/src/com/cloud/network/IPAddressVO.java b/server/src/com/cloud/network/IPAddressVO.java index 9ed071f774d..ea69b592ff8 100644 --- a/server/src/com/cloud/network/IPAddressVO.java +++ b/server/src/com/cloud/network/IPAddressVO.java @@ -100,6 +100,9 @@ public class IPAddressVO implements IpAddress, Identity { @Transient @Column(name="domain_id") private Long domainId = null; + + @Column(name="vpc_id") + private Long vpcId; protected IPAddressVO() { this.uuid = UUID.randomUUID().toString(); @@ -271,4 +274,14 @@ public class IPAddressVO implements IpAddress, Identity { public void setSystem(boolean isSystem) { this.system = isSystem; } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public void setVpcId(Long vpcId) { + this.vpcId = vpcId; + } } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 2577440d298..65d35da25ec 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -36,11 +37,14 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; +import com.cloud.network.element.Site2SiteVpnServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; @@ -74,19 +78,9 @@ public interface NetworkManager extends NetworkService { * @throws InsufficientAddressCapacityException */ - PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, + boolean isSystem) throws InsufficientAddressCapacityException; - /** - * assigns a source nat ip address to an account within a network. - * - * @param owner - * @param network - * @param callerId - * @return - * @throws ConcurrentOperationException - * @throws InsufficientAddressCapacityException - */ - PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException; /** * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects. @@ -97,28 +91,26 @@ public interface NetworkManager extends NetworkService { * @param ipAddress * @return true if it did; false if it didn't */ - public boolean releasePublicIpAddress(long id, long userId, Account caller); + public boolean disassociatePublicIpAddress(long id, long userId, Account caller); /** * Lists IP addresses that belong to VirtualNetwork VLANs * * @param accountId * - account that the IP address should belong to - * @param dcId - * - zone that the IP address should belong to - * @param sourceNat - * - (optional) true if the IP address should be a source NAT address * @param associatedNetworkId * TODO + * @param sourceNat + * - (optional) true if the IP address should be a source NAT address * @return - list of IP addresses */ - List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId); + List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat); List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) throws ConcurrentOperationException; List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException; + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException; List getSystemAccountNetworkOfferings(String... offeringNames); @@ -145,6 +137,8 @@ public interface NetworkManager extends NetworkService { public boolean validateRule(FirewallRule rule); List getRemoteAccessVpnElements(); + + List getSite2SiteVpnElements(); PublicIpAddress getPublicIpAddress(long ipAddressId); @@ -161,8 +155,8 @@ public interface NetworkManager extends NetworkService { boolean destroyNetwork(long networkId, ReservationContext context); - Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, Long domainId, - PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; + Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork, + long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; /** * @throws ResourceAllocationException TODO @@ -240,8 +234,6 @@ public interface NetworkManager extends NetworkService { boolean canElementEnableIndividualServices(Provider provider); - PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId); - boolean areServicesSupportedInNetwork(long networkId, Service... services); boolean isNetworkSystem(Network network); @@ -261,9 +253,6 @@ public interface NetworkManager extends NetworkService { void canProviderSupportServices(Map> providersMap); - PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork( - long physicalNetworkId); - List getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType); @@ -307,4 +296,170 @@ public interface NetworkManager extends NetworkService { String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware); String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware); + + /** + * @param providerName + * @return + */ + NetworkElement getElementImplementingProvider(String providerName); + + /** + * @param owner + * @param guestNetwork + * @return + * @throws ConcurrentOperationException + * @throws InsufficientAddressCapacityException + */ + PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param owner + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws InsufficientAddressCapacityException + */ + PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param accountId + * @param zoneId + * @return + */ + String getAccountNetworkDomain(long accountId, long zoneId); + + + /** + * @return + */ + String getDefaultNetworkDomain(); + + + /** + * @param networkId + * @return + */ + List getNtwkOffDistinctProviders(long networkId); + + + /** + * @param requested + * @param network + * @param isDefaultNic + * @param deviceId + * @param vm + * @return + * @throws InsufficientVirtualNetworkCapcityException + * @throws InsufficientAddressCapacityException + * @throws ConcurrentOperationException + */ + Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, + VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param vmProfile + * @param dest + * @param context + * @param nicId + * @param network + * @return + * @throws InsufficientVirtualNetworkCapcityException + * @throws InsufficientAddressCapacityException + * @throws ConcurrentOperationException + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + */ + NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, + ReservationContext context, long nicId, NetworkVO network) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException; + + + /** + * @param vmProfile + * @param network + * @return TODO + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException; + + + /** + * @param vm + * @param network + */ + void removeNic(VirtualMachineProfile vm, Network network); + + + /** + * @param accountId + * @param dcId + * @param sourceNat + * @return + */ + List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat); + + + /** + * @param ipAddrId + * @param networkId + */ + IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param ipId + */ + void unassignIPFromVpcNetwork(long ipId); + + + /** + * @param vm + * @param networkId + * @return + */ + NicProfile getNicProfile(VirtualMachine vm, long networkId); + + + /** + * @param network + * @param provider + * @return + */ + boolean setupDns(Network network, Provider provider); + + + /** + * @param vmProfile + * @param network + * @param broadcastUri + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) + throws ConcurrentOperationException, ResourceUnavailableException; + + + /** + * @param zoneId + * @param trafficType + * @return + */ + List getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType); + + + /** + * @param guestNic + * @return + */ + boolean isPrivateGateway(Nic guestNic); + + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 4a43a5ff09f..f5d51ed6f72 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -23,6 +23,7 @@ import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; @@ -55,12 +56,10 @@ import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.ListTrafficTypeImplementorsCmd; import com.cloud.api.commands.RestartNetworkCmd; -import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -110,6 +109,7 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork.BroadcastDomainRange; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; @@ -126,13 +126,16 @@ import com.cloud.network.element.DhcpServiceProvider; import com.cloud.network.element.FirewallServiceProvider; import com.cloud.network.element.IpDeployer; import com.cloud.network.element.LoadBalancingServiceProvider; +import com.cloud.network.element.NetworkACLServiceProvider; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.RemoteAccessVPNServiceProvider; +import com.cloud.network.element.Site2SiteVpnServiceProvider; import com.cloud.network.element.SourceNatServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.element.VirtualRouterElement; +import com.cloud.network.element.VpcVirtualRouterElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; @@ -149,6 +152,11 @@ import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StaticNatRuleImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.network.vpc.NetworkACLManager; +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.Dao.PrivateIpDao; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; @@ -230,10 +238,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject UserVmDao _userVmDao = null; @Inject - ResourceLimitDao _limitDao = null; - @Inject - CapacityDao _capacityDao = null; - @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @@ -301,8 +305,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkServiceMapDao _ntwkSrvcDao; @Inject StorageNetworkManager _stnwMgr; + @Inject + VpcManager _vpcMgr; + @Inject + PrivateIpDao _privateIpDao; + @Inject + NetworkACLManager _networkACLMgr; private final HashMap _systemNetworks = new HashMap(5); + private static Long _privateOfferingId = null; ScheduledExecutorService _executor; @@ -326,6 +337,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); private static HashMap s_providerToNetworkElementMap = new HashMap(); + @Override public NetworkElement getElementImplementingProvider(String providerName) { String elementName = s_providerToNetworkElementMap.get(providerName); NetworkElement element = _networkElements.get(elementName); @@ -352,11 +364,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem); + return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null); } @DB - public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem) + public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, + Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId) throws InsufficientAddressCapacityException { StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in "); Transaction txn = Transaction.currentTxn(); @@ -382,8 +395,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // for direct network take ip addresses only from the vlans belonging to the network if (vlanUse == VlanType.DirectAttached) { - sc.setJoinParameters("vlan", "networkId", networkId); - errorMessage.append(", network id=" + networkId); + sc.setJoinParameters("vlan", "networkId", guestNetworkId); + errorMessage.append(", network id=" + guestNetworkId); } sc.setJoinParameters("vlan", "type", vlanUse); @@ -398,13 +411,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (addrs.size() == 0) { if (podId != null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Insufficient address capacity", Pod.class, podId); // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object. ex.addProxyObject("Pod", podId, "podId"); throw ex; } s_logger.warn(errorMessage.toString()); - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Insufficient address capacity", DataCenter.class, dcId); ex.addProxyObject("data_center", dcId, "dcId"); throw ex; } @@ -426,7 +441,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); if (vlanUse != VlanType.DirectAttached || zone.getNetworkType() == NetworkType.Basic) { - addr.setAssociatedWithNetworkId(networkId); + addr.setAssociatedWithNetworkId(guestNetworkId); + addr.setVpcId(vpcId); } _ipAddressDao.update(addr.getId(), addr); @@ -445,7 +461,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @DB protected void markPublicIpAsAllocated(IPAddressVO addr) { - assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : "Unable to transition from state " + addr.getState() + " to " + IpAddress.State.Allocated; + assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : + "Unable to transition from state " + addr.getState() + " to " + IpAddress.State.Allocated; Transaction txn = Transaction.currentTxn(); @@ -461,7 +478,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String guestType = vlan.getVlanType().toString(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, addr.getSystem()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), + addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, + addr.getSystem()); _usageEventDao.persist(usageEvent); // don't increment resource count for direct ip addresses if (addr.getAssociatedWithNetworkId() != null) { @@ -472,16 +491,60 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag txn.commit(); } + @Override - @DB - public PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException { - assert (network.getTrafficType() != null) : "You're asking for a source nat but your network can't participate in source nat. What do you have to say for yourself?"; + public PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException { + long dcId = vpc.getZoneId(); + + IPAddressVO sourceNatIp = getExistingSourceNat(owner.getId(), null, vpc.getId()); + + PublicIp ipToReturn = null; + + if (sourceNatIp != null) { + ipToReturn = new PublicIp(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(sourceNatIp.getMacAddress())); + } else { + ipToReturn = assignSourceNatIpAddress(owner, null, vpc.getId(), dcId); + } + + return ipToReturn; + } + + @Override + public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) + throws InsufficientAddressCapacityException, ConcurrentOperationException { + assert (guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network " + + "can't participate in source nat. What do you have to say for yourself?"; + long dcId = guestNetwork.getDataCenterId(); + + IPAddressVO sourceNatIp = getExistingSourceNat(owner.getId(), guestNetwork.getId(), guestNetwork.getVpcId()); + + PublicIp ipToReturn = null; + if (sourceNatIp != null) { + ipToReturn = new PublicIp(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(sourceNatIp.getMacAddress())); + } else { + ipToReturn = assignSourceNatIpAddress(owner, guestNetwork.getId(), null, dcId); + } + + return ipToReturn; + } + + @DB + public PublicIp assignSourceNatIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId) + throws ConcurrentOperationException, InsufficientAddressCapacityException { - long dcId = network.getDataCenterId(); long ownerId = owner.getId(); - PublicIp ip = null; + // Check that the maximum number of public IPs for the given accountId will not be exceeded + try { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); + } catch (ResourceAllocationException ex) { + s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); + throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); + } + PublicIp ip = null; Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -492,57 +555,28 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class // to get the table name and field name that is queried to fill this ownerid. ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account"); - ex.addProxyObject("account", ownerId, "ownerId"); - throw ex; } if (s_logger.isDebugEnabled()) { s_logger.debug("lock account " + ownerId + " is acquired"); } - IPAddressVO sourceNat = null; - List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, dcId, null, network.getId()); - if (addrs.size() == 0) { - - // Check that the maximum number of public IPs for the given accountId will not be exceeded - try { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); - } catch (ResourceAllocationException ex) { - s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); - throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("assigning a new ip address in " + dcId + " to " + owner); - } - // If account has Account specific ip ranges, try to allocate ip from there Long vlanId = null; List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId); if (maps != null && !maps.isEmpty()) { //check if the ips from this vlan are associated with this network List ips = _ipAddressDao.listByVlanId(maps.get(0).getVlanDbId()); - if (ips != null && !ips.isEmpty() && ips.get(0).getAssociatedWithNetworkId() == network.getId()) { + if (ips != null && !ips.isEmpty() && ips.get(0).getAssociatedWithNetworkId() == guestNtwkId) { vlanId = maps.get(0).getVlanDbId(); } } - ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false, null, false); - sourceNat = ip.ip(); + ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, guestNtwkId, + true, false, null, false, vpcId); + IPAddressVO sourceNatIp = ip.ip(); - markPublicIpAsAllocated(sourceNat); - _ipAddressDao.update(sourceNat.getId(), sourceNat); - } else { - // Account already has ip addresses - for (IPAddressVO addr : addrs) { - if (addr.isSourceNat()) { - sourceNat = addr; - break; - } - } - - assert (sourceNat != null) : "How do we get a bunch of ip addresses but none of them are source nat? account=" + ownerId + "; dc=" + dcId; - ip = new PublicIp(sourceNat, _vlanDao.findById(sourceNat.getVlanId()), NetUtils.createSequenceBasedMacAddress(sourceNat.getMacAddress())); - } + markPublicIpAsAllocated(sourceNatIp); + _ipAddressDao.update(sourceNatIp.getId(), sourceNatIp); txn.commit(); return ip; @@ -577,6 +611,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // The admin is making the call, determine if it is for someone else or for himself if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + // TBD: Check if call to addProxyObject() needs correction. PermissionDeniedException ex = new PermissionDeniedException("Invalid domain id given, permission denied"); ex.addProxyObject("domain", domainId, "domainId"); throw ex; @@ -586,6 +621,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (userAccount != null) { account = userAccount; } else { + // TBD: Check if call to addProxyObject() needs correction. PermissionDeniedException ex = new PermissionDeniedException("Unable to find account " + accountName + " in specified domain, permission denied"); ex.addProxyObject("domain", domainId, "domainId"); throw ex; @@ -605,7 +641,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List publicIps = new ArrayList(); if (userIps != null && !userIps.isEmpty()) { for (IPAddressVO userIp : userIps) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); publicIps.add(publicIp); } } @@ -614,16 +651,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (success) { for (IPAddressVO addr : userIps) { - if (addr.getState() == IpAddress.State.Allocating) { - - addr.setAssociatedWithNetworkId(network.getId()); markPublicIpAsAllocated(addr); - } else if (addr.getState() == IpAddress.State.Releasing) { // Cleanup all the resources for ip address if there are any, and only then un-assign ip in the // system if (cleanupIpResources(addr.getId(), Account.ACCOUNT_ID_SYSTEM, _accountMgr.getSystemAccount())) { + s_logger.debug("Unassiging ip address " + addr); _ipAddressDao.unassignIpAddress(addr.getId()); } else { success = false; @@ -690,7 +724,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag ipToServices.put(ip, services); // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service -// provider + // provider if (ip.getState() == State.Allocating) { continue; } @@ -704,9 +738,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } purposes.add(Purpose.StaticNat); } + //TODO Need to check site 2 site vpn ip assignment if (purposes == null || purposes.isEmpty()) { // since no active rules are there check if any rules are applied on the public IP but are in // revoking state + purposes = getPublicIpPurposeInRules(ip, true, includingFirewall); if (ip.isOneToOneNat()) { if (purposes == null) { @@ -884,7 +920,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return providerToIpList; } - protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List publicIps) throws ResourceUnavailableException { + protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, + List publicIps) throws ResourceUnavailableException { boolean success = true; Map> ipToServices = getIpToServices(publicIps, rulesRevoked, false); @@ -981,54 +1018,31 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true) - public IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { - return allocateIP(networkId, ipOwner, false); - } - - @DB - public IpAddress allocateIP(long networkId, Account ipOwner, boolean isSystem) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) + throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); - long userId = UserContext.current().getCallerUserId(); - - long ownerId = ipOwner.getId(); - Network network = _networksDao.findById(networkId); - if (network == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Network id is invalid"); - ex.addProxyObject("networks", networkId, "networkId"); - throw ex; - } + long callerUserId = UserContext.current().getCallerUserId(); // check permissions _accountMgr.checkAccess(caller, null, false, ipOwner); - _accountMgr.checkAccess(ipOwner, AccessType.UseNetwork, false, network); - DataCenter zone = _configMgr.getZone(network.getDataCenterId()); + DataCenter zone = _configMgr.getZone(zoneId); - // allow associating IP addresses to guest network only - if (network.getTrafficType() != TrafficType.Guest) { - throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest); - } + return allocateIp(ipOwner, isSystem, caller, callerUserId, zone); + } - // In Advance zone only allow to do IP assoc for Isolated networks with source nat service enabled - if (zone.getNetworkType() == NetworkType.Advanced && !(network.getGuestType() == GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the " - + Service.SourceNat.getName() + " enabled"); - } - - // Check that network belongs to IP owner - skip this check for Basic zone as there is just one guest network, -// and it - // belongs to the system - if (zone.getNetworkType() != NetworkType.Basic && network.getAccountId() != ipOwner.getId()) { - throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP"); - } + @DB + public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) + throws ConcurrentOperationException, ResourceAllocationException, + InsufficientAddressCapacityException { VlanType vlanType = VlanType.VirtualNetwork; boolean assign = false; if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { // zone is of type DataCenter. See DataCenterVO.java. - PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled"); - ex.addProxyObject("data_center", zone.getId(), "zoneId"); + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, zone with specified id is currently disabled"); + ex.addProxyObject(zone, zone.getId(), "zoneId"); throw ex; } @@ -1038,11 +1052,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account accountToLock = null; try { if (s_logger.isDebugEnabled()) { - s_logger.debug("Associate IP address called for user " + userId + " account " + ownerId); + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); } - accountToLock = _accountDao.acquireInLockTable(ownerId); + accountToLock = _accountDao.acquireInLockTable(ipOwner.getId()); if (accountToLock == null) { - s_logger.warn("Unable to lock account: " + ownerId); + s_logger.warn("Unable to lock account: " + ipOwner.getId()); throw new ConcurrentOperationException("Unable to acquire account lock"); } @@ -1054,57 +1068,72 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // accountId will not be exceeded _resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip); - boolean isSourceNat = false; - txn.start(); - NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); - boolean sharedSourceNat = offering.getSharedSourceNat(); - - if (!sharedSourceNat) { - // First IP address should be source nat when it's being associated with Guest Virtual network - List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, zone.getId(), true, networkId); - - if (addrs.isEmpty() && network.getGuestType() == Network.GuestType.Isolated) { - isSourceNat = true; - } - } - - ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, network.getId(), isSourceNat, assign, null, isSystem); + ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, + false, assign, null, isSystem, null); if (ip == null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId()); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Unable to find available public IP addresses", DataCenter.class, zone.getId()); ex.addProxyObject("data_center", zone.getId(), "zoneId"); throw ex; } UserContext.current().setEventDetails("Ip Id: " + ip.getId()); Ip ipAddress = ip.getAddress(); - s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + network.getDataCenterId()); + s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); txn.commit(); } finally { if (accountToLock != null) { - _accountDao.releaseFromLockTable(ownerId); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock account " + ipOwner); + } + _accountDao.releaseFromLockTable(ipOwner.getId()); s_logger.debug("Associate IP address lock released"); } } - return ip; } - @Override - @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) - public IpAddress associateIP(long ipId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { - return associateIP(ipId, false); + + protected IPAddressVO getExistingSourceNat(long ownerId, Long networkId, Long vpcId) { + + List addrs = null; + if (vpcId != null) { + addrs = listPublicIpsAssignedToVpc(ownerId, true, vpcId); + } else if (networkId != null) { + addrs = listPublicIpsAssignedToGuestNtwk(ownerId, networkId, true); + } + + IPAddressVO sourceNatIp = null; + if (addrs.isEmpty()) { + return null; + } else { + // Account already has ip addresses + for (IPAddressVO addr : addrs) { + if (addr.isSourceNat()) { + sourceNatIp = addr; + return sourceNatIp; + } + } + + assert (sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + + "account=" + ownerId + "; networkId=" + networkId + "; vpcId=" + vpcId; + } + + return sourceNatIp; } @DB - private IpAddress associateIP(long ipId, boolean isSystem) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { + @Override + public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); Account owner = null; - IpAddress ipToAssoc = getIp(ipId); + IPAddressVO ipToAssoc = _ipAddressDao.findById(ipId); if (ipToAssoc != null) { _accountMgr.checkAccess(caller, null, true, ipToAssoc); owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId()); @@ -1113,16 +1142,68 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return null; } - Network network = _networksDao.findById(ipToAssoc.getAssociatedWithNetworkId()); + if (ipToAssoc.getAssociatedWithNetworkId() != null) { + s_logger.debug("IP " + ipToAssoc + " is already assocaited with network id" + networkId); + return ipToAssoc; + } + + Network network = _networksDao.findById(networkId); + if (network != null) { + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + } else { + s_logger.debug("Unable to find ip address by id: " + ipId); + return null; + } + + DataCenter zone = _configMgr.getZone(network.getDataCenterId()); + + // allow associating IP addresses to guest network only + if (network.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + + TrafficType.Guest); + } + + // Check that network belongs to IP owner - skip this check for Basic zone as there is just one guest network, + // and it belongs to the system + if (zone.getNetworkType() != NetworkType.Basic && network.getAccountId() != owner.getId()) { + throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP"); + } + + // In Advance zone only allow to do IP assoc for Isolated networks with source nat service enabled + if (zone.getNetworkType() == NetworkType.Advanced && + !(network.getGuestType() == GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), + Service.SourceNat))) { + throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + + " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the " + + Service.SourceNat.getName() + " enabled"); + } + + NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + boolean sharedSourceNat = offering.getSharedSourceNat(); + boolean isSourceNat = false; + if (!sharedSourceNat) { + if (getExistingSourceNat(owner.getId(), networkId, null) == null) { + if (network.getGuestType() == GuestType.Isolated && network.getVpcId() == null) { + isSourceNat = true; + } + } + } + + s_logger.debug("Associating ip " + ipToAssoc + " to network " + network); IPAddressVO ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setAssociatedWithNetworkId(networkId); + ip.setSourceNat(isSourceNat); + _ipAddressDao.update(ipId, ip); + boolean success = false; try { success = applyIpAssociations(network, false); if (success) { - s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " for account " + owner.getId() + " in zone " + network.getDataCenterId()); + s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network); } else { - s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " for account " + owner.getId() + " in zone " + network.getDataCenterId()); + s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network); } return ip; } catch (ResourceUnavailableException e) { @@ -1136,8 +1217,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _ipAddressDao.markAsUnavailable(ip.getId()); if (!applyIpAssociations(network, true)) { // if fail to apply ip assciations again, unassign ip address without updating resource -// count and - // generating usage event as there is no need to keep it in the db + // count and generating usage event as there is no need to keep it in the db _ipAddressDao.unassignIpAddress(ip.getId()); } } catch (Exception e) { @@ -1148,12 +1228,60 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + + @DB + protected IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException { + Account caller = UserContext.current().getCaller(); + Account owner = null; + + IpAddress ipToAssoc = getIp(ipId); + if (ipToAssoc != null) { + _accountMgr.checkAccess(caller, null, true, ipToAssoc); + owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId()); + } else { + s_logger.debug("Unable to find ip address by id: " + ipId); + return null; + } + + Vpc vpc = _vpcMgr.getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Invalid VPC id " + vpcId); + } + + // check permissions + _accountMgr.checkAccess(caller, null, true, owner, vpc); + + boolean isSourceNat = false; + if (getExistingSourceNat(owner.getId(), null, vpcId) == null) { + isSourceNat = true; + } + + s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + IPAddressVO ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setVpcId(vpcId); + ip.setSourceNat(isSourceNat); + _ipAddressDao.update(ipId, ip); + + //mark ip as allocated + markPublicIpAsAllocated(ip); + txn.commit(); + + s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc); + + return _ipAddressDao.findById(ipId); + } + + @Override @DB - public boolean releasePublicIpAddress(long addrId, long userId, Account caller) { + public boolean disassociatePublicIpAddress(long addrId, long userId, Account caller) { boolean success = true; - // Cleanup all ip address resources - PF/LB/Static nat rules if (!cleanupIpResources(addrId, userId, caller)) { success = false; @@ -1181,10 +1309,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } catch (ResourceUnavailableException e) { throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e); } + } else { + if (ip.getState() == IpAddress.State.Releasing) { + _ipAddressDao.unassignIpAddress(ip.getId()); + } } if (success) { - s_logger.debug("released a public ip id=" + addrId); + s_logger.debug("Released a public ip id=" + addrId); } return success; @@ -1217,6 +1349,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, true); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); _systemNetworks.put(NetworkOfferingVO.SystemStorageNetwork, storageNetworkOffering); + NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, + GuestType.Isolated); + privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); + _systemNetworks.put(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering); + _privateOfferingId = privateGatewayNetworkOffering.getId(); + // populate providers Map> defaultSharedNetworkOfferingProviders = new HashMap>(); @@ -1237,7 +1375,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sgProviders.add(Provider.SecurityGroupProvider); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders); - Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap>(); + Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = + new HashMap>(); defaultProviders.clear(); defaultProviders.add(Network.Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); @@ -1257,29 +1396,56 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO offering = null; if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, - null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null, + true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, - null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, + defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + Map> defaultINetworkOfferingProvidersForVpcNetwork = new HashMap>(); + defaultProviders.clear(); + defaultProviders.add(Network.Provider.VPCVirtualRouter); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dhcp, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dns, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.UserData, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Firewall, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Gateway, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Lb, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.SourceNat, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.StaticNat, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.PortForwarding, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Vpn, defaultProviders); + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", - TrafficType.Guest, null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, + "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, + null, false, Availability.Required, null, defaultINetworkOfferingProvidersForVpcNetwork, + true, Network.GuestType.Isolated, false, null, true, null, false); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, + null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, + true, Network.GuestType.Isolated, false, null, false, null, false); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, - true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, + "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, + Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, + false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -1307,8 +1473,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag serviceCapabilityMap.put(Service.StaticNat, eip); if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, - true, Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, + Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true); offering.setState(NetworkOffering.State.Enabled); offering.setDedicatedLB(false); _networkOfferingDao.update(offering.getId(), offering); @@ -1348,6 +1514,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag IpAddressSearch = _ipAddressDao.createSearchBuilder(); IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ); IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ); + IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ); IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ); SearchBuilder virtualNetworkVlanSB = _vlanDao.createSearchBuilder(); virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ); @@ -1387,7 +1554,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Provider implementedProvider = element.getProvider(); if (implementedProvider != null) { if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) { - s_logger.error("Cannot start NetworkManager: Provider <-> NetworkElement must be a one-to-one map, multiple NetworkElements found for Provider: " + implementedProvider.getName()); + s_logger.error("Cannot start NetworkManager: Provider <-> NetworkElement must be a one-to-one map, " + + "multiple NetworkElements found for Provider: " + implementedProvider.getName()); return false; } s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName()); @@ -1419,13 +1587,37 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId) { + public List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) { + SearchCriteria sc = IpAddressSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("associatedWithNetworkId", associatedNetworkId); + + if (sourceNat != null) { + sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); + } + sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork); + + return _ipAddressDao.search(sc, null); + } + + @Override + public List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) { SearchCriteria sc = IpAddressSearch.create(); sc.setParameters("accountId", accountId); sc.setParameters("dataCenterId", dcId); - if (associatedNetworkId != null) { - sc.setParameters("associatedWithNetworkId", associatedNetworkId); + + if (sourceNat != null) { + sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); } + sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork); + + return _ipAddressDao.search(sc, null); + } + + protected List listPublicIpsAssignedToVpc(long accountId, Boolean sourceNat, long vpcId) { + SearchCriteria sc = IpAddressSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("vpcId", vpcId); if (sourceNat != null) { sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); @@ -1436,15 +1628,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) + public List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, + String displayText, boolean isDefault) throws ConcurrentOperationException { - return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null); + return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null, null); } @Override @DB - public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { + public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan + plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException { + Account locked = _accountDao.acquireInLockTable(owner.getId()); if (locked == null) { throw new ConcurrentOperationException("Unable to acquire lock on " + owner); @@ -1452,7 +1647,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag try { if (predefined == null - || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) { + || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null + && predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) { List configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId()); if (configs.size() > 0) { if (s_logger.isDebugEnabled()) { @@ -1460,7 +1656,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (errorIfAlreadySetup) { - throw new InvalidParameterValueException("Found existing network configuration for offering " + offering + ": " + configs.get(0)); + InvalidParameterValueException ex = new InvalidParameterValueException("Found existing network configuration (with specified id) for offering (with specified id)"); + ex.addProxyObject(offering, offering.getId(), "offeringId"); + ex.addProxyObject(configs.get(0), configs.get(0).getId(), "networkConfigId"); + throw ex; } else { return configs; } @@ -1474,7 +1673,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (errorIfAlreadySetup) { - throw new InvalidParameterValueException("Found existing network configuration for offering " + offering + ": " + configs.get(0)); + InvalidParameterValueException ex = new InvalidParameterValueException("Found existing network configuration (with specified id) for offering (with specified id)"); + ex.addProxyObject(offering, offering.getId(), "offeringId"); + ex.addProxyObject(configs.get(0), configs.get(0).getId(), "networkConfigId"); + throw ex; } else { return configs; } @@ -1508,9 +1710,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Transaction txn = Transaction.currentTxn(); txn.start(); - NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, predefined.getNetworkDomain(), - offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges()); - networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); + NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), + related, name, displayText, predefined.getNetworkDomain(), offering.getGuestType(), + plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId); + networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, + finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); if (domainId != null && aclType == ACLType.Domain) { _networksDao.addDomainToNetwork(id, domainId, subdomainAccess); @@ -1521,9 +1725,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (networks.size() < 1) { // see networkOfferingVO.java - CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering to network profile"); - ex.addProxyObject("network_offerings", offering.getId(), "networkOfferingId"); - throw ex; + CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering with specified id to network profile"); + ex.addProxyObject(offering, offering.getId(), "offeringId"); + throw ex; } return networks; @@ -1548,7 +1752,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public void allocate(VirtualMachineProfile vm, List> networks) throws InsufficientCapacityException, ConcurrentOperationException { + public void allocate(VirtualMachineProfile vm, List> networks) + throws InsufficientCapacityException, ConcurrentOperationException { Transaction txn = Transaction.currentTxn(); txn.start(); @@ -1557,63 +1762,53 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean[] deviceIds = new boolean[networks.size()]; Arrays.fill(deviceIds, false); - List nics = new ArrayList(networks.size()); - NicVO defaultNic = null; + List nics = new ArrayList(networks.size()); + NicProfile defaultNic = null; for (Pair network : networks) { NetworkVO config = network.first(); - NetworkGuru guru = _networkGurus.get(config.getGuruName()); NicProfile requested = network.second(); - if (requested != null && requested.getMode() == null) { - requested.setMode(config.getMode()); - } - NicProfile profile = guru.allocate(config, requested, vm); - if (vm != null && vm.getVirtualMachine().getType() == Type.User && (requested != null && requested.isDefaultNic())) { - profile.setDefaultNic(true); + Boolean isDefaultNic = false; + if (vm != null && (requested != null && requested.isDefaultNic())) { + isDefaultNic = true; } - if (profile == null) { - continue; - } - - if (requested != null && requested.getMode() == null) { - profile.setMode(requested.getMode()); - } else { - profile.setMode(config.getMode()); - } - - NicVO vo = new NicVO(guru.getName(), vm.getId(), config.getId(), vm.getType()); - while (deviceIds[deviceId] && deviceId < deviceIds.length) { deviceId++; } - deviceId = applyProfileToNic(vo, profile, deviceId); + Pair vmNicPair = allocateNic(requested, config, isDefaultNic, + deviceId, vm); - vo = _nicDao.persist(vo); - - if (vo.isDefaultNic()) { - if (defaultNic != null) { - throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vo); - } - defaultNic = vo; + NicProfile vmNic = vmNicPair.first(); + if (vmNic == null) { + continue; } - int devId = vo.getDeviceId(); + deviceId = vmNicPair.second(); + + int devId = vmNic.getDeviceId(); if (devId > deviceIds.length) { - throw new IllegalArgumentException("Device id for nic is too large: " + vo); + throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); } if (deviceIds[devId]) { - throw new IllegalArgumentException("Conflicting device id for two different nics: " + devId); + throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); } deviceIds[devId] = true; - nics.add(vo); - Integer networkRate = getNetworkRate(config.getId(), vm.getId()); - vm.addNic(new NicProfile(vo, network.first(), vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network.first()), getNetworkTag(vm.getHypervisorType(), - network.first()))); + if (vmNic.isDefaultNic()) { + if (defaultNic != null) { + throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + + defaultNic + "; nic 2 = " + vmNic); + } + defaultNic = vmNic; + } + + nics.add(vmNic); + vm.addNic(vmNic); + } if (nics.size() != networks.size()) { @@ -1628,6 +1823,49 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag txn.commit(); } + + @DB + @Override + public Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, + int deviceId, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException{ + + NetworkVO ntwkVO = _networksDao.findById(network.getId()); + s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network); + NetworkGuru guru = _networkGurus.get(ntwkVO.getGuruName()); + + if (requested != null && requested.getMode() == null) { + requested.setMode(network.getMode()); + } + NicProfile profile = guru.allocate(network, requested, vm); + if (isDefaultNic != null) { + profile.setDefaultNic(isDefaultNic); + } + + if (profile == null) { + return null; + } + + if (requested != null && requested.getMode() == null) { + profile.setMode(requested.getMode()); + } else { + profile.setMode(network.getMode()); + } + + NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType()); + + deviceId = applyProfileToNic(vo, profile, deviceId); + + vo = _nicDao.persist(vo); + + Integer networkRate = getNetworkRate(network.getId(), vm.getId()); + NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), + network)); + + return new Pair(vmNic, Integer.valueOf(deviceId)); + } + protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) { if (profile.getDeviceId() != null) { vo.setDeviceId(profile.getDeviceId()); @@ -1718,7 +1956,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, + public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { Transaction.currentTxn(); Pair implemented = new Pair(null, null); @@ -1775,25 +2014,45 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag shutdownNetwork(networkId, context, false); } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock for network id " + networkId); + } _networksDao.releaseFromLockTable(networkId); } } - private void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, NetworkVO network, NetworkOfferingVO offering) + private void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, + NetworkVO network, NetworkOfferingVO offering) throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException { // If this is a 1) guest virtual network 2) network has sourceNat service 3) network offering does not support a -// Shared source NAT rule, + // Shared source NAT rule, // associate a source NAT IP (if one isn't already associated with the network) boolean sharedSourceNat = offering.getSharedSourceNat(); - if (network.getGuestType() == Network.GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) && !sharedSourceNat) { - List ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); + if (network.getGuestType() == Network.GuestType.Isolated + && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) + && !sharedSourceNat) { + + List ips = null; + Vpc vpc = null; + if (network.getVpcId() != null) { + vpc = _vpcMgr.getVpc(network.getVpcId()); + ips = _ipAddressDao.listByAssociatedVpc(vpc.getId(), true); + } else { + ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); + } + if (ips.isEmpty()) { - s_logger.debug("Creating a source nat ip for " + network); + String target = vpc != null ? vpc.toString() : network.toString(); + s_logger.debug("Creating a source nat ip for " + target); Account owner = _accountMgr.getAccount(network.getAccountId()); - assignSourceNatIpAddress(owner, network, context.getCaller().getId()); + if (vpc != null) { + assignSourceNatIpAddressToVpc(owner, vpc); + } else { + assignSourceNatIpAddressToGuestNetwork(owner, network); + } } } @@ -1802,16 +2061,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkElement element : _networkElements) { if (providersToImplement.contains(element.getProvider())) { if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), "VirtualRouter")) { - // see NetworkVO.java. - CloudRuntimeException ex = new CloudRuntimeException("Service provider " + element.getProvider().getName() + "either doesn't exist or is not enabled in specified physical network id"); - ex.addProxyObject("networks", network.getPhysicalNetworkId(), "physicalNetworkId"); - throw ex; + // The physicalNetworkId will not get translated into a uuid by the reponse serializer, + // because the serializer would look up the NetworkVO class's table and retrieve the + // network id instead of the physical network id. + // So just throw this exception as is. We may need to TBD by changing the serializer. + throw new CloudRuntimeException("Service provider " + element.getProvider().getName() + "either doesn't exist or is not enabled in physical network id: " + network.getPhysicalNetworkId()); } if (s_logger.isDebugEnabled()) { s_logger.debug("Asking " + element.getName() + " to implemenet " + network); } if (!element.implement(network, offering, dest, context)) { - throw new CloudRuntimeException("Failed to implement provider " + element.getProvider().getName() + " for network " + network); + CloudRuntimeException ex = new CloudRuntimeException("Failed to implement provider " + element.getProvider().getName() + " for network with specified id"); + ex.addProxyObject(network, network.getId(), "networkId"); + throw ex; } } } @@ -1827,7 +2089,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - protected void prepareElement(NetworkElement element, NetworkVO network, NicProfile profile, VirtualMachineProfile vmProfile, + protected void prepareElement(NetworkElement element, NetworkVO network, + NicProfile profile, VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { element.prepare(network, profile, vmProfile, dest, context); @@ -1871,9 +2134,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vmProfile.getId()); // we have to implement default nics first - to ensure that default network elements start up first in multiple -// nics - // case) - // (need for setting DNS on Dhcp to domR's Ip4 address) + // nics case)(need for setting DNS on Dhcp to domR's Ip4 address) Collections.sort(nics, new Comparator() { @Override @@ -1887,9 +2148,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NicVO nic : nics) { Pair implemented = implementNetwork(nic.getNetworkId(), dest, context); - NetworkGuru guru = implemented.first(); + NetworkVO network = implemented.second(); + NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network); + vmProfile.addNic(profile); + } + } + + @Override + public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination + dest, ReservationContext context, long nicId, NetworkVO network) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, + ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + Integer networkRate = getNetworkRate(network.getId(), vmProfile.getId()); + NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NicVO nic = _nicDao.findById(nicId); + NicProfile profile = null; if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { nic.setState(Nic.State.Reserving); @@ -1902,7 +2177,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag URI isolationUri = nic.getIsolationUri(); - profile = new NicProfile(nic, network, broadcastUri, isolationUri, networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + profile = new NicProfile(nic, network, broadcastUri, isolationUri, + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); guru.reserve(profile, network, vmProfile, dest, context); nic.setIp4Address(profile.getIp4Address()); nic.setAddressFormat(profile.getFormat()); @@ -1921,7 +2197,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag updateNic(nic, network.getId(), 1); } else { - profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); guru.updateNicProfile(profile, network); nic.setState(Nic.State.Reserved); updateNic(nic, network.getId(), 1); @@ -1936,8 +2213,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag profile.setSecurityGroupEnabled(isSecurityGroupSupportedInNetwork(network)); guru.updateNicProfile(profile, network); - vmProfile.addNic(profile); - } + return profile; } @Override @@ -1948,7 +2224,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Integer networkRate = getNetworkRate(network.getId(), vm.getId()); NetworkGuru guru = _networkGurus.get(network.getGuruName()); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); guru.updateNicProfile(profile, network); vm.addNic(profile); } @@ -1960,13 +2237,49 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vmProfile.getId()); for (NicVO nic : nics) { NetworkVO network = _networksDao.findById(nic.getNetworkId()); + releaseNic(vmProfile, nic, network); + } + } + + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vmProfile.getId()); + releaseNic(vmProfile, nic, network); + + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + return profile; + } + + + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) + throws ConcurrentOperationException, ResourceUnavailableException { + NicVO nic = null; + if (broadcastUri != null) { + nic = _nicDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vmProfile.getId(), broadcastUri.toString()); + } else { + nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vmProfile.getId()); + } + releaseNic(vmProfile, nic, network); + + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + return profile; + } + + + protected void releaseNic(VirtualMachineProfile vmProfile, NicVO nic, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException { if (nic.getState() == Nic.State.Reserved || nic.getState() == Nic.State.Reserving) { Nic.State originalState = nic.getState(); if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { NetworkGuru guru = _networkGurus.get(network.getGuruName()); nic.setState(Nic.State.Releasing); _nicDao.update(nic.getId(), nic); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); if (guru.release(profile, vmProfile, nic.getReservationId())) { applyProfileToNicForRelease(nic, profile); nic.setState(Nic.State.Allocated); @@ -1992,7 +2305,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - } @Override public List getNics(long vmId) { @@ -2010,7 +2322,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Integer networkRate = getNetworkRate(network.getId(), vm.getId()); NetworkGuru guru = _networkGurus.get(network.getGuruName()); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); guru.updateNicProfile(profile, network); profiles.add(profile); } @@ -2018,19 +2331,31 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return profiles; } + @Override + public NicProfile getNicProfile(VirtualMachine vm, long networkId) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NetworkVO network = _networksDao.findById(networkId); + Integer networkRate = getNetworkRate(network.getId(), vm.getId()); + + NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + guru.updateNicProfile(profile, network); + + return profile; + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true) - public boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException { + public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException { Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); // Verify input parameters IPAddressVO ipVO = _ipAddressDao.findById(ipAddressId); if (ipVO == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find ip address by id"); - ex.addProxyObject("user_ip_address", ipAddressId, "ipAddressId"); - throw ex; + throw new InvalidParameterValueException("Unable to find ip address by id"); } if (ipVO.getAllocatedTime() == null) { @@ -2043,9 +2368,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountMgr.checkAccess(caller, null, true, ipVO); } - Network associatedNetwork = getNetwork(ipVO.getAssociatedWithNetworkId()); - - if (ipVO.isSourceNat() && areServicesSupportedInNetwork(associatedNetwork.getId(), Service.SourceNat)) { + if (ipVO.isSourceNat()) { throw new IllegalArgumentException("ip address is used for source nat purposes and can not be disassociated."); } @@ -2055,21 +2378,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } // Check for account wide pool. It will have an entry for account_vlan_map. - if (_accountVlanMapDao.findAccountVlanMap(ipVO.getAllocatedToAccountId(), ipVO.getVlanId()) != null) { + if (_accountVlanMapDao.findAccountVlanMap(ipVO.getAllocatedToAccountId(), ipVO.getVlanId()) != null) { //see IPaddressVO.java InvalidParameterValueException ex = new InvalidParameterValueException("Sepcified IP address uuid belongs to Account wide IP pool and cannot be disassociated"); - ex.addProxyObject("user_ip_address", ipAddressId, "ipAddressId"); - throw ex; + ex.addProxyObject(ipVO, ipVO.getId(), "systemIpAddrId"); + throw ex; } // don't allow releasing system ip address if (ipVO.getSystem()) { - throw new InvalidParameterValueException("Can't release system IP address " + ipVO); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't release system IP address with specified id"); + ex.addProxyObject(ipVO, ipVO.getId(), "systemIpAddrId"); + throw ex; } - boolean success = releasePublicIpAddress(ipAddressId, userId, caller); - if (success) { - Network guestNetwork = getNetwork(ipVO.getAssociatedWithNetworkId()); + boolean success = disassociatePublicIpAddress(ipAddressId, userId, caller); + + Long networkId = ipVO.getAssociatedWithNetworkId(); + if (success && networkId != null) { + Network guestNetwork = getNetwork(networkId); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); Long vmId = ipVO.getAssociatedWithVmId(); if (offering.getElasticIp() && vmId != null) { @@ -2103,9 +2430,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException { String mac = _networksDao.getNextAvailableMacAddress(networkId); if (mac == null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId); - ex.addProxyObject("networks", networkId, "networkId"); - throw ex; + throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId); } return mac; } @@ -2129,6 +2454,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return elements; } + @Override + public List getSite2SiteVpnElements() { + List elements = new ArrayList(); + for (NetworkElement element : _networkElements) { + if (element instanceof Site2SiteVpnServiceProvider) { + Site2SiteVpnServiceProvider e = (Site2SiteVpnServiceProvider) element; + elements.add(e); + } + } + + return elements; + } + @Override public void cleanupNics(VirtualMachineProfile vm) { if (s_logger.isDebugEnabled()) { @@ -2137,14 +2475,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vm.getId()); for (NicVO nic : nics) { + removeNic(vm, nic); + } + } + + @Override + public void removeNic(VirtualMachineProfile vm, Network network) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vm.getVirtualMachine().getId()); + removeNic(vm, nic); + } + + protected void removeNic(VirtualMachineProfile vm, NicVO nic) { nic.setState(Nic.State.Deallocating); _nicDao.update(nic.getId(), nic); NetworkVO network = _networksDao.findById(nic.getNetworkId()); - NicProfile profile = new NicProfile(nic, network, null, null, null, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, null, null, null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); NetworkGuru guru = _networkGurus.get(network.getGuruName()); guru.deallocate(network, profile, vm); _nicDao.remove(nic.getId()); - } + s_logger.debug("Removed nic id=" + nic.getId()); } @Override @@ -2187,20 +2537,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return; } - String currCidrAddress = getCidrAddress(cidr); - int currCidrSize = getCidrSize(cidr); - for (long networkId : networkToCidr.keySet()) { String ntwkCidr = networkToCidr.get(networkId); - String ntwkCidrAddress = getCidrAddress(ntwkCidr); - int ntwkCidrSize = getCidrSize(ntwkCidr); - - long cidrSizeToUse = currCidrSize < ntwkCidrSize ? currCidrSize : ntwkCidrSize; - - String ntwkCidrSubnet = NetUtils.getCidrSubNet(ntwkCidrAddress, cidrSizeToUse); - String cidrSubnet = NetUtils.getCidrSubNet(currCidrAddress, cidrSizeToUse); - - if (cidrSubnet.equals(ntwkCidrSubnet)) { + if (NetUtils.isNetworksOverlap(ntwkCidr, cidr)) { InvalidParameterValueException ex = new InvalidParameterValueException("Warning: The specified existing network has conflict CIDR subnets with new network!"); ex.addProxyObject("networks", networkId, "networkId"); throw ex; @@ -2211,7 +2550,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network") - public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { + public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { Long networkOfferingId = cmd.getNetworkOfferingId(); String gateway = cmd.getGateway(); String startIP = cmd.getStartIp(); @@ -2221,7 +2560,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String vlanId = cmd.getVlan(); String name = cmd.getNetworkName(); String displayText = cmd.getDisplayText(); - Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); Long physicalNetworkId = cmd.getPhysicalNetworkId(); Long zoneId = cmd.getZoneId(); @@ -2229,12 +2567,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Long domainId = cmd.getDomainId(); boolean isDomainSpecific = false; Boolean subdomainAccess = cmd.getSubdomainAccess(); + Long vpcId = cmd.getVpcId(); // Validate network offering NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); if (ntwkOff == null || ntwkOff.isSystemOnly()) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering by specified id"); - ex.addProxyObject("network_offerings", networkOfferingId, "networkOfferingId"); + if (ntwkOff != null) { + ex.addProxyObject(ntwkOff, networkOfferingId, "networkOfferingId"); + throw ex; + } throw ex; } // validate physical network and zone @@ -2243,9 +2585,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (physicalNetworkId != null) { pNtwk = _physicalNetworkDao.findById(physicalNetworkId); if (pNtwk == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network having the given id"); - ex.addProxyObject("physical_network", physicalNetworkId, "physicalNetworkId"); - throw ex; + throw new InvalidParameterValueException("Unable to find a physical network having the specified physical network id"); } } @@ -2254,11 +2594,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } DataCenter zone = _dcDao.findById(zoneId); + if (zone == null) { + throw new InvalidParameterValueException("Specified zone id was not found"); + } + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { // See DataCenterVO.java PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled"); - ex.addProxyObject("data_center", zone.getId(), "zoneId"); - throw ex; + ex.addProxyObject(zone, zoneId, "zoneId"); + throw ex; + } + + //validate vpc + if (vpcId != null) { + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC "); + ex.addProxyObject("vpc", vpcId, "VPC"); + throw ex; + } + _accountMgr.checkAccess(caller, null, false, vpc); } // Only domain and account ACL types are supported in Acton. @@ -2278,7 +2633,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } else if (ntwkOff.getGuestType() == GuestType.Shared) { if (!(aclType == ACLType.Domain || aclType == ACLType.Account)) { - throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + ACLType.Account + " for network of type " + Network.GuestType.Shared); + throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + + ACLType.Account + " for network of type " + Network.GuestType.Shared); } } } else { @@ -2308,15 +2664,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (domainId != null) { if (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Shared) { - throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + TrafficType.Guest + " and guest type " + Network.GuestType.Shared); + throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + + TrafficType.Guest + " and guest type " + Network.GuestType.Shared); } DomainVO domain = _domainDao.findById(domainId); - if (domain == null) { - // see DomainVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain by specified if"); - ex.addProxyObject("domain", domainId, "domainId"); - throw ex; + if (domain == null) { + throw new InvalidParameterValueException("Unable to find domain by specified id"); } _accountMgr.checkAccess(caller, domain); } @@ -2369,7 +2723,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated && areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("Regular user can create a network only from the network offering having traffic type " + TrafficType.Guest + " and network type " + throw new InvalidParameterValueException("Regular user can create a network only from the network" + + " offering having traffic type " + TrafficType.Guest + " and network type " + Network.GuestType.Isolated + " with a service " + Service.SourceNat.getName() + " enabled"); } @@ -2393,19 +2748,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external devices!"); } - if (cidr != null) { - checkVirtualNetworkCidrOverlap(zoneId, cidr); - } // Vlan is created in 2 cases - works in Advance zone only: // 1) GuestType is Shared // 2) GuestType is Isolated, but SourceNat service is disabled boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced && ((ntwkOff.getGuestType() == Network.GuestType.Shared) - || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)))); + || (ntwkOff.getGuestType() == GuestType.Isolated && + !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)))); // Can add vlan range only to the network which allows it if (createVlan && !ntwkOff.getSpecifyIpRanges()) { - throw new InvalidParameterValueException("Network offering " + ntwkOff + " doesn't support adding multiple ip ranges"); + InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id doesn't support adding multiple ip ranges"); + ex.addProxyObject(ntwkOff, ntwkOff.getId(), "networkOfferingId"); + throw ex; } Transaction txn = Transaction.currentTxn(); @@ -2426,11 +2781,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); } - Network network = createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, false, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess); + //Create guest network + Network network = null; + if (vpcId != null) { + network = createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + } else { + network = createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + } if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { // Create vlan ip range - _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId, null); + _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, + false, null, startIP, endIP, gateway, netmask, vlanId, null); } txn.commit(); @@ -2438,10 +2802,33 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return network; } + @DB + protected Network createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway, + String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, long vpcId) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + //1) Validate if network can be created for VPC + _vpcMgr.validateGuestNtkwForVpc(_configMgr.getNetworkOffering(ntwkOffId), cidr, networkDomain, owner, vpc); + + if (networkDomain == null) { + networkDomain = vpc.getNetworkDomain(); + } + + //2) Create network + Network guestNetwork = createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + + return guestNetwork; + } + @Override @DB - public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, - Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, + String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); // this method supports only guest network creation @@ -2460,14 +2847,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (ntwkOff.getState() != NetworkOffering.State.Enabled) { // see NetworkOfferingVO InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled); - ex.addProxyObject("network_offerings", networkOfferingId, "networkOfferingId"); - throw ex; + ex.addProxyObject(ntwkOff, ntwkOff.getId(), "networkOfferingId"); + throw ex; } // Validate physical network if (pNtwk.getState() != PhysicalNetwork.State.Enabled) { // see PhysicalNetworkVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is in incorrect state:" + pNtwk.getState()); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + + " in incorrect state:" + pNtwk.getState()); ex.addProxyObject("physical_network", pNtwk.getId(), "physicalNetworkId"); throw ex; } @@ -2483,12 +2871,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Only one guest network is supported in Basic zone List guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest); if (!guestNetworks.isEmpty()) { - throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic); + throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + + NetworkType.Basic); } // if zone is basic, only Shared network offerings w/o source nat service are allowed - if (!(ntwkOff.getGuestType() == GuestType.Shared && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + if (!(ntwkOff.getGuestType() == GuestType.Shared && + !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { + throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + + "guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + " service are allowed"); } @@ -2499,14 +2890,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (subdomainAccess == null) { subdomainAccess = true; } else if (!subdomainAccess) { - throw new InvalidParameterValueException("Subdomain access should be set to true for the guest network in the Basic zone"); + throw new InvalidParameterValueException("Subdomain access should be set to true for the" + + " guest network in the Basic zone"); } if (vlanId == null) { vlanId = Vlan.UNTAGGED; } else { if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in the zone of type " + NetworkType.Basic); + throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + + "the zone of type " + NetworkType.Basic); } } @@ -2514,9 +2907,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (zone.isSecurityGroupEnabled()) { // Only Account specific Isolated network with sourceNat service disabled are allowed in security group // enabled zone - boolean allowCreation = (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)); + boolean allowCreation = (ntwkOff.getGuestType() == GuestType.Isolated + && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)); if (!allowCreation) { - throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat service disabled are allowed in security group enabled zone"); + throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat " + + "service disabled are allowed in security group enabled zone"); } } } @@ -2531,21 +2926,31 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - // Don't allow to create network with vlan that already exists in the system if (vlanId != null) { String uri = "vlan://" + vlanId; - List networks = _networksDao.listBy(zoneId, uri); - if ((networks != null && !networks.isEmpty())) { - throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); + // For Isolated networks, don't allow to create network with vlan that already exists in the zone + if (ntwkOff.getGuestType() == GuestType.Isolated) { + if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { + throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); + } + } else { + //don't allow to create Shared network with Vlan that already exists in the zone for Isolated networks + if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0) { + throw new InvalidParameterValueException("Isolated network with vlan " + vlanId + " already exists " + + "in zone " + zoneId); + } } } + // If networkDomain is not specified, take it from the global configuration if (areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) { - Map dnsCapabilities = getNetworkOfferingServiceCapabilities(_configMgr.getNetworkOffering(networkOfferingId), Service.Dns); + Map dnsCapabilities = getNetworkOfferingServiceCapabilities + (_configMgr.getNetworkOffering(networkOfferingId), Service.Dns); String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification); if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) { if (networkDomain != null) { - throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId); + throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + + networkOfferingId + " in zone id=" + zoneId); } } else { if (networkDomain == null) { @@ -2565,7 +2970,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // validate network domain if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( - "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'); can't start or end with \"-\""); } } @@ -2576,9 +2982,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // limitation, remove after we introduce support for multiple ip ranges // with different Cidrs for the same Shared network boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced && ntwkOff.getTrafficType() == TrafficType.Guest - && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))); + && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated + && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))); if (cidr == null && cidrRequired) { - throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " + throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of" + + " type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled"); } @@ -2619,13 +3027,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccess); + List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, + aclType, subdomainAccess, vpcId); Network network = null; if (networks == null || networks.isEmpty()) { throw new CloudRuntimeException("Fail to create a network"); } else { - if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) { + if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && + networks.get(0).getTrafficType() == TrafficType.Guest) { Network defaultGuestNetwork = networks.get(0); for (Network nw : networks) { if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) { @@ -2669,6 +3079,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean listAll = cmd.listAll(); boolean isRecursive = cmd.isRecursive(); Boolean specifyIpRanges = cmd.getSpecifyIpRanges(); + Long vpcId = cmd.getVpcId(); + Boolean canUseForDeploy = cmd.canUseForDeploy(); // 1) default is system to false if not specified // 2) reset parameter to false if it's specified by the regular user @@ -2685,9 +3097,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag DomainVO domain = _domainDao.findById(domainId); if (domain == null) { // see DomainVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Specified domain id doesn't exist in the system"); - ex.addProxyObject("domain", domainId, "domainId"); - throw ex; + throw new InvalidParameterValueException("Specified domain id doesn't exist in the system"); } _accountMgr.checkAccess(caller, domain); @@ -2695,9 +3105,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account owner = _accountMgr.getActiveAccountByName(accountName, domainId); if (owner == null) { // see DomainVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain"); - ex.addProxyObject("domain", domainId, "domainId"); - throw ex; + throw new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain"); } _accountMgr.checkAccess(caller, null, true, owner); @@ -2722,17 +3130,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { permittedAccounts.clear(); Project project = _projectMgr.getProject(projectId); - if (project == null) { - // see ProjectVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by specified id"); - ex.addProxyObject("projects", projectId, "projectId"); - throw ex; + if (project == null) { + throw new InvalidParameterValueException("Unable to find project by specified id"); } if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) { - // see ProjectVO.java + // getProject() returns type ProjectVO. InvalidParameterValueException ex = new InvalidParameterValueException("Account " + caller + " cannot access specified project id"); - ex.addProxyObject("projects", projectId, "projectId"); - throw ex; + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } permittedAccounts.add(project.getProjectAccountId()); } @@ -2779,21 +3184,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (domainId != null) { networksToReturn .addAll(listDomainLevelNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, domainId)); } if (!permittedAccounts.isEmpty()) { networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, permittedAccounts)); } else if (domainId == null || listAll) { networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, path, isRecursive)); } } else { - networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges), + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter); } @@ -2817,14 +3226,41 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - return supportedNetworks; - } else { - return networksToReturn; + networksToReturn=supportedNetworks; } + + if (canUseForDeploy != null) { + List networksForDeploy = new ArrayList(); + for (NetworkVO network : networksToReturn) { + if (canUseForDeploy(network) == canUseForDeploy) { + networksForDeploy.add(network); + } + } + + networksToReturn=networksForDeploy; + } + + return networksToReturn; } - private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges) { + @Override + public boolean canUseForDeploy(Network network) { + if (network.getTrafficType() != TrafficType.Guest) { + return false; + } + boolean hasFreeIps = true; + if (network.getGuestType() == GuestType.Shared) { + hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0; + } else { + hasFreeIps = (getAvailableIps(network, null)).size() > 0; + } + + return hasFreeIps; + } + + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId) { SearchCriteria sc = sb.create(); if (isSystem != null) { @@ -2873,6 +3309,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges); } + if (vpcId != null) { + sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); + } + return sc; } @@ -2938,12 +3378,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (network == null) { // see NetworkVO.java - throw new InvalidParameterValueException("unable to find network " + networkId); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find network with specified id"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } // don't allow to delete system network if (isNetworkSystem(network)) { - throw new InvalidParameterValueException("Network " + network + " is system and can't be removed"); + InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id is system and can't be removed"); + ex.addProxyObject(network, network.getId(), "networkId"); + throw ex; } Account owner = _accountMgr.getAccount(network.getAccountId()); @@ -2962,8 +3406,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) { boolean result = false; - Transaction txn = Transaction.currentTxn(); - txn.start(); NetworkVO network = _networksDao.lockRow(networkId, true); if (network == null) { s_logger.debug("Unable to find network with id: " + networkId); @@ -2976,10 +3418,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag network.setState(Network.State.Shutdown); _networksDao.update(network.getId(), network); - txn.commit(); boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network); + Transaction txn = Transaction.currentTxn(); txn.start(); if (success) { if (s_logger.isDebugEnabled()) { @@ -3007,7 +3449,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, NetworkVO network) { // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down -// the elements + // the elements boolean cleanupResult = true; try { cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId()); @@ -3164,15 +3606,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } - private boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) { - List vlans = _vlanDao.listVlansByNetworkId(networkId); + protected boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) { + + //cleanup Public vlans + List publicVlans = _vlanDao.listVlansByNetworkId(networkId); boolean result = true; - for (VlanVO vlan : vlans) { + for (VlanVO vlan : publicVlans) { if (!_configMgr.deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), vlan.getId(), callerAccount)) { s_logger.warn("Failed to delete vlan " + vlan.getId() + ");"); result = false; } } + + //cleanup private vlans + int privateIpAllocCount = _privateIpDao.countAllocatedByNetworkId(networkId); + if (privateIpAllocCount > 0) { + s_logger.warn("Can't delete Private ip range for network " + networkId + " as it has allocated ip addresses"); + result = false; + } else { + _privateIpDao.deleteByNetworkId(networkId); + s_logger.debug("Deleted ip range for private network id=" + networkId); + } return result; } @@ -3261,6 +3715,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } handled = ((FirewallServiceProvider) ne).applyFWRules(network, rules); break; + case NetworkACL: + boolean isNetworkACLProvider = isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider); + if (!(ne instanceof NetworkACLServiceProvider && isNetworkACLProvider)) { + continue; + } + handled = ((NetworkACLServiceProvider) ne).applyNetworkACLs(network, rules); + break; default: s_logger.debug("Unable to handle network rules for purpose: " + purpose.toString()); handled = false; @@ -3383,7 +3844,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Check if network exists NetworkVO network = _networksDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Network with id=" + networkId + " doesn't exist"); + InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id doesn't exist"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } // implement the network @@ -3496,6 +3959,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } + + //apply network ACLs + if (!_networkACLMgr.applyNetworkACLs(networkId, caller)) { + s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart"); + success = false; + } + return success; } @@ -3530,6 +4000,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public Map getNetworkServiceCapabilities(long networkId, Service service) { if (!areServicesSupportedInNetwork(networkId, service)) { + // TBD: networkId to uuid. No VO object being passed. So we will need to call + // addProxyObject with hardcoded tablename. Or we should probably look up the correct dao proxy object. throw new UnsupportedServiceException("Service " + service.getName() + " is not supported in the network id=" + networkId); } @@ -3556,6 +4028,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) { if (!areServicesSupportedByNetworkOffering(offering.getId(), service)) { + // TBD: We should be sending networkOfferingId and not the offering object itself. throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the network offering " + offering); } @@ -3564,21 +4037,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // get the Provider for this Service for this offering List providers = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), service); if (providers.isEmpty()) { + // TBD: We should be sending networkOfferingId and not the offering object itself. throw new InvalidParameterValueException("Service " + service.getName() + " is not supported by the network offering " + offering); } // FIXME - in post 3.0 we are going to support multiple providers for the same service per network offering, so -// we have to calculate capabilities for all of them + // we have to calculate capabilities for all of them String provider = providers.get(0); // FIXME we return the capabilities of the first provider of the service - what if we have multiple providers -// for same Service? + // for same Service? NetworkElement element = getElementImplementingProvider(provider); if (element != null) { Map> elementCapabilities = element.getCapabilities(); ; if (elementCapabilities == null || !elementCapabilities.containsKey(service)) { + // TBD: We should be sending providerId and not the offering object itself. throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() + " implementing Provider=" + provider); } serviceCapabilities = elementCapabilities.get(service); @@ -3605,6 +4080,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); if (networks == null || networks.isEmpty()) { + // TBD: send uuid instead of zoneId. Hardcode tablename in call to addProxyObject(). throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); } return networks.get(0); @@ -3665,14 +4141,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public String getIpInNetwork(long vmId, long networkId) { Nic guestNic = getNicInNetwork(vmId, networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null"; + assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + + "ipAddress or ip4 address is null"; return guestNic.getIp4Address(); } @Override public String getIpInNetworkIncludingRemoved(long vmId, long networkId) { Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null"; + assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + + "ipAddress or ip4 address is null"; return guestNic.getIp4Address(); } @@ -3701,8 +4179,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag createNetwork = true; } else if (networks.size() == 1) { guestNetwork = networks.get(0); - }else{ - throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); + } else { + throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " + + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); } } @@ -3710,20 +4189,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (createNetwork) { List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (requiredOfferings.size() < 1) { - throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as part of createVlanIpRange"); + throw new CloudRuntimeException("Unable to find network offering with availability=" + + Availability.Required + " to automatically create the network as part of createVlanIpRange"); } PhysicalNetwork physicalNetwork = translateZoneIdToPhysicalNetwork(zoneId); if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { - s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of createVlanIpRange process"); - guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, null, null, owner, false, null, physicalNetwork, zoneId, - ACLType.Account, null); + s_logger.debug("Creating network for account " + owner + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of createVlanIpRange process"); + guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network" + , owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork, + zoneId, ACLType.Account, + null, null); if (guestNetwork == null) { s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); - throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); + throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); } } else { - throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + + " is not in " + NetworkOffering.State.Enabled); } } @@ -3746,6 +4231,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag addr.setSourceNat(false); } addr.setAssociatedWithNetworkId(guestNetwork.getId()); + addr.setVpcId(guestNetwork.getVpcId()); addr.setAllocatedTime(new Date()); addr.setAllocatedInDomainId(owner.getDomainId()); addr.setAllocatedToAccountId(owner.getId()); @@ -3989,7 +4475,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String guestType = vlan.getVlanType().toString(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(), guestType, ip.getSystem()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, + ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), + ip.isSourceNat(), guestType, ip.getSystem()); _usageEventDao.persist(usageEvent); } @@ -4059,8 +4547,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkVO network = _networksDao.findById(networkId); if (network == null) { // see NetworkVO.java - //throw new InvalidParameterValueException("Network id=" + networkId + "doesn't exist in the system"); - InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system"); ex.addProxyObject("networks", networkId, "networkId"); throw ex; } @@ -4103,12 +4590,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId); if (networkOffering == null || networkOffering.isSystemOnly()) { - throw new InvalidParameterValueException("Unable to find network offering by id " + networkOfferingId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering with specified id"); + ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); + throw ex; } // network offering should be in Enabled state if (networkOffering.getState() != NetworkOffering.State.Enabled) { - throw new InvalidParameterValueException("Network offering " + networkOffering + " is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it"); + InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it"); + ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId"); + throw ex; } if (networkOfferingId != oldNetworkOfferingId) { @@ -4118,7 +4609,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (changeCidr) { if (!checkForNonStoppedVmInNetwork(network.getId())) { - throw new InvalidParameterValueException("All user vm of network: " + network + " should be stopped before changing CIDR!"); + InvalidParameterValueException ex = new InvalidParameterValueException("All user vm of network of specified id should be stopped before changing CIDR!"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } } // check if the network is upgradable @@ -4151,6 +4644,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Map dnsCapabilities = getNetworkOfferingServiceCapabilities(_configMgr.getNetworkOffering(offeringId), Service.Dns); String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification); if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) { + // TBD: use uuid instead of networkOfferingId. May need to hardcode tablename in call to addProxyObject(). throw new InvalidParameterValueException("Domain name change is not supported by the network offering id=" + networkOfferingId); } @@ -4170,19 +4664,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!shutdownNetworkElementsAndResources(context, true, network)) { s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network); - throw new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of network update: " + network); + CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } } else { // We need to shutdown the network, since we want to re-implement the network. s_logger.debug("Shutting down network id=" + networkId + " as a part of network update"); if (!shutdownNetwork(network.getId(), context, true)) { - s_logger.warn("Failed to shutdown the network as a part of network update: " + network); - throw new CloudRuntimeException("Failed to shutdown the network as a part of network update: " + network); + s_logger.warn("Failed to shutdown the network as a part of update to network with specified id"); + CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } } } else { - throw new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of network update: " + network + "; network is in wrong state: " + network.getState()); + CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState()); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } } @@ -4191,7 +4691,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Network.State networkState = _networksDao.findById(networkId).getState(); boolean validStateToImplement = (networkState == Network.State.Implemented || networkState == Network.State.Setup || networkState == Network.State.Allocated); if (restartNetwork && !validStateToImplement) { - throw new CloudRuntimeException("Failed to implement the network elements and resources as a part of network update: " + network + "; network is in wrong state: " + networkState); + CloudRuntimeException ex = new CloudRuntimeException("Failed to implement the network elements and resources as a part of update to network with specified id; network is in wrong state: " + networkState); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } if (networkOfferingId != null) { @@ -4239,7 +4741,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } catch (Exception ex) { s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex); - throw new CloudRuntimeException("Failed to implement network " + network + " elements and resources as a part of network update"); + CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update"); + e.addProxyObject(network, networkId, "networkId"); + throw e; } } } @@ -4280,36 +4784,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public String acquireGuestIpAddress(Network network, String requestedIp) { - List ips = _nicDao.listIpAddressInNetwork(network.getId()); - String[] cidr = network.getCidr().split("/"); - Set allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1])); - Set usedIps = new TreeSet(); - + public String acquireGuestIpAddress(Network network, String requestedIp) { if (requestedIp != null && requestedIp.equals(network.getGateway())) { s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network); return null; } - for (String ip : ips) { - if (requestedIp != null && requestedIp.equals(ip)) { - s_logger.warn("Requested ip address " + requestedIp + " is already in use in network " + network); - return null; - } - - usedIps.add(NetUtils.ip2Long(ip)); - } - if (usedIps.size() != 0) { - allPossibleIps.removeAll(usedIps); - } - if (allPossibleIps.isEmpty()) { + Set availableIps = getAvailableIps(network, requestedIp); + + if (availableIps.isEmpty()) { return null; } - Long[] array = allPossibleIps.toArray(new Long[allPossibleIps.size()]); + Long[] array = availableIps.toArray(new Long[availableIps.size()]); if (requestedIp != null) { // check that requested ip has the same cidr + String[] cidr = network.getCidr().split("/"); boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1])); if (!isSameCidr) { s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr"); @@ -4326,6 +4817,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return result; } + protected Set getAvailableIps(Network network, String requestedIp) { + String[] cidr = network.getCidr().split("/"); + List ips = _nicDao.listIpAddressInNetwork(network.getId()); + Set allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1])); + Set usedIps = new TreeSet(); + + for (String ip : ips) { + if (requestedIp != null && requestedIp.equals(ip)) { + s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network); + return null; + } + + usedIps.add(NetUtils.ip2Long(ip)); + } + if (usedIps.size() != 0) { + allPossibleIps.removeAll(usedIps); + } + return allPossibleIps; + } + + private String getZoneNetworkDomain(long zoneId) { return _dcDao.findById(zoneId).getDomain(); } @@ -4339,7 +4851,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networkDomain; } - private String getAccountNetworkDomain(long accountId, long zoneId) { + @Override + public String getAccountNetworkDomain(long accountId, long zoneId) { String networkDomain = _accountDao.findById(accountId).getNetworkDomain(); if (networkDomain == null) { @@ -4398,8 +4911,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } // static NAT rules can not programmed unless IP is associated with network service provider, so run IP -// association for - // the network so as to ensure IP is associated before applying rules (in add state) + // association for the network so as to ensure IP is associated before applying rules (in add state) applyIpAssociations(network, false, continueOnError, publicIps); // get provider @@ -4615,7 +5127,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true) - public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { + public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List + isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { // Check if zone exists if (zoneId == null) { @@ -4628,6 +5141,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (Grouping.AllocationState.Enabled == zone.getAllocationState()) { + // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject(). throw new PermissionDeniedException("Cannot create PhysicalNetwork since the Zone is currently enabled, zone Id: " + zoneId); } @@ -4635,6 +5149,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (zoneType == NetworkType.Basic) { if (!_physicalNetworkDao.listByZone(zoneId).isEmpty()) { + // TBD: Send uuid instead of zoneId; may have to hardcode tablename in call to addProxyObject(). throw new CloudRuntimeException("Cannot add the physical network to basic zone id: " + zoneId + ", there is a physical network already existing in this basic Zone"); } } @@ -4718,6 +5233,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // add security group provider to the physical network addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId()); + // add VPCVirtualRouter as the defualt network service provider + addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId()); + txn.commit(); return pNetwork; } catch (Exception ex) { @@ -4754,13 +5272,17 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // verify input parameters PhysicalNetworkVO network = _physicalNetworkDao.findById(id); if (network == null) { - throw new InvalidParameterValueException("Physical Network id=" + id + "doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); + ex.addProxyObject(network, id, "physicalNetworkId"); + throw ex; } // if zone is of Basic type, don't allow to add vnet range DataCenter zone = _dcDao.findById(network.getDataCenterId()); if (zone == null) { - throw new InvalidParameterValueException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Zone with id=" + network.getDataCenterId() + " doesn't exist in the system"); + ex.addProxyObject(zone, network.getDataCenterId(), "dataCenterId"); + throw ex; } if (newVnetRangeString != null) { if (zone.getNetworkType() == NetworkType.Basic @@ -4892,7 +5414,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // verify input parameters PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId); if (pNetwork == null) { - throw new InvalidParameterValueException("Network id=" + physicalNetworkId + "doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); + ex.addProxyObject(pNetwork, physicalNetworkId, "physicalNetworkId"); + throw ex; } checkIfPhysicalNetworkIsDeletable(physicalNetworkId); @@ -5077,14 +5601,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // verify input parameters PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId); if (network == null) { - throw new InvalidParameterValueException("Physical Network id=" + physicalNetworkId + "doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); + ex.addProxyObject(network, physicalNetworkId, "physicalNetworkId"); + throw ex; } // verify input parameters if (destinationPhysicalNetworkId != null) { PhysicalNetworkVO destNetwork = _physicalNetworkDao.findById(destinationPhysicalNetworkId); if (destNetwork == null) { - throw new InvalidParameterValueException("Destination Physical Network id=" + destinationPhysicalNetworkId + "doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Destination Physical Network with specified id doesn't exist in the system"); + ex.addProxyObject(destNetwork, destinationPhysicalNetworkId, "destinationPhysicalNetworkId"); + throw ex; } } @@ -5096,6 +5624,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (_pNSPDao.findByServiceProvider(physicalNetworkId, providerName) != null) { + // TBD: send uuid instead of physicalNetworkId. throw new CloudRuntimeException("The '" + providerName + "' provider already exists on physical network : " + physicalNetworkId); } @@ -5387,7 +5916,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean success = true; Network network = getNetwork(networkId); - // remove all PF/Static Nat rules for the network + //remove all PF/Static Nat rules for the network try { if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, callerUserId, caller)) { s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId); @@ -5401,7 +5930,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex); } - // remove all LB rules for the network + //remove all LB rules for the network if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, callerUserId)) { s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId); } else { @@ -5410,7 +5939,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup"); } - // revoke all firewall rules for the network + //revoke all firewall rules for the network try { if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, callerUserId, caller)) { s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId); @@ -5423,13 +5952,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // shouldn't even come here as network is being cleaned up after all network elements are shutdown s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex); } + + //revoke all network ACLs for network + try { + if (_networkACLMgr.revokeAllNetworkACLsForNetwork(networkId, callerUserId, caller)) { + s_logger.debug("Successfully cleaned up NetworkACLs for network id=" + networkId); + } else { + success = false; + s_logger.warn("Failed to cleanup NetworkACLs as a part of network id=" + networkId + " cleanup"); + } + } catch (ResourceUnavailableException ex) { + success = false; + s_logger.warn("Failed to cleanup Network ACLs as a part of network id=" + networkId + + " cleanup due to resourceUnavailable ", ex); + } - // release all ip addresses + //release all ip addresses List ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null); for (IPAddressVO ipToRelease : ipsToRelease) { + if (ipToRelease.getVpcId() != null) { IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId()); assert (ip != null) : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable."; } + } try { if (!applyIpAssociations(network, true)) { @@ -5613,7 +6158,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new CloudRuntimeException("This physical network already supports the traffic type: " + trafficType); } // For Storage, Control, Management, Public check if the zone has any other physical network with this -// traffictype already present + // traffictype already present // If yes, we cant add these traffics to one more physical network in the zone. if (TrafficType.isSystemNetwork(trafficType) || TrafficType.Public.equals(trafficType) || TrafficType.Storage.equals(trafficType)) { @@ -5744,7 +6289,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public List listTrafficTypes(Long physicalNetworkId) { PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId); if (network == null) { - throw new InvalidParameterValueException("Physical Network id=" + physicalNetworkId + "doesn't exist in the system"); + InvalidParameterValueException ex = new InvalidParameterValueException("Physical Network with specified id doesn't exist in the system"); + ex.addProxyObject(network, physicalNetworkId, "physicalNetworkId"); + throw ex; } return _pNTrafficTypeDao.listBy(physicalNetworkId); @@ -5756,11 +6303,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType); if (networkList.isEmpty()) { - throw new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in zone id=" + zoneId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the default physical network with traffic=" + trafficType + " in the specified zone id"); + // Since we don't have a DataCenterVO object at our disposal, we just set the table name that the zoneId's corresponding uuid is looked up from, manually. + ex.addProxyObject("data_center", zoneId, "zoneId"); + throw ex; } if (networkList.size() > 1) { - throw new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType); + InvalidParameterValueException ex = new InvalidParameterValueException("More than one physical networks exist in zone id=" + zoneId + " with traffic type=" + trafficType); + ex.addProxyObject("data_center", zoneId, "zoneId"); + throw ex; } return networkList.get(0); @@ -6042,7 +6594,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { // locate physicalNetwork with supported traffic type // We can make this assumptions based on the fact that Public/Management/Control traffic types are -// supported only in one physical network in the zone in 3.0 + // supported only in one physical network in the zone in 3.0 for (PhysicalNetworkVO pNtwk : pNtwks) { if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), network.getTrafficType())) { physicalNetworkId = pNtwk.getId(); @@ -6069,8 +6621,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networks.get(0); } - @Override - public PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { + protected PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName(), null, null); // add instance of the provider @@ -6078,15 +6629,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (element == null) { throw new CloudRuntimeException("Unable to find the Network Element implementing the VirtualRouter Provider"); } - element.addElement(nsp.getId()); + element.addElement(nsp.getId(), VirtualRouterProviderType.VirtualRouter); return nsp; } - @Override - public PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { + protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) { - PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.SecurityGroupProvider.getName(), null, null); + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + Network.Provider.VPCVirtualRouter.getName(), null, null); + // add instance of the provider + VpcVirtualRouterElement element = (VpcVirtualRouterElement) getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()); + if (element == null) { + throw new CloudRuntimeException("Unable to find the Network Element implementing the VPCVirtualRouter Provider"); + } + element.addElement(nsp.getId(), VirtualRouterProviderType.VPCVirtualRouter); + + return nsp; + } + + protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { + + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + Network.Provider.SecurityGroupProvider.getName(), null, null); return nsp; } @@ -6111,7 +6676,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkOfferingServiceMapVO serviceMap : servicesMap) { if (svcProviders.containsKey(serviceMap.getService())) { // FIXME - right now we pick up the first provider from the list, need to add more logic based on -// provider load, etc + // provider load, etc continue; } @@ -6125,7 +6690,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // check that provider is supported if (checkPhysicalNetwork) { if (!_pNSPDao.isServiceProviderEnabled(physicalNetworkId, provider, service)) { - throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't support service " + service + " in physical network id=" + physicalNetworkId); + throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't " + + "support service " + service + " in physical network id=" + physicalNetworkId); } } @@ -6359,7 +6925,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException { + public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) + throws InsufficientAddressCapacityException { Network guestNetwork = getNetwork(networkId); NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); IpAddress ip = null; @@ -6368,9 +6935,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag try { s_logger.debug("Allocating system IP address for load balancer rule..."); // allocate ip - ip = allocateIP(networkId, owner, true); + ip = allocateIP(owner, true, guestNetwork.getDataCenterId()); // apply ip associations - ip = associateIP(ip.getId()); + ip = associateIP(ip.getId(), networkId, null); } catch (ResourceAllocationException ex) { throw new CloudRuntimeException("Failed to allocate system ip due to ", ex); } catch (ConcurrentOperationException ex) { @@ -6394,7 +6961,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (networkId != null) { if (ip.getSystem()) { UserContext ctx = UserContext.current(); - if (!releasePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { + if (!disassociatePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { s_logger.warn("Unable to release system ip address id=" + ip.getId()); success = false; } else { @@ -6491,11 +7058,64 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } catch (Exception ex) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Failed to retrieve the default label for guest traffic." + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to: " + ex.getMessage()); + s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + dcId + + " hypervisor: " + hypervisorType + " due to:" + ex.getMessage()); } } return null; } + + @Override + public List listNetworksByVpc(long vpcId) { + return _networksDao.listByVpc(vpcId); + } + + @Override + public String getDefaultNetworkDomain() { + return _networkDomain; + } + + @Override + public List getNtwkOffDistinctProviders(long networkId) { + List providerNames = _ntwkOfferingSrvcDao.getDistinctProviders(networkId); + List providers = new ArrayList(); + for (String providerName : providerNames) { + providers.add(Network.Provider.getProvider(providerName)); + } + + return providers; + } + + @Override + public boolean isVmPartOfNetwork(long vmId, long ntwkId) { + if (_nicDao.findNonReleasedByInstanceIdAndNetworkId(ntwkId, vmId) != null) { + return true; + } + return false; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) + public IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, + ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { + if (vpcId != null) { + return associateIPToVpc(ipId, vpcId); + } + + if (networkId != null) { + Network network = _networksDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Invalid network id is given"); + } + + if (network.getVpcId() != null) { + throw new InvalidParameterValueException("Specify vpcId to associate ip address to VPC"); + } + return associateIPToGuestNetwork(ipId, networkId); + } + + return null; + } private PhysicalNetwork getOnePhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) { List networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType); @@ -6512,4 +7132,133 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networkList.get(0); } + + @Override + public void unassignIPFromVpcNetwork(long ipId) { + IPAddressVO ip = _ipAddressDao.findById(ipId); + Long vpcId = ip.getVpcId(); + + if (vpcId == null) { + return; + } + + ip.setAssociatedWithNetworkId(null); + _ipAddressDao.update(ipId, ip); + s_logger.debug("IP address " + ip + " is no longer associated with the network inside vpc id=" + vpcId); + } + + @Override @DB + public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, + String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + + Account owner = _accountMgr.getAccount(networkOwnerId); + + // Get system network offeirng + NetworkOfferingVO ntwkOff = _systemNetworks.get(NetworkOffering.SystemPrivateGatewayNetworkOffering); + + // Validate physical network + PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId); + if (pNtwk == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network" + + " having the given id"); + ex.addProxyObject("physical_network", physicalNetworkId, "physicalNetworkId"); + throw ex; + } + + // VALIDATE IP INFO + // if end ip is not specified, default it to startIp + if (!NetUtils.isValidIp(startIp)) { + throw new InvalidParameterValueException("Invalid format for the startIp parameter"); + } + if (endIp == null) { + endIp = startIp; + } else if (!NetUtils.isValidIp(endIp)) { + throw new InvalidParameterValueException("Invalid format for the endIp parameter"); + } + + String cidr = null; + if (!NetUtils.isValidIp(gateway)) { + throw new InvalidParameterValueException("Invalid gateway"); + } + if (!NetUtils.isValidNetmask(netmask)) { + throw new InvalidParameterValueException("Invalid netmask"); + } + + cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + //lock datacenter as we need to get mac address seq from there + DataCenterVO dc = _dcDao.lockRow(pNtwk.getDataCenterId(), true); + + //check if we need to create guest network + Network privateNetwork = _networksDao.getPrivateNetwork(BroadcastDomainType.Vlan.toUri(vlan).toString(), cidr, + networkOwnerId, pNtwk.getDataCenterId()); + if (privateNetwork == null) { + //create Guest network + privateNetwork = createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan, + null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null); + s_logger.debug("Created private network " + privateNetwork); + } else { + s_logger.debug("Private network already exists: " + privateNetwork); + } + + //add entry to private_ip_address table + PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNetwork.getId(), startIp); + if (privateIp != null) { + throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + + " in zone " + _configMgr.getZone(pNtwk.getDataCenterId()).getName()); + } + + Long mac = dc.getMacAddress(); + Long nextMac = mac + 1; + dc.setMacAddress(nextMac); + + privateIp = new PrivateIpVO(startIp, privateNetwork.getId(), nextMac); + _privateIpDao.persist(privateIp); + + _dcDao.update(dc.getId(), dc); + + txn.commit(); + s_logger.debug("Private network " + privateNetwork + " is created"); + + return privateNetwork; + } + + @Override + public boolean setupDns(Network network, Provider provider) { + boolean dnsProvided = isProviderSupportServiceInNetwork(network.getId(), Service.Dns, provider ); + boolean dhcpProvided =isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, + provider); + + boolean setupDns = dnsProvided || dhcpProvided; + return setupDns; + } + + @Override + public List getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) { + + List pNtwks = _physicalNetworkDao.listByZone(zoneId); + + Iterator it = pNtwks.iterator(); + while (it.hasNext()) { + PhysicalNetwork pNtwk = it.next(); + if (!_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), trafficType)) { + it.remove(); + } + } + return pNtwks; + } + + @Override + public boolean isPrivateGateway(Nic guestNic) { + Network network = getNetwork(guestNic.getNetworkId()); + if (network.getTrafficType() != TrafficType.Guest || network.getNetworkOfferingId() != _privateOfferingId.longValue()) { + return false; + } + return true; + } } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 4dae61a7871..b1f1c0a8b41 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -75,6 +75,9 @@ public class NetworkVO implements Network, Identity { @Column(name="network_offering_id") long networkOfferingId; + + @Column(name="vpc_id") + Long vpcId; @Column(name="physical_network_id") Long physicalNetworkId; @@ -157,7 +160,8 @@ public class NetworkVO implements Network, Identity { * @param dataCenterId * @param physicalNetworkId TODO */ - public NetworkVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, State state, long dataCenterId, Long physicalNetworkId) { + public NetworkVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, + State state, long dataCenterId, Long physicalNetworkId) { this.trafficType = trafficType; this.mode = mode; this.broadcastDomainType = broadcastDomainType; @@ -173,8 +177,11 @@ public class NetworkVO implements Network, Identity { this.uuid = UUID.randomUUID().toString(); } - public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) { - this(id, that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, domainId, accountId, related, name, displayText, networkDomain, guestType, dcId, physicalNetworkId, aclType, specifyIpRanges); + public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, + long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, + Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId) { + this(id, that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, domainId, accountId, + related, name, displayText, networkDomain, guestType, dcId, physicalNetworkId, aclType, specifyIpRanges, vpcId); this.gateway = that.getGateway(); this.cidr = that.getCidr(); this.broadcastUri = that.getBroadcastUri(); @@ -201,9 +208,12 @@ public class NetworkVO implements Network, Identity { * @param guestType TODO * @param aclType TODO * @param specifyIpRanges TODO + * @param vpcId TODO * @param dataCenterId */ - public NetworkVO(long id, TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) { + public NetworkVO(long id, TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, + long networkOfferingId, long domainId, long accountId, long related, String name, String displayText, + String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId) { this(trafficType, mode, broadcastDomainType, networkOfferingId, State.Allocated, dcId, physicalNetworkId); this.domainId = domainId; this.accountId = accountId; @@ -216,6 +226,7 @@ public class NetworkVO implements Network, Identity { this.uuid = UUID.randomUUID().toString(); this.guestType = guestType; this.specifyIpRanges = specifyIpRanges; + this.vpcId = vpcId; } @Override @@ -447,7 +458,6 @@ public class NetworkVO implements Network, Identity { return buf.toString(); } - public String getUuid() { return this.uuid; } @@ -473,4 +483,9 @@ public class NetworkVO implements Network, Identity { public boolean getSpecifyIpRanges() { return specifyIpRanges; } + + @Override + public Long getVpcId() { + return vpcId; + } } diff --git a/server/src/com/cloud/network/RouterNetworkDaoImpl.java b/server/src/com/cloud/network/RouterNetworkDaoImpl.java new file mode 100644 index 00000000000..dcb6583a313 --- /dev/null +++ b/server/src/com/cloud/network/RouterNetworkDaoImpl.java @@ -0,0 +1,58 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import java.util.List; + +import com.cloud.utils.db.GenericDao; +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.SearchCriteria.Op; + +/** + * @author Alena Prokharchyk + */ +public class RouterNetworkDaoImpl extends GenericDaoBase implements GenericDao{ + protected final GenericSearchBuilder RouterNetworksSearch; + protected final SearchBuilder AllFieldsSearch; + + public RouterNetworkDaoImpl() { + super(); + + RouterNetworksSearch = createSearchBuilder(Long.class); + RouterNetworksSearch.selectField(RouterNetworksSearch.entity().getNetworkId()); + RouterNetworksSearch.and("routerId", RouterNetworksSearch.entity().getRouterId(), Op.EQ); + RouterNetworksSearch.done(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("routerId", AllFieldsSearch.entity().getRouterId(), Op.EQ); + AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ); + AllFieldsSearch.done(); + } + + public List getRouterNetworks(long routerId) { + SearchCriteria sc = RouterNetworksSearch.create(); + sc.setParameters("routerId", routerId); + return customSearch(sc, null); + } + + public RouterNetworkVO findByRouterAndNetwork (long routerId, long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("routerId", routerId); + sc.setParameters("networkId", networkId); + return findOneBy(sc); + } + +} diff --git a/server/src/com/cloud/network/RouterNetworkVO.java b/server/src/com/cloud/network/RouterNetworkVO.java new file mode 100644 index 00000000000..629a5f438ee --- /dev/null +++ b/server/src/com/cloud/network/RouterNetworkVO.java @@ -0,0 +1,72 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +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 com.cloud.network.Network.GuestType; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="router_network_ref") +public class RouterNetworkVO{ + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + long id; + + @Column(name="router_id") + long routerId; + + @Column(name="network_id") + long networkId; + + @Column(name="guest_type") + @Enumerated(value=EnumType.STRING) + Network.GuestType guestType; + + protected RouterNetworkVO() { + } + + public RouterNetworkVO(long routerId, long networkId, GuestType guestType) { + this.networkId = networkId; + this.routerId = routerId; + this.guestType = guestType; + } + + + public long getRouterId() { + return routerId; + } + + public long getNetworkId() { + return networkId; + } + + public Network.GuestType getGuestType() { + return guestType; + } + + public long getId() { + return id; + } +} diff --git a/server/src/com/cloud/network/Site2SiteCustomerGatewayVO.java b/server/src/com/cloud/network/Site2SiteCustomerGatewayVO.java new file mode 100644 index 00000000000..d0d8b2b69fd --- /dev/null +++ b/server/src/com/cloud/network/Site2SiteCustomerGatewayVO.java @@ -0,0 +1,127 @@ +package com.cloud.network; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name=("s2s_customer_gateway")) +public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="gateway_ip") + private String gatewayIp; + + @Column(name="guest_cidr_list") + private String guestCidrList; + + @Column(name="ipsec_psk") + private String ipsecPsk; + + @Column(name="ike_policy") + private String ikePolicy; + + @Column(name="esp_policy") + private String espPolicy; + + @Column(name="lifetime") + private long lifetime; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + public Site2SiteCustomerGatewayVO() { } + + public Site2SiteCustomerGatewayVO(String gatewayIp, String guestCidrList, String ipsecPsk, String ikePolicy, String espPolicy, long lifetime) { + this.gatewayIp = gatewayIp; + this.guestCidrList = guestCidrList; + this.ipsecPsk = ipsecPsk; + this.ikePolicy = ikePolicy; + this.espPolicy = espPolicy; + this.lifetime = lifetime; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getId() { + return id; + } + + @Override + public String getGatewayIp() { + return gatewayIp; + } + + public void setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + } + + @Override + public String getGuestCidrList() { + return guestCidrList; + } + + public void setGuestCidrList(String guestCidrList) { + this.guestCidrList = guestCidrList; + } + + @Override + public String getIpsecPsk() { + return ipsecPsk; + } + + public void setIpsecPsk(String ipsecPsk) { + this.ipsecPsk = ipsecPsk; + } + + @Override + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + public long getLifetime() { + return lifetime; + } + + public void setLifetime(long lifetime) { + this.lifetime = lifetime; + } + + public String getIkePolicy() { + return ikePolicy; + } + + public void setIkePolicy(String ikePolicy) { + this.ikePolicy = ikePolicy; + } + + public String getEspPolicy() { + return espPolicy; + } + + public void setEspPolicy(String espPolicy) { + this.espPolicy = espPolicy; + } + + public String getUuid() { + return uuid; + } +} diff --git a/server/src/com/cloud/network/Site2SiteVpnConnectionVO.java b/server/src/com/cloud/network/Site2SiteVpnConnectionVO.java new file mode 100644 index 00000000000..4362b2210a3 --- /dev/null +++ b/server/src/com/cloud/network/Site2SiteVpnConnectionVO.java @@ -0,0 +1,103 @@ +package com.cloud.network; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name=("s2s_vpn_connection")) +public class Site2SiteVpnConnectionVO implements Site2SiteVpnConnection { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="vpn_gateway_id") + private long vpnGatewayId; + + @Column(name="customer_gateway_id") + private long customerGatewayId; + + @Column(name="state") + private State state; + + @Column(name=GenericDao.CREATED_COLUMN) + private Date created; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + public Site2SiteVpnConnectionVO() { } + + public Site2SiteVpnConnectionVO(long vpnGatewayId, long customerGatewayId) { + this.uuid = UUID.randomUUID().toString(); + this.setVpnGatewayId(vpnGatewayId); + this.setCustomerGatewayId(customerGatewayId); + this.setState(State.Pending); + } + + @Override + public long getId() { + return id; + } + + @Override + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public long getVpnGatewayId() { + return vpnGatewayId; + } + + public void setVpnGatewayId(long vpnGatewayId) { + this.vpnGatewayId = vpnGatewayId; + } + + @Override + public long getCustomerGatewayId() { + return customerGatewayId; + } + + public void setCustomerGatewayId(long customerGatewayId) { + this.customerGatewayId = customerGatewayId; + } + + @Override + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + @Override + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + public String getUuid() { + return uuid; + } +} diff --git a/server/src/com/cloud/network/Site2SiteVpnGatewayVO.java b/server/src/com/cloud/network/Site2SiteVpnGatewayVO.java new file mode 100644 index 00000000000..5c9486637c4 --- /dev/null +++ b/server/src/com/cloud/network/Site2SiteVpnGatewayVO.java @@ -0,0 +1,65 @@ +package com.cloud.network; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name=("s2s_vpn_gateway")) +public class Site2SiteVpnGatewayVO implements Site2SiteVpnGateway { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="addr_id") + private long addrId; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + public Site2SiteVpnGatewayVO() { } + + public Site2SiteVpnGatewayVO(long addrId) { + this.uuid = UUID.randomUUID().toString(); + this.setAddrId(addrId); + } + + @Override + public long getId() { + return id; + } + + @Override + public long getAddrId() { + return addrId; + } + + public void setAddrId(long addrId) { + this.addrId = addrId; + } + + @Override + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + public String getUuid() { + return uuid; + } +} diff --git a/server/src/com/cloud/network/addr/PublicIp.java b/server/src/com/cloud/network/addr/PublicIp.java index 5322674e19b..11948e5c836 100644 --- a/server/src/com/cloud/network/addr/PublicIp.java +++ b/server/src/com/cloud/network/addr/PublicIp.java @@ -180,4 +180,20 @@ public class PublicIp implements PublicIpAddress { public boolean getSystem() { return _addr.getSystem(); } + + /* (non-Javadoc) + * @see com.cloud.network.IpAddress#getVpcId() + */ + @Override + public Long getVpcId() { + return _addr.getVpcId(); + } + + /* (non-Javadoc) + * @see com.cloud.network.IpAddress#setVpcId(java.lang.Long) + */ + @Override + public void setVpcId(Long vpcId) { + _addr.setVpcId(vpcId); + } } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDao.java b/server/src/com/cloud/network/dao/FirewallRulesDao.java index dc9ab00e15c..48aec350b28 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDao.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDao.java @@ -50,5 +50,8 @@ public interface FirewallRulesDao extends GenericDao { List listByIpAndNotRevoked(long ipAddressId); long countRulesByIpId(long sourceIpId); + + List listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType); + } diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index 66cf887d0f7..5423ad91c90 100644 --- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -21,6 +21,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; +import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; @@ -69,6 +70,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(), Op.EQ); NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(), Op.EQ); NotRevokedSearch.and("networkId", NotRevokedSearch.entity().getNetworkId(), Op.EQ); + NotRevokedSearch.and("trafficType", NotRevokedSearch.entity().getTrafficType(), Op.EQ); NotRevokedSearch.done(); ReleaseSearch = createSearchBuilder(); @@ -265,4 +267,19 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i return customSearch(sc, null).get(0); } + @Override + public List listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, Purpose purpose, TrafficType trafficType) { + SearchCriteria sc = NotRevokedSearch.create(); + sc.setParameters("networkId", networkId); + sc.setParameters("state", State.Revoke); + + if (purpose != null) { + sc.setParameters("purpose", purpose); + } + + sc.setParameters("trafficType", trafficType); + + return listBy(sc); + } + } diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index 1b44b16ba9e..0624bf86c33 100755 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -54,6 +54,10 @@ public interface IPAddressDao extends GenericDao { public IPAddressVO findByIpAndDcId(long dcId, String ipAddress); List listByPhysicalNetworkId(long physicalNetworkId); + + List listByAssociatedVpc(long vpcId, Boolean isSourceNat); - long countFreeIPs(); + long countFreePublicIPs(); + + long countFreeIPsInNetwork(long networkId); } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index 425c215c430..8e8229ea2e6 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -67,6 +67,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen AllFieldsSearch.and("oneToOneNat", AllFieldsSearch.entity().isOneToOneNat(), Op.EQ); AllFieldsSearch.and("sourcenetwork", AllFieldsSearch.entity().getSourceNetworkId(), Op.EQ); AllFieldsSearch.and("physicalNetworkId", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); VlanDbIdSearchUnallocated = createSearchBuilder(); @@ -110,6 +111,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen CountFreePublicIps = createSearchBuilder(Long.class); CountFreePublicIps.select(null, Func.COUNT, null); CountFreePublicIps.and("state", CountFreePublicIps.entity().getState(), SearchCriteria.Op.EQ); + CountFreePublicIps.and("networkId", CountFreePublicIps.entity().getSourceNetworkId(), SearchCriteria.Op.EQ); SearchBuilder join = _vlanDao.createSearchBuilder(); join.and("vlanType", join.entity().getVlanType(), Op.EQ); CountFreePublicIps.join("vlans", join, CountFreePublicIps.entity().getVlanId(), join.entity().getId(), JoinBuilder.JoinType.INNER); @@ -140,6 +142,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen address.setAssociatedWithVmId(null); address.setState(State.Free); address.setAssociatedWithNetworkId(null); + address.setVpcId(null); address.setSystem(false); update(ipAddressId, address); } @@ -293,10 +296,30 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen } @Override - public long countFreeIPs() { + public long countFreePublicIPs() { SearchCriteria sc = CountFreePublicIps.create(); sc.setParameters("state", State.Free); sc.setJoinParameters("vlans", "vlanType", VlanType.VirtualNetwork); return customSearch(sc, null).get(0); } + + @Override + public List listByAssociatedVpc(long vpcId, Boolean isSourceNat) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + + if (isSourceNat != null) { + sc.setParameters("sourceNat", isSourceNat); + } + + return listBy(sc); + } + + @Override + public long countFreeIPsInNetwork(long networkId) { + SearchCriteria sc = CountFreePublicIps.create(); + sc.setParameters("state", State.Free); + sc.setParameters("networkId", networkId); + return customSearch(sc, null).get(0); + } } diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java index df74f238409..f86ede5ae84 100644 --- a/server/src/com/cloud/network/dao/NetworkDao.java +++ b/server/src/com/cloud/network/dao/NetworkDao.java @@ -54,7 +54,9 @@ public interface NetworkDao extends GenericDao { List listBy(long accountId, long networkId); - List listBy(long zoneId, String broadcastUri); + long countByZoneAndUri(long zoneId, String broadcastUri); + + long countByZoneUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType); List listByZone(long zoneId); @@ -70,8 +72,6 @@ public interface NetworkDao extends GenericDao { void addDomainToNetwork(long networkId, long domainId, Boolean subdomainAccess); - Long getNetworkCountByOfferingId(long offeringId); - List listByPhysicalNetwork(long physicalNetworkId); List listSecurityGroupEnabledNetworks(); @@ -95,5 +95,11 @@ public interface NetworkDao extends GenericDao { long countNetworksUserCanCreate(long ownerId); List listSourceNATEnabledNetworks(long accountId, long dataCenterId, GuestType type); + + int getNetworkCountByVpcId(long vpcId); + + List listByVpc(long vpcId); + + NetworkVO getPrivateNetwork(String broadcastUri, String cidr, long accountId, long zoneId); } diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index f907ce8116b..dc2db243b07 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -21,6 +21,7 @@ import javax.persistence.TableGenerator; import com.cloud.acl.ControlledEntity.ACLType; import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkAccountDaoImpl; @@ -31,6 +32,7 @@ import com.cloud.network.NetworkVO; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; +import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; import com.cloud.utils.component.ComponentLocator; @@ -56,12 +58,13 @@ public class NetworkDaoImpl extends GenericDaoBase implements N final SearchBuilder AccountNetworkSearch; final SearchBuilder ZoneBroadcastUriSearch; final SearchBuilder ZoneSecurityGroupSearch; - final GenericSearchBuilder CountByOfferingId; + final GenericSearchBuilder CountBy; final SearchBuilder PhysicalNetworkSearch; final SearchBuilder SecurityGroupSearch; final GenericSearchBuilder NetworksRegularUserCanCreateSearch; private final GenericSearchBuilder NetworksCount; final SearchBuilder SourceNATSearch; + final GenericSearchBuilder CountByZoneAndURI; NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class); @@ -88,6 +91,8 @@ public class NetworkDaoImpl extends GenericDaoBase implements N AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ); AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), Op.EQ); AllFieldsSearch.and("physicalNetwork", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); + AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); AccountSearch = createSearchBuilder(); @@ -117,7 +122,17 @@ public class NetworkDaoImpl extends GenericDaoBase implements N ZoneBroadcastUriSearch = createSearchBuilder(); ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ); ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ); + ZoneBroadcastUriSearch.and("guestType", ZoneBroadcastUriSearch.entity().getGuestType(), Op.EQ); ZoneBroadcastUriSearch.done(); + + CountByZoneAndURI = createSearchBuilder(Long.class); + CountByZoneAndURI.select(null, Func.COUNT, null); + CountByZoneAndURI.and("dataCenterId", CountByZoneAndURI.entity().getDataCenterId(), Op.EQ); + CountByZoneAndURI.and("broadcastUri", CountByZoneAndURI.entity().getBroadcastUri(), Op.EQ); + CountByZoneAndURI.and("guestType", CountByZoneAndURI.entity().getGuestType(), Op.EQ); + + CountByZoneAndURI.done(); + ZoneSecurityGroupSearch = createSearchBuilder(); ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ); @@ -126,11 +141,12 @@ public class NetworkDaoImpl extends GenericDaoBase implements N ZoneSecurityGroupSearch.join("services", join1, ZoneSecurityGroupSearch.entity().getId(), join1.entity().getNetworkId(), JoinBuilder.JoinType.INNER); ZoneSecurityGroupSearch.done(); - CountByOfferingId = createSearchBuilder(Long.class); - CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); - CountByOfferingId.and("offeringId", CountByOfferingId.entity().getNetworkOfferingId(), Op.EQ); - CountByOfferingId.and("removed", CountByOfferingId.entity().getRemoved(), Op.NULL); - CountByOfferingId.done(); + CountBy = createSearchBuilder(Integer.class); + CountBy.select(null, Func.COUNT, CountBy.entity().getId()); + CountBy.and("offeringId", CountBy.entity().getNetworkOfferingId(), Op.EQ); + CountBy.and("vpcId", CountBy.entity().getVpcId(), Op.EQ); + CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); + CountBy.done(); PhysicalNetworkSearch = createSearchBuilder(); PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ); @@ -298,11 +314,13 @@ public class NetworkDaoImpl extends GenericDaoBase implements N } @Override - public List listBy(long zoneId, String broadcastUri) { - SearchCriteria sc = ZoneBroadcastUriSearch.create(); + public long countByZoneAndUri(long zoneId, String broadcastUri) { + + SearchCriteria sc = CountByZoneAndURI.create(); sc.setParameters("dataCenterId", zoneId); sc.setParameters("broadcastUri", broadcastUri); - return search(sc, null); + + return customSearch(sc, null).get(0); } @Override @@ -311,6 +329,15 @@ public class NetworkDaoImpl extends GenericDaoBase implements N sc.setParameters("dataCenterId", zoneId); return search(sc, null); } + + @Override + public long countByZoneUriAndGuestType(long zoneId, String broadcastUri, GuestType guestType) { + SearchCriteria sc = CountByZoneAndURI.create(); + sc.setParameters("dataCenterId", zoneId); + sc.setParameters("broadcastUri", broadcastUri); + sc.setParameters("guestType", guestType); + return customSearch(sc, null).get(0); + } @Override public List listByZoneSecurityGroup(Long zoneId) { @@ -363,14 +390,16 @@ public class NetworkDaoImpl extends GenericDaoBase implements N NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId, subdomainAccess); _domainsDao.persist(domain); } - + + @Override - public Long getNetworkCountByOfferingId(long offeringId) { - SearchCriteria sc = CountByOfferingId.create(); - sc.setParameters("offeringId", offeringId); - List results = customSearch(sc, null); + public int getNetworkCountByVpcId(long vpcId) { + SearchCriteria sc = CountBy.create(); + sc.setParameters("vpcId", vpcId); + List results = customSearch(sc, null); return results.get(0); } + @Override public List listSecurityGroupEnabledNetworks() { @@ -458,5 +487,25 @@ public class NetworkDaoImpl extends GenericDaoBase implements N sc.setJoinParameters("services", "service", Service.SourceNat.getName()); return listBy(sc); } + + @Override + public List listByVpc(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + + return listBy(sc, null); + } + + + @Override + public NetworkVO getPrivateNetwork(String broadcastUri, String cidr, long accountId, long zoneId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("datacenter", zoneId); + sc.setParameters("broadcastUri", broadcastUri); + sc.setParameters("cidr", cidr); + sc.setParameters("account", accountId); + sc.setParameters("offering", _ntwkOffDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOffering).getId()); + return findOneBy(sc); + } } diff --git a/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java b/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java new file mode 100644 index 00000000000..a27903b9ee1 --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDao.java @@ -0,0 +1,8 @@ +package com.cloud.network.dao; + +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.utils.db.GenericDao; + +public interface Site2SiteCustomerGatewayDao extends GenericDao { + Site2SiteCustomerGatewayVO findByGatewayIp(String ip); +} diff --git a/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java b/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java new file mode 100644 index 00000000000..6c5fb3fc74f --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteCustomerGatewayDaoImpl.java @@ -0,0 +1,31 @@ +package com.cloud.network.dao; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={Site2SiteCustomerGatewayDao.class}) +public class Site2SiteCustomerGatewayDaoImpl extends GenericDaoBase implements Site2SiteCustomerGatewayDao { + private static final Logger s_logger = Logger.getLogger(Site2SiteCustomerGatewayDaoImpl.class); + + private final SearchBuilder AllFieldsSearch; + + protected Site2SiteCustomerGatewayDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("gatewayIp", AllFieldsSearch.entity().getGatewayIp(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public Site2SiteCustomerGatewayVO findByGatewayIp(String ip) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("gatewayIp", ip); + return findOneBy(sc); + } + +} diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java b/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java new file mode 100644 index 00000000000..61204a5d9e5 --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDao.java @@ -0,0 +1,9 @@ +package com.cloud.network.dao; + +import com.cloud.network.Site2SiteVpnConnectionVO; +import com.cloud.utils.db.GenericDao; + +public interface Site2SiteVpnConnectionDao extends GenericDao { + Site2SiteVpnConnectionVO findByCustomerGatewayId(long id); + Site2SiteVpnConnectionVO findByVpnGatewayId(long id); +} diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java b/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java new file mode 100644 index 00000000000..8659d2784be --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteVpnConnectionDaoImpl.java @@ -0,0 +1,38 @@ +package com.cloud.network.dao; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.Site2SiteVpnConnectionVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={Site2SiteVpnConnectionDao.class}) +public class Site2SiteVpnConnectionDaoImpl extends GenericDaoBase implements Site2SiteVpnConnectionDao { + private static final Logger s_logger = Logger.getLogger(Site2SiteVpnConnectionDaoImpl.class); + + private final SearchBuilder AllFieldsSearch; + + protected Site2SiteVpnConnectionDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("customerGatewayId", AllFieldsSearch.entity().getCustomerGatewayId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("vpnGatewayId", AllFieldsSearch.entity().getVpnGatewayId(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public Site2SiteVpnConnectionVO findByCustomerGatewayId(long id) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("customerGatewayId", id); + return findOneBy(sc); + } + + @Override + public Site2SiteVpnConnectionVO findByVpnGatewayId(long id) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpnGatewayId", id); + return findOneBy(sc); + } +} diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java new file mode 100644 index 00000000000..e9dcbbfbeb0 --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java @@ -0,0 +1,10 @@ +package com.cloud.network.dao; + +import java.util.List; + +import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.utils.db.GenericDao; + +public interface Site2SiteVpnGatewayDao extends GenericDao { + Site2SiteVpnGatewayVO findByIpAddrId(long id); +} diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java new file mode 100644 index 00000000000..feab33a992f --- /dev/null +++ b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java @@ -0,0 +1,32 @@ +package com.cloud.network.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={Site2SiteVpnGatewayDao.class}) +public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase implements Site2SiteVpnGatewayDao { + private static final Logger s_logger = Logger.getLogger(Site2SiteVpnGatewayDaoImpl.class); + + private final SearchBuilder AllFieldsSearch; + + protected Site2SiteVpnGatewayDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("addrId", AllFieldsSearch.entity().getAddrId(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + } + + @Override + public Site2SiteVpnGatewayVO findByIpAddrId(long id) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("addrId", id); + return findOneBy(sc); + } +} diff --git a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java index 0473291d15d..1aa23daef4a 100644 --- a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java +++ b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java @@ -266,6 +266,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); firewallCapabilities.put(Capability.MultipleIps, "true"); firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); // Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work diff --git a/server/src/com/cloud/network/element/NetscalerElement.java b/server/src/com/cloud/network/element/NetscalerElement.java index 81d5424d4ab..e8ea3bcdbe6 100644 --- a/server/src/com/cloud/network/element/NetscalerElement.java +++ b/server/src/com/cloud/network/element/NetscalerElement.java @@ -270,7 +270,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); firewallCapabilities.put(Capability.MultipleIps, "true"); - + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); return capabilities; @@ -608,7 +608,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl if (loadBalancersToApply.size() > 0) { int numLoadBalancersForCommand = loadBalancersToApply.size(); LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); @@ -660,7 +660,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } } - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null); answer = (SetStaticNatRulesAnswer) _agentMgr.send(lbDevice.getHostId(), cmd); if (answer == null) { return false; diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index d69ad6f17cc..05d8a99c02c 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -85,11 +85,12 @@ import com.cloud.vm.dao.UserVmDao; import com.google.gson.Gson; @Local(value = NetworkElement.class) -public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, +public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, + UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); - private static final Map> capabilities = setCapabilities(); + protected static final Map> capabilities = setCapabilities(); @Inject NetworkDao _networksDao; @@ -127,8 +128,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (physicalNetworkId == null) { return false; } + + if (network.getVpcId() != null) { + return false; + } - if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, "VirtualRouter")) { + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())) { return false; } @@ -139,7 +144,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } } else { if (!_networkMgr.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { - s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network); + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + + " in the network " + network); return false; } } @@ -148,23 +154,32 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { + if (offering.isSystemOnly()) { return false; } Map params = new HashMap(1); - params.put(VirtualMachineProfile.Param.ReProgramNetwork, true); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), params, offering.getRedundantRouter()); - - return true; + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, + _accountMgr.getAccount(network.getAccountId()), params, + offering.getRedundantRouter()); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + return true; } @Override - public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, - InsufficientCapacityException, ResourceUnavailableException { + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) { return false; } @@ -177,17 +192,21 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (offering.isSystemOnly()) { return false; } - if (!_networkMgr.isProviderEnabledInPhysicalNetwork(_networkMgr.getPhysicalNetworkId(network), "VirtualRouter")) { + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(_networkMgr.getPhysicalNetworkId(network), getProvider().getName())) { return false; } @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - List routers = _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters(), offering.getRedundantRouter()); + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, + _accountMgr.getAccount(network.getAccountId()), + uservm.getParameters(), offering.getRedundantRouter()); if ((routers == null) || (routers.size() == 0)) { - throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); } - return true; + + return true; } @Override @@ -195,7 +214,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(config, Service.Firewall)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + config.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); return true; } @@ -265,10 +285,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl expire = value; } if ((expire != null) && !containsOnlyNumbers(expire, timeEndChar)) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: expire is not in timeformat: " + expire); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: expire is not in timeformat: " + expire); } if ((tablesize != null) && !containsOnlyNumbers(tablesize, "kmg")) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: tablesize is not in size format: " + tablesize); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: tablesize is not in size format: " + tablesize); } } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { @@ -294,10 +316,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } if ((length != null) && (!containsOnlyNumbers(length, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: length is not a number: " + length); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: length is not a number: " + length); } if ((holdTime != null) && (!containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: holdtime is not in timeformat: " + holdTime); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: holdtime is not in timeformat: " + holdTime); } } } @@ -321,7 +345,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Lb)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -342,7 +367,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + + " doesn't exist in the network " + network.getId()); return null; } return _routerMgr.applyVpnUsers(network, users, routers); @@ -357,7 +383,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't" + + " exist in the network " + network.getId()); return true; } return _routerMgr.startRemoteAccessVpn(network, vpn, routers); @@ -372,7 +399,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + + "exist in the network " + network.getId()); return true; } return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers); @@ -383,7 +411,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean applyIps(Network network, List ipAddress, Set services) throws ResourceUnavailableException { + public boolean applyIps(Network network, List ipAddress, Set services) + throws ResourceUnavailableException { boolean canHandle = true; for (Service service : services) { if (!canHandle(network, service)) { @@ -394,7 +423,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -421,37 +451,61 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method."); method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false); method.addParam("mode", false, - "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); + "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created" + + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); method.addParam( "nocache", false, - "This option is recommended in conjunction with the insert mode when there is a cache between the client and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs to be inserted. This is important because if all persistence cookies are added on a cacheable home page for instance, then all customers will then fetch the page from an outer cache and will all share the same persistence cookie, leading to one server receiving much more traffic than others. See also the insert and postonly options. ", + "This option is recommended in conjunction with the insert mode when there is a cache between the client" + + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " + + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" + + " for instance, then all customers will then fetch the page from an outer cache and will all share the " + + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + + "insert and postonly options. ", true); method.addParam( "indirect", false, - "When this option is specified in insert mode, cookies will only be added when the server was not reached after a direct access, which means that only when a server is elected after applying a load-balancing algorithm, or after a redispatch, then the cookie will be inserted. If the client has all the required information to connect to the same server next time, no further cookie will be inserted. In all cases, when the indirect option is used in insert mode, the cookie is always removed from the requests transmitted to the server. The persistence mechanism then becomes totally transparent from the application point of view.", + "When this option is specified in insert mode, cookies will only be added when the server was not reached" + + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," + + " or after a redispatch, then the cookie will be inserted. If the client has all the required information" + + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " + + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " + + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true); method.addParam( "postonly", false, - "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an alternative to the nocache option, because POST responses are not cacheable, so this ensures that the persistence cookie will never get cached.Since most sites do not need any sort of persistence before the first POST which generally is a login request, this is a very efficient method to optimize caching without risking to find a persistence cookie in the cache. See also the insert and nocache options.", + "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" + + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " + + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" + + " first POST which generally is a login request, this is a very efficient method to optimize caching " + + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true); method.addParam( "domain", false, - "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter: a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host ending with that name. It is also possible to specify several domain names by invoking this option multiple times. Some browsers might have small limits on the number of domains, so be careful when doing that. For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", + "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" + + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " + + "ending with that name. It is also possible to specify several domain names by invoking this option multiple" + + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " + + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false); methodList.add(method); method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, - "This is App session based sticky method. Define session stickiness on an existing application cookie. It can be used only for a specific http traffic"); - method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will have to learn for each new session. Default value: Auto geneared based on ip", false); - method.addParam("length", false, "This is the max number of characters that will be memorized and checked in each cookie value. Default value:52", false); + "This is App session based sticky method. Define session stickiness on an existing application cookie. " + + "It can be used only for a specific http traffic"); + method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " + + "have to learn for each new session. Default value: Auto geneared based on ip", false); + method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + + "each cookie value. Default value:52", false); method.addParam( "holdtime", false, - "This is the time after which the cookie will be removed from memory if unused. The value should be in the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid , cannot use th combinations like 20h30m. Default value:3h ", + "This is the time after which the cookie will be removed from memory if unused. The value should be in " + + "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," + + " cannot use th combinations like 20h30m. Default value:3h ", false); method.addParam( "request-learn", @@ -461,18 +515,25 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl method.addParam( "prefix", false, - "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", + "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). " + + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", true); method.addParam( "mode", false, - "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters : The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string : In this mode, the parser will look for the appsession in the query string.", + "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " + + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " + + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" + + " In this mode, the parser will look for the appsession in the query string.", false); methodList.add(method); - method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, it can be used for any type of protocol."); - method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m or 400g. Default value:200k", false); - method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d . example: expire=30m 20s 50h 4d. Default value:3h", false); + method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + + "it can be used for any type of protocol."); + method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + + " or 400g. Default value:200k", false); + method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." + + " example: expire=30m 20s 50h 4d. Default value:3h", false); methodList.add(method); Gson gson = new Gson(); @@ -498,12 +559,13 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); firewallCapabilities.put(Capability.MultipleIps, "true"); - + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); // Set capabilities for vpn Map vpnCapabilities = new HashMap(); - vpnCapabilities.put(Capability.SupportedVpnTypes, "pptp,l2tp,ipsec"); + vpnCapabilities.put(Capability.SupportedVpnProtocols, "pptp,l2tp,ipsec"); + vpnCapabilities.put(Capability.VpnTypes, "removeaccessvpn"); capabilities.put(Service.Vpn, vpnCapabilities); Map dnsCapabilities = new HashMap(); @@ -531,7 +593,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(config, Service.StaticNat)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual router doesn't exist in the network " + config.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); return true; } @@ -542,7 +605,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { return true; @@ -577,7 +641,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException { + public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) + throws ResourceUnavailableException { if (!canHandle(network, null)) { return false; } @@ -613,13 +678,13 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public VirtualRouterProvider addElement(Long nspId) { - VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, VirtualRouterProviderType.VirtualRouter); + public VirtualRouterProvider addElement(Long nspId, VirtualRouterProviderType providerType) { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType); if (element != null) { s_logger.debug("There is already a virtual router element with service provider id " + nspId); return null; } - element = new VirtualRouterProviderVO(nspId, VirtualRouterProviderType.VirtualRouter); + element = new VirtualRouterProviderVO(nspId, providerType); _vrProviderDao.persist(element); return element; } @@ -629,7 +694,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.PortForwarding)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -645,7 +711,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public boolean isReady(PhysicalNetworkServiceProvider provider) { - VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), VirtualRouterProviderType.VirtualRouter); + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), + getVirtualRouterProvider()); if (element == null) { return false; } @@ -653,9 +720,11 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { - VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), VirtualRouterProviderType.VirtualRouter); + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), + getVirtualRouterProvider()); if (element == null) { return true; } @@ -687,13 +756,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } @Override - public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.Dhcp)) { if (vm.getType() != VirtualMachine.Type.User) { @@ -703,33 +774,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { - publicNetwork = true; - } - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && - network.getTrafficType() == TrafficType.Guest; - - List routers; - - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } else { - Long podId = dest.getPod().getId(); - if (isPodBased) { - routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); - } else { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } - } - - // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" - Long podId = dest.getPod().getId(); - if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { - List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); - routers.addAll(allRunningRoutersOutsideThePod); - } + List routers = getRouters(network, dest); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); @@ -741,7 +786,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.UserData)) { if (vm.getType() != VirtualMachine.Type.User) { @@ -751,33 +797,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { - publicNetwork = true; - } - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && - network.getTrafficType() == TrafficType.Guest; - - List routers; - - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } else { - Long podId = dest.getPod().getId(); - if (isPodBased) { - routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); - } else { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } - } - - // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" - Long podId = dest.getPod().getId(); - if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { - List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); - routers.addAll(allRunningRoutersOutsideThePod); - } + List routers = getRouters(network, dest); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); @@ -788,6 +808,39 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return false; } + protected List getRouters(Network network, DeployDestination dest) { + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { + publicNetwork = true; + } + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic + || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && + network.getTrafficType() == TrafficType.Guest; + + List routers; + + if (publicNetwork) { + routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + } else { + Long podId = dest.getPod().getId(); + if (isPodBased) { + routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); + } else { + routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + } + } + + // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when + // network.dns.basiczone.updates is set to "all" + Long podId = dest.getPod().getId(); + if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { + List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), + podId, State.Running, Role.VIRTUAL_ROUTER); + routers.addAll(allRunningRoutersOutsideThePod); + } + return routers; + } + @Override public List searchForVirtualRouterElement(ListVirtualRouterElementsCmd cmd) { Long id = cmd.getId(); @@ -823,4 +876,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl public IpDeployer getIpDeployer(Network network) { return this; } + + protected VirtualRouterProviderType getVirtualRouterProvider() { + return VirtualRouterProviderType.VirtualRouter; + } } diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java new file mode 100644 index 00000000000..1b5c28861e5 --- /dev/null +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -0,0 +1,486 @@ + +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.element; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +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.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkService; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.router.VpcVirtualNetworkApplianceManager; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.NetworkACL; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcGateway; +import com.cloud.network.vpc.VpcManager; +import com.cloud.offering.NetworkOffering; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; + +/** + * @author Alena Prokharchyk + */ +@Local(value = NetworkElement.class) +public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, Site2SiteVpnServiceProvider, NetworkACLServiceProvider{ + private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class); + @Inject + NetworkService _ntwkService; + @Inject + VpcManager _vpcMgr; + @Inject + VpcVirtualNetworkApplianceManager _vpcRouterMgr; + @Inject + Site2SiteCustomerGatewayDao _customerGatewayDao; + @Inject + Site2SiteVpnGatewayDao _vpnGatewayDao; + @Inject + Site2SiteVpnConnectionDao _vpnConnectionDao; + @Inject + IPAddressDao _ipAddressDao; + + + private static final Map> capabilities = setCapabilities(); + + + @Override + protected boolean canHandle(Network network, Service service) { + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + if (physicalNetworkId == null) { + return false; + } + + if (network.getVpcId() == null) { + return false; + } + + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName())) { + return false; + } + + if (service == null) { + if (!_networkMgr.isProviderForNetwork(getProvider(), network.getId())) { + s_logger.trace("Element " + getProvider().getName() + " is not a provider for the network " + network); + return false; + } + } else { + if (!_networkMgr.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + + " in the network " + network); + return false; + } else if (service == Service.Firewall) { + //todo - get capability here + } + } + + return true; + } + + @Override + public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params); + + return true; + } + + @Override + public boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + List routers = _routerDao.listByVpcId(vpc.getId()); + if (routers == null || routers.isEmpty()) { + return true; + } + boolean result = true; + for (DomainRouterVO router : routers) { + result = result && (_routerMgr.destroyRouter(router.getId()) != null); + } + return result; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ResourceUnavailableException, ConcurrentOperationException, + InsufficientCapacityException { + + Long vpcId = network.getVpcId(); + if (vpcId == null) { + s_logger.trace("Network " + network + " is not associated with any VPC"); + return false; + } + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + List routers = _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + if (routers.size() > 1) { + throw new CloudRuntimeException("Found more than one router in vpc " + vpc); + } + + DomainRouterVO router = routers.get(0); + //Add router to guest network if needed + if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { + if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) { + throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network); + } else { + s_logger.debug("Successfully added VPC router " + router + " to guest network " + network); + } + } + + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + + Long vpcId = network.getVpcId(); + if (vpcId == null) { + s_logger.trace("Network " + network + " is not associated with any VPC"); + return false; + } + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } + + if (vm.getType() == Type.User) { + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + List routers = _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, + _accountMgr.getAccount(vpc.getAccountId()), params); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + if (routers.size() > 1) { + throw new CloudRuntimeException("Found more than one router in vpc " + vpc); + } + + DomainRouterVO router = routers.get(0); + //Add router to guest network if needed + if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { + if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) { + throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network); + } else { + s_logger.debug("Successfully added VPC router " + router + " to guest network " + network); + } + } + } + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException { + boolean success = true; + Long vpcId = network.getVpcId(); + if (vpcId == null) { + s_logger.debug("Network " + network + " doesn't belong to any vpc, so skipping unplug nic part"); + return success; + } + + List routers = _routerDao.listByVpcId(vpcId); + for (VirtualRouter router : routers) { + //1) Check if router is already a part of the network + if (!_ntwkService.isVmPartOfNetwork(router.getId(), network.getId())) { + s_logger.debug("Router " + router + " is not a part the network " + network); + continue; + } + //2) Call unplugNics in the network service + success = success && _vpcRouterMgr.removeRouterFromGuestNetwork(router, network, false); + if (!success) { + s_logger.warn("Failed to unplug nic in network " + network + " for virtual router " + router); + } else { + s_logger.debug("Successfully unplugged nic in network " + network + " for virtual router " + router); + } + } + + return success; + } + + @Override + public boolean destroy(Network config) throws ConcurrentOperationException, ResourceUnavailableException { + boolean success = true; + Long vpcId = config.getVpcId(); + if (vpcId == null) { + s_logger.debug("Network " + config + " doesn't belong to any vpc, so skipping unplug nic part"); + return success; + } + + List routers = _routerDao.listByVpcId(vpcId); + for (VirtualRouter router : routers) { + //1) Check if router is already a part of the network + if (!_ntwkService.isVmPartOfNetwork(router.getId(), config.getId())) { + s_logger.debug("Router " + router + " is not a part the network " + config); + continue; + } + //2) Call unplugNics in the network service + success = success && _vpcRouterMgr.removeRouterFromGuestNetwork(router, config, false); + if (!success) { + s_logger.warn("Failed to unplug nic in network " + config + " for virtual router " + router); + } else { + s_logger.debug("Successfully unplugged nic in network " + config + " for virtual router " + router); + } + } + + return success; + } + + @Override + public Provider getProvider() { + return Provider.VPCVirtualRouter; + } + + private static Map> setCapabilities() { + Map> capabilities = VirtualRouterElement.capabilities; + + Map sourceNatCapabilities = capabilities.get(Service.SourceNat); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + Map vpnCapabilities = capabilities.get(Service.Vpn); + vpnCapabilities.put(Capability.VpnTypes, "s2svpn"); + capabilities.put(Service.Vpn, vpnCapabilities); + + Map firewallCapabilities = capabilities.get(Service.Firewall); + firewallCapabilities.put(Capability.FirewallType, "networkacl"); + capabilities.put(Service.Firewall, firewallCapabilities); + + return capabilities; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + @Override + public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException { + if (gateway.getType() != VpcGateway.Type.Private) { + s_logger.warn("Type of vpc gateway is not " + VpcGateway.Type.Private); + return false; + } + + List routers = _vpcMgr.getVpcRouters(gateway.getVpcId()); + if (routers == null || routers.isEmpty()) { + s_logger.debug(this.getName() + " element doesn't need to create Private gateway on the backend; VPC virtual " + + "router doesn't exist in the vpc id=" + gateway.getVpcId()); + return true; + } + + if (routers.size() > 1) { + throw new CloudRuntimeException("Found more than one router in vpc " + gateway.getVpcId()); + } + + VirtualRouter router = routers.get(0); + + return _vpcRouterMgr.setupPrivateGateway(gateway, router); + } + + @Override + public boolean deletePrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException { + if (gateway.getType() != VpcGateway.Type.Private) { + s_logger.warn("Type of vpc gateway is not " + VpcGateway.Type.Private); + return false; + } + + List routers = _vpcMgr.getVpcRouters(gateway.getVpcId()); + if (routers == null || routers.isEmpty()) { + s_logger.debug(this.getName() + " element doesn't need to delete Private gateway on the backend; VPC virtual " + + "router doesn't exist in the vpc id=" + gateway.getVpcId()); + return true; + } + + if (routers.size() > 1) { + throw new CloudRuntimeException("Found more than one router in vpc " + gateway.getVpcId()); + } + + VirtualRouter router = routers.get(0); + + return _vpcRouterMgr.destroyPrivateGateway(gateway, router); + } + + @Override + protected List getRouters(Network network, DeployDestination dest) { + return _vpcMgr.getVpcRouters(network.getVpcId()); + } + + @Override + public boolean applyIps(Network network, List ipAddress, Set services) + throws ResourceUnavailableException { + boolean canHandle = true; + for (Service service : services) { + if (!canHandle(network, service)) { + canHandle = false; + break; + } + } + if (canHandle) { + List routers = getRouters(network, null); + if (routers == null || routers.isEmpty()) { + s_logger.debug(this.getName() + " element doesn't need to associate ip addresses on the backend; VPC virtual " + + "router doesn't exist in the network " + network.getId()); + return true; + } + + return _vpcRouterMgr.associateIP(network, ipAddress, routers); + } else { + return false; + } + } + + @Override + public boolean applyNetworkACLs(Network config, List rules) throws ResourceUnavailableException { + if (canHandle(config, Service.Firewall)) { + List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); + if (routers == null || routers.isEmpty()) { + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); + return true; + } + + if (!_vpcRouterMgr.applyNetworkACLs(config, (List)rules, routers)) { + throw new CloudRuntimeException("Failed to apply firewall rules in network " + config.getId()); + } else { + return true; + } + } else { + return true; + } + } + + @Override + protected VirtualRouterProviderType getVirtualRouterProvider() { + return VirtualRouterProviderType.VPCVirtualRouter; + } + + @Override + public boolean applyStaticRoutes(Vpc vpc, List routes) throws ResourceUnavailableException { + List routers = _routerDao.listByVpcId(vpc.getId()); + if (routers == null || routers.isEmpty()) { + s_logger.debug("Virtual router elemnt doesn't need to static routes on the backend; virtual " + + "router doesn't exist in the vpc " + vpc); + return true; + } + + if (!_vpcRouterMgr.applyStaticRoutes(routes, routers)) { + throw new CloudRuntimeException("Failed to apply static routes in vpc " + vpc); + } else { + s_logger.debug("Applied static routes on vpc " + vpc); + return true; + } + } + + public boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + + /* + if (!canHandle(network, Service.Vpn)) { + return false; + } + */ + + Map vpnCapabilities = capabilities.get(Service.Vpn); + if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) { + return false; + } + + List routers = _vpcMgr.getVpcRouters(ip.getVpcId()); + if (routers == null || routers.size() != 1) { + s_logger.debug("Cannot enable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId()); + return true; + } + + return _vpcRouterMgr.startSite2SiteVpn(conn, routers.get(0)); + } + + @Override + public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + + /* + if (!canHandle(network, Service.Vpn)) { + return false; + } + */ + + Map vpnCapabilities = capabilities.get(Service.Vpn); + if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) { + return false; + } + + List routers = _vpcMgr.getVpcRouters(ip.getVpcId()); + if (routers == null || routers.size() != 1) { + s_logger.debug("Cannot disable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId()); + return true; + } + + return _vpcRouterMgr.stopSite2SiteVpn(conn, routers.get(0)); + } +} diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index aef6d7ca77e..c4149680f65 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -72,7 +72,7 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; -@Local(value = { FirewallService.class, FirewallManager.class }) +@Local(value = { FirewallService.class, FirewallManager.class}) public class FirewallManagerImpl implements FirewallService, FirewallManager, Manager { private static final Logger s_logger = Logger.getLogger(FirewallManagerImpl.class); String _name; @@ -131,21 +131,26 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException { Account caller = UserContext.current().getCaller(); - return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(), - rule.getIcmpType(), null, rule.getType()); + return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), + rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(), + rule.getIcmpType(), null, rule.getType(), rule.getNetworkId()); } @DB @Override @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true) - public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, - Long relatedRuleId, FirewallRule.FirewallRuleType type) throws NetworkRuleConflictException { + public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, + Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, + Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException { + IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId); - // Validate ip address if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) { - throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system"); + throw new InvalidParameterValueException("Unable to create firewall rule; ip id=" + ipAddrId + + " doesn't exist in the system"); } + + _networkMgr.checkIpForService(ipAddress, Service.Firewall); validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type); @@ -158,27 +163,24 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP"); } - Long networkId = null; Long accountId = null; Long domainId = null; if (ipAddress != null) { - networkId = ipAddress.getAssociatedWithNetworkId(); accountId = ipAddress.getAllocatedToAccountId(); domainId = ipAddress.getAllocatedInDomainId(); } - _networkMgr.checkIpForService(ipAddress, Service.Firewall); - Transaction txn = Transaction.currentTxn(); txn.start(); - FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId); + FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, + accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, null); newRule.setType(type); newRule = _firewallDao.persist(newRule); if (type == FirewallRuleType.User) - detectRulesConflict(newRule, ipAddress); + detectRulesConflict(newRule); if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); @@ -237,18 +239,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException { - assert newRule.getSourceIpAddressId() == ipAddress.getId() : "You passed in an ip address that doesn't match the address in the new rule"; + public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException { List rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null); - assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for network conflicts so we should at least have one rule at this point."; + assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " + + "network conflicts so we should at least have one rule at this point."; for (FirewallRuleVO rule : rules) { if (rule.getId() == newRule.getId()) { continue; // Skips my own rule. } - boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol() + boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) + && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol() .equalsIgnoreCase(rule.getProtocol())))); // if both rules are firewall and their cidrs are different, we can skip port ranges verification @@ -273,35 +276,46 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (!oneOfRulesIsFirewall) { if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) { - throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId()); + throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + + newRule.getSourceIpAddressId()); } else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) { - throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId()); + throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + + newRule.getSourceIpAddressId()); } } if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) { - throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid()); + throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + + rule.getXid()); } if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) { - if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() + if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() + && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) { throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId()); } } - boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null); + boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && + rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null); if (!notNullPorts) { continue; } else if (!oneOfRulesIsFirewall && !(bothRulesFirewall && !duplicatedCidrs) - && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) - || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) - || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) - || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) { + && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() + && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) + || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() + && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() + && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() + && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) { // we allow port forwarding rules with the same parameters but different protocols - boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())); - boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())); + boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding + && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())); + boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat + && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())); if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall)) { throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId() @@ -316,7 +330,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type) { + public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, + String proto, Purpose purpose, FirewallRuleType type) { if (portStart != null && !NetUtils.isValidPort(portStart)) { throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart); } @@ -336,30 +351,40 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma // Validate ip address _accountMgr.checkAccess(caller, null, true, ipAddress); - Long networkId = ipAddress.getAssociatedWithNetworkId(); - if (networkId == null) { - throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + ipAddress.getId() + " is not associated with any network"); + Long networkId = null; + if (ipAddress.getAssociatedWithNetworkId() == null) { + throw new InvalidParameterValueException("Unable to create firewall rule ; ip id=" + + ipAddress.getId() + " is not associated with any network"); + } else { + networkId = ipAddress.getAssociatedWithNetworkId(); } Network network = _networkMgr.getNetwork(networkId); assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?"; // Verify that the network guru supports the protocol specified - Map protocolCapabilities = null; + Map caps = null; if (purpose == Purpose.LoadBalancing) { if (!_elbEnabled) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Lb); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Lb); } } else if (purpose == Purpose.Firewall) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + if (caps != null) { + String firewallType = caps.get(Capability.FirewallType); + //regular firewall rules are not supported in networks supporting network ACLs + if (firewallType.equalsIgnoreCase("networkacl")) { + throw new UnsupportedOperationException("Firewall rules are not supported in network " + network); + } + } } else if (purpose == Purpose.PortForwarding) { - protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding); + caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding); } - if (protocolCapabilities != null) { - String supportedProtocols = protocolCapabilities.get(Capability.SupportedProtocols).toLowerCase(); + if (caps != null) { + String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); if (!supportedProtocols.contains(proto.toLowerCase())) { throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId()); } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) { @@ -369,7 +394,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public boolean applyRules(List rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException { + public boolean applyRules(List rules, boolean continueOnError, boolean updateRulesInDB) + throws ResourceUnavailableException { boolean success = true; if (!_networkMgr.applyRules(rules, continueOnError)) { s_logger.warn("Rules are not completely applied"); @@ -380,10 +406,11 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (rule.getState() == FirewallRule.State.Revoke) { FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(rule.getId()); if (relatedRule != null) { - s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); + s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); success = false; } else { - _firewallDao.remove(rule.getId()); + removeRule(rule); } } else if (rule.getState() == FirewallRule.State.Add) { FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId()); @@ -397,6 +424,24 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma return success; } + @DB + @Override + public void removeRule(FirewallRule rule) { + + Transaction txn = Transaction.currentTxn(); + txn.start(); + //remove the rule + _firewallDao.remove(rule.getId()); + + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); + if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } + + txn.commit(); + } + @Override public boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException { List rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall); @@ -407,7 +452,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public boolean applyFirewallRules(List rules, boolean continueOnError, Account caller) { if (rules.size() == 0) { - s_logger.debug("There are no firewall rules to apply for ip id=" + rules); + s_logger.debug("There are no firewall rules to apply"); return true; } @@ -459,7 +504,6 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } return success; - } @Override @@ -484,7 +528,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (s_logger.isDebugEnabled()) { s_logger.debug("Found a rule that is still in stage state so just removing it: " + rule); } - _firewallDao.remove(rule.getId()); + removeRule(rule); generateUsageEvent = true; } else if (rule.getState() == State.Add || rule.getState() == State.Active) { rule.setState(State.Revoke); @@ -535,18 +579,21 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId) + public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, + Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException { // If firwallRule for this port range already exists, return it - List rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, protocol, Purpose.Firewall); + List rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, + protocol, Purpose.Firewall); if (!rules.isEmpty()) { return rules.get(0); } List oneCidr = new ArrayList(); oneCidr.add(NetUtils.ALL_CIDRS); - return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User); + return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType, + relatedRuleId, FirewallRule.FirewallRuleType.User, networkId); } @Override @@ -560,7 +607,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma for (FirewallRuleVO rule : fwRules) { // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no -// need to send them one by one + // need to send them one by one revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM); } @@ -654,7 +701,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma for (FirewallRuleVO rule : systemRules) { try { this.createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), - rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System); + rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId()); } catch (Exception e) { s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString()); } diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index f9977102b1f..cb6f045bc68 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -42,11 +42,11 @@ import com.cloud.network.Network.State; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkProfile; import com.cloud.network.NetworkVO; -import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.PhysicalNetworkDao; @@ -114,10 +114,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { protected boolean canHandle(NetworkOffering offering, DataCenter dc) { // This guru handles only Guest Isolated network that supports Source nat service - if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated) { + if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated && !offering.isSystemOnly()) { return true; } else { - s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); + s_logger.trace("We only take care of non-system Guest networks of type " + GuestType.Isolated + " in zone of type " + + NetworkType.Advanced); return false; } } @@ -129,9 +131,11 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { return null; } - NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); + NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), + State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); if (userSpecified != null) { - if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { + if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || + (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { throw new InvalidParameterValueException("cidr and gateway must be specified together."); } @@ -185,54 +189,6 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } } -// @Override -// @DB -// public Ip4Address acquireIp4Address(Network network, Ip4Address requestedIp, String reservationId) { -// List ips = _nicDao.listIpAddressInNetwork(network.getId()); -// String[] cidr = network.getCidr().split("/"); -// Set allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1])); -// Set usedIps = new TreeSet(); -// -// if (requestedIp != null && requestedIp.equals(network.getGateway())) { -// s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network); -// return null; -// } -// -// for (String ip : ips) { -// if (requestedIp != null && requestedIp.equals(ip)) { -// s_logger.warn("Requested ip address " + requestedIp + " is already in use in network " + network); -// return null; -// } -// -// usedIps.add(NetUtils.ip2Long(ip)); -// } -// if (usedIps.size() != 0) { -// allPossibleIps.removeAll(usedIps); -// } -// if (allPossibleIps.isEmpty()) { -// return null; -// } -// -// Long[] array = allPossibleIps.toArray(new Long[allPossibleIps.size()]); -// -// if (requestedIp != null) { -// //check that requested ip has the same cidr -// boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1])); -// if (!isSameCidr) { -// s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr"); -// return null; -// } else { -// return requestedIp; -// } -// } -// -// String result; -// do { -// result = NetUtils.long2Ip(array[_rand.nextInt(array.length)]); -// } while (result.split("\\.")[3].equals("1")); -// return result; -// } - public Ip4Address acquireIp4Address(Network network, Ip4Address requestedIp, String reservationId) { List ips = _nicDao.listIpAddressInNetwork(network.getId()); String[] cidr = network.getCidr().split("/"); @@ -303,17 +259,20 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (network.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); if (vnet == null) { - throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); + throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + + "part of network " + network + " implement ", DataCenter.class, dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); + EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } } @Override - public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, + ReservationContext context) throws InsufficientVirtualNetworkCapcityException { assert (network.getState() == State.Implementing) : "Why are we implementing " + network; long dcId = dest.getDataCenter().getId(); @@ -321,7 +280,8 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { //get physical network id long physicalNetworkId = _networkMgr.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType()); - NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, + NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), + network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, network.getDataCenterId(), physicalNetworkId); allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId()); @@ -337,10 +297,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { - assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling me when the traffic type is : " + network.getTrafficType(); + assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling" + + " me when the traffic type is : " + network.getTrafficType(); if (nic == null) { nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); @@ -351,15 +313,21 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (nic.getIp4Address() == null) { nic.setBroadcastUri(network.getBroadcastUri()); nic.setIsolationUri(network.getBroadcastUri()); - nic.setGateway(network.getGateway()); String guestIp = null; if (network.getSpecifyIpRanges()) { _networkMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIp()); } else { - guestIp = _networkMgr.acquireGuestIpAddress(network, nic.getRequestedIp()); - if (guestIp == null) { - throw new InsufficientVirtualNetworkCapcityException("Unable to acquire Guest IP address for network " + network, DataCenter.class, dc.getId()); + //if Vm is router vm, set ip4 to the network gateway + if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) { + guestIp = network.getGateway(); + } else { + nic.setGateway(network.getGateway()); + guestIp = _networkMgr.acquireGuestIpAddress(network, nic.getRequestedIp()); + if (guestIp == null) { + throw new InsufficientVirtualNetworkCapcityException("Unable to acquire Guest IP" + + " address for network " + network, DataCenter.class, dc.getId()); + } } nic.setIp4Address(guestIp); @@ -393,7 +361,8 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? "; @@ -412,8 +381,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { public void shutdown(NetworkProfile profile, NetworkOffering offering) { s_logger.debug("Releasing vnet for the network id=" + profile.getId()); if (profile.getBroadcastUri() != null && !offering.getSpecifyVlan()) { - _dcDao.releaseVnet(profile.getBroadcastUri().getHost(), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " + _dcDao.releaseVnet(profile.getBroadcastUri().getHost(), profile.getDataCenterId(), + profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); + EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " +profile.getBroadcastUri().getHost()+" for Network: "+profile.getId(), 0); profile.setBroadcastUri(null); } diff --git a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java new file mode 100644 index 00000000000..ab078743498 --- /dev/null +++ b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java @@ -0,0 +1,242 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.guru; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkProfile; +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.vpc.PrivateIpAddress; +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.network.vpc.Dao.PrivateIpDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.Nic.ReservationStrategy; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value = NetworkGuru.class) +public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { + private static final Logger s_logger = Logger.getLogger(PrivateNetworkGuru.class); + @Inject + protected ConfigurationManager _configMgr; + @Inject + protected PrivateIpDao _privateIpDao; + @Inject + protected NetworkManager _networkMgr; + + private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; + + protected PrivateNetworkGuru() { + super(); + } + + @Override + public boolean isMyTrafficType(TrafficType type) { + for (TrafficType t : _trafficTypes) { + if (t == type) { + return true; + } + } + return false; + } + + @Override + public TrafficType[] getSupportedTrafficType() { + return _trafficTypes; + } + + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + // This guru handles only system Guest network + if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated && offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of system Guest networks of type " + GuestType.Isolated + " in zone of type " + + NetworkType.Advanced); + return false; + } + } + + @Override + public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { + DataCenter dc = _configMgr.getZone(plan.getDataCenterId()); + if (!canHandle(offering, dc)) { + return null; + } + + NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), + State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); + if (userSpecified != null) { + if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || + (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { + throw new InvalidParameterValueException("cidr and gateway must be specified together."); + } + + if (userSpecified.getCidr() != null) { + network.setCidr(userSpecified.getCidr()); + network.setGateway(userSpecified.getGateway()); + } else { + throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in"); + } + + if (offering.getSpecifyVlan()) { + network.setBroadcastUri(userSpecified.getBroadcastUri()); + network.setState(State.Setup); + } + } else { + throw new CloudRuntimeException("Can't design network " + network + "; netmask/gateway must be passed in"); + + } + + return network; + } + + @Override + public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); + } + + PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + if (ip != null) { + _privateIpDao.releaseIpAddress(nic.getIp4Address(), nic.getNetworkId()); + } + nic.deallocate(); + } + + + @Override + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, + ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + + return network; + } + + @Override + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + NetworkOffering offering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (!canHandle(offering, dc)) { + return null; + } + + if (nic == null) { + nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); + } + + getIp(nic, dc, network); + + if (nic.getIp4Address() == null) { + nic.setStrategy(ReservationStrategy.Start); + } else { + nic.setStrategy(ReservationStrategy.Create); + } + + return nic; + } + + + protected void getIp(NicProfile nic, DataCenter dc, Network network) + throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException { + if (nic.getIp4Address() == null) { + PrivateIpVO ipVO = _privateIpDao.allocateIpAddress(network.getDataCenterId(), network.getId()); + String vlanTag = network.getBroadcastUri().getHost(); + String netmask = NetUtils.getCidrNetmask(network.getCidr()); + PrivateIpAddress ip = new PrivateIpAddress(ipVO, vlanTag, network.getGateway(), netmask, ipVO.getMacAddress()); + + nic.setIp4Address(ip.getIpAddress()); + nic.setGateway(ip.getGateway()); + nic.setNetmask(ip.getNetmask()); + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + nic.setFormat(AddressFormat.Ip4); + nic.setReservationId(String.valueOf(ip.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + } + + nic.setDns1(dc.getDns1()); + nic.setDns2(dc.getDns2()); + } + + + @Override + public void updateNicProfile(NicProfile profile, Network network) { + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + if (profile != null) { + profile.setDns1(dc.getDns1()); + profile.setDns2(dc.getDns2()); + } + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + if (nic.getIp4Address() == null) { + getIp(nic, _configMgr.getZone(network.getDataCenterId()), network); + nic.setStrategy(ReservationStrategy.Create); + } + } + + @Override + public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { + return true; + } + + @Override + public void shutdown(NetworkProfile profile, NetworkOffering offering) { + + } + + @Override + public boolean trash(Network network, NetworkOffering offering, Account owner) { + return true; + } + + @Override + public void updateNetworkProfile(NetworkProfile networkProfile) { + DataCenter dc = _configMgr.getZone(networkProfile.getDataCenterId()); + networkProfile.setDns1(dc.getDns1()); + networkProfile.setDns2(dc.getDns2()); + } +} diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index d26493872cd..d094445c2f8 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -132,7 +132,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(network.getDataCenterId()); @@ -172,7 +173,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) + throws InsufficientVirtualNetworkCapcityException { return network; } diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index a5d9a39c547..793698a6e1b 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -39,6 +39,8 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; import com.cloud.configuration.Config; @@ -128,6 +130,7 @@ import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; @Local(value = { ElasticLoadBalancerManager.class }) public class ElasticLoadBalancerManagerImpl implements @@ -185,6 +188,8 @@ public class ElasticLoadBalancerManagerImpl implements PhysicalNetworkServiceProviderDao _physicalProviderDao; @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject + NicDao _nicDao; String _name; @@ -224,7 +229,7 @@ public class ElasticLoadBalancerManagerImpl implements Pod pod = podId == null?null:_podDao.findById(podId); Map params = new HashMap( 1); - params.put(VirtualMachineProfile.Param.ReProgramNetwork, true); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); Account owner = _accountService.getActiveAccountByName("system", new Long(1)); DeployDestination dest = new DeployDestination(dc, pod, null, null); s_logger.debug("About to deploy ELB vm "); @@ -274,7 +279,7 @@ public class ElasticLoadBalancerManagerImpl implements } private void createApplyLoadBalancingRulesCommands( - List rules, DomainRouterVO elbVm, Commands cmds) { + List rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) { LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; @@ -293,7 +298,8 @@ public class ElasticLoadBalancerManagerImpl implements lbs[i++] = lb; } - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(),elbVm.getGuestIpAddress(),elbVm.getPrivateIpAddress()); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), + _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress(), null, null); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, elbVm.getPrivateIpAddress()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, @@ -310,9 +316,9 @@ public class ElasticLoadBalancerManagerImpl implements } protected boolean applyLBRules(DomainRouterVO elbVm, - List rules) throws ResourceUnavailableException { + List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, elbVm, cmds); + createApplyLoadBalancingRulesCommands(rules, elbVm, cmds, guestNetworkId); // Send commands to elbVm return sendCommandsToRouter(elbVm, cmds); } @@ -357,7 +363,7 @@ public class ElasticLoadBalancerManagerImpl implements lb, dstList, policyList); lbRules.add(loadBalancing); } - return applyLBRules(elbVm, lbRules); + return applyLBRules(elbVm, lbRules, network.getId()); } else if (elbVm.getState() == State.Stopped || elbVm.getState() == State.Stopping) { s_logger.debug("ELB VM is in " @@ -496,8 +502,9 @@ public class ElasticLoadBalancerManagerImpl implements List> networks = new ArrayList>(2); NicProfile guestNic = new NicProfile(); guestNic.setDefaultNic(true); - networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); networks.add(new Pair(controlConfig, null)); + networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); + VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId); @@ -512,8 +519,10 @@ public class ElasticLoadBalancerManagerImpl implements throw new CloudRuntimeException("Cannot find virtual router provider " + typeString + " as service provider " + provider.getId()); } - elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(), - template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), false, 0, false, RedundantState.UNKNOWN, _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm); + elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), + VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), false, 0, false, RedundantState.UNKNOWN, + _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm, null); elbVm.setRole(Role.LB); elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner); //TODO: create usage stats @@ -607,7 +616,7 @@ public class ElasticLoadBalancerManagerImpl implements IPAddressVO ipvo = _ipAddressDao.findById(ipId); ipvo.setAssociatedWithNetworkId(null); _ipAddressDao.update(ipvo.getId(), ipvo); - _networkMgr.releasePublicIpAddress(ipId, userId, caller); + _networkMgr.disassociatePublicIpAddress(ipId, userId, caller); _ipAddressDao.unassignIpAddress(ipId); } @@ -801,7 +810,17 @@ public class ElasticLoadBalancerManagerImpl implements @Override public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { DomainRouterVO elbVm = profile.getVirtualMachine(); - NetworkVO network = _networkDao.findById(elbVm.getNetworkId()); + + List elbNics = profile.getNics(); + Long guestNtwkId = null; + for (NicProfile routerNic : elbNics) { + if (routerNic.getTrafficType() == TrafficType.Guest) { + guestNtwkId = routerNic.getNetworkId(); + break; + } + } + + NetworkVO guestNetwork = _networkDao.findById(guestNtwkId); DataCenter dc = dest.getDataCenter(); @@ -842,12 +861,13 @@ public class ElasticLoadBalancerManagerImpl implements // ask elb vm to setup SSH on guest network buf.append(" sshonguest=true"); } + } controlNic = nic; } } - String domain = network.getNetworkDomain(); + String domain = guestNetwork.getNetworkDomain(); if (domain != null) { buf.append(" domain=" + domain); } @@ -879,8 +899,6 @@ public class ElasticLoadBalancerManagerImpl implements elbVm.setPublicIpAddress(nic.getIp4Address()); elbVm.setPublicNetmask(nic.getNetmask()); elbVm.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Guest) { - elbVm.setGuestIpAddress(nic.getIp4Address()); } else if (nic.getTrafficType() == TrafficType.Control) { elbVm.setPrivateIpAddress(nic.getIp4Address()); elbVm.setPrivateMacAddress(nic.getMacAddress()); @@ -911,6 +929,7 @@ public class ElasticLoadBalancerManagerImpl implements DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterIdToDeployIn()); NicProfile controlNic = null; + Long guestNetworkId = null; if(profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { // TODO this is a ugly to test hypervisor type here @@ -918,12 +937,15 @@ public class ElasticLoadBalancerManagerImpl implements for (NicProfile nic : profile.getNics()) { if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { controlNic = nic; + guestNetworkId = nic.getNetworkId(); } } } else { for (NicProfile nic : profile.getNics()) { if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { controlNic = nic; + } else if (nic.getTrafficType() == TrafficType.Guest) { + guestNetworkId = nic.getNetworkId(); } } } @@ -947,7 +969,7 @@ public class ElasticLoadBalancerManagerImpl implements s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of ELB vm " + elbVm + " start."); if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds); + createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId); } return true; @@ -974,7 +996,6 @@ public class ElasticLoadBalancerManagerImpl implements } - @Override public Long convertToId(String vmName) { if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, _elbVmNamePrefix)) { @@ -983,4 +1004,26 @@ public class ElasticLoadBalancerManagerImpl implements return VirtualMachineName.getSystemVmId(vmName); } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public void prepareStop(VirtualMachineProfile profile) { + + } } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index f3f72884fc1..83e79c28250 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -47,7 +47,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.ExternalLoadBalancerUsageManager; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; @@ -67,7 +66,7 @@ import com.cloud.network.dao.LBStickinessPolicyDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.element.NetworkElement; +import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.rules.FirewallManager; @@ -409,7 +408,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa UserVm vm = _vmDao.findById(instanceId); if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { - throw new InvalidParameterValueException("Invalid instance id: " + instanceId); + InvalidParameterValueException ex = new InvalidParameterValueException("Invalid instance id specified"); + ex.addProxyObject(vm, instanceId, "instanceId"); + throw ex; } _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller); @@ -429,7 +430,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } if (nicInSameNetwork == null) { - throw new InvalidParameterValueException("VM " + instanceId + " cannot be added because it doesn't belong in the same network."); + InvalidParameterValueException ex = new InvalidParameterValueException("VM " + instanceId + " cannot be added because it doesn't belong in the same network."); + ex.addProxyObject(vm, instanceId, "instanceId"); + throw ex; } if (s_logger.isDebugEnabled()) { @@ -473,7 +476,10 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } if(!success){ - throw new CloudRuntimeException("Failed to add load balancer rule id " + loadBalancerId + " for vms " + instanceIds); + CloudRuntimeException ex = new CloudRuntimeException("Failed to add specified loadbalancerruleid for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + // TBD: Also pack in the instanceIds in the exception using the right VO object or table name. + throw ex; } return success; @@ -510,7 +516,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (!applyLoadBalancerConfig(loadBalancerId)) { s_logger.warn("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds); - throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds); + CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + throw ex; } success = true; } catch (ResourceUnavailableException e) { @@ -530,7 +538,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); } if(!success){ - throw new CloudRuntimeException("Failed to remove load balancer rule id " + loadBalancerId + " for vms " + instanceIds); + CloudRuntimeException ex = new CloudRuntimeException("Failed to remove specified load balancer rule id for vms " + instanceIds); + ex.addProxyObject(loadBalancer, loadBalancerId, "loadBalancerId"); + throw ex; } return success; } @@ -665,7 +675,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa s_logger.warn("Unable to remove firewall rule id=" + lb.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); success = false; } else { - _firewallDao.remove(lb.getId()); + _firewallMgr.removeRule(lb); } _elbMgr.handleDeleteLoadBalancerRule(lb, callerUserId, caller); @@ -696,30 +706,47 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } Long ipAddrId = lb.getSourceIpAddressId(); - IPAddressVO ipAddressVo = null; + IPAddressVO ipAddressVO = null; if (ipAddrId != null) { - ipAddressVo = _ipAddressDao.findById(ipAddrId); + ipAddressVO = _ipAddressDao.findById(ipAddrId); // Validate ip address - if (ipAddressVo == null) { - throw new InvalidParameterValueException("Unable to create load balance rule; ip id=" + ipAddrId + " doesn't exist in the system"); - } else if (ipAddressVo.isOneToOneNat()) { - throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipAddressVo.getAddress()); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Unable to create load balance rule; ip id=" + ipAddrId + "" + + " doesn't exist in the system"); + } else if (ipAddressVO.isOneToOneNat()) { + throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipAddressVO.getAddress()); } - - _networkMgr.checkIpForService(ipAddressVo, Service.Lb); } LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId()); + boolean performedIpAssoc = false; if (result == null) { IpAddress ip = null; Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId()); NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); - if (off.getElasticLb() && ipAddressVo == null) { + if (off.getElasticLb() && ipAddressVO == null) { ip = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false); lb.setSourceIpAddressId(ip.getId()); } + try { + if (ipAddressVO != null) { + if (ipAddressVO.getAssociatedWithNetworkId() == null) { + //set networkId just for verification purposes + ipAddressVO.setAssociatedWithNetworkId(lb.getNetworkId()); + _networkMgr.checkIpForService(ipAddressVO, Service.Lb); + + s_logger.debug("The ip is not associated with the network id="+ lb.getNetworkId() + " so assigning"); + ipAddressVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId()); + boolean perfomedIpAssoc = true; + } + _networkMgr.checkIpForService(ipAddressVO, Service.Lb); + } + + if (lb.getSourceIpAddressId() == null) { + throw new CloudRuntimeException("No ip address is defined to assign the LB to"); + } result = createLoadBalancer(lb, openFirewall); } catch (Exception ex) { s_logger.warn("Failed to create load balancer due to ", ex); @@ -731,6 +758,15 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa s_logger.debug("Releasing system IP address " + ip + " as corresponding lb rule failed to create"); _networkMgr.handleSystemIpRelease(ip); } + // release ip address if ipassoc was perfored + if (performedIpAssoc) { + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + ip = _ipAddressDao.findById(ip.getId()); + if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + s_logger.debug("Releasing VPC ip address " + ip + " as LB rule failed to create"); + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } + } } } @@ -750,19 +786,25 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa long sourceIpId = lb.getSourceIpAddressId(); IPAddressVO ipAddr = _ipAddressDao.findById(sourceIpId); - Long networkId = ipAddr.getSourceNetworkId(); // make sure ip address exists if (ipAddr == null || !ipAddr.readyToUse()) { - throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id" + sourceIpId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id specified"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + throw ex; } else if (ipAddr.isOneToOneNat()) { - throw new InvalidParameterValueException("Unable to create load balancer rule; ip id=" + sourceIpId + " has static nat enabled"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule; specified sourceip id has static nat enabled"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + throw ex; } - _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), Purpose.LoadBalancing, FirewallRuleType.User); + _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), + Purpose.LoadBalancing, FirewallRuleType.User); - networkId = ipAddr.getAssociatedWithNetworkId(); + Long networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { - throw new InvalidParameterValueException("Unable to create load balancer rule ; ip id=" + sourceIpId + " is not associated with any network"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network"); + ex.addProxyObject(ipAddr, sourceIpId, "sourceIpId"); + throw ex; } NetworkVO network = _networkDao.findById(networkId); @@ -771,8 +813,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa // verify that lb service is supported by the network if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Lb)) { - throw new InvalidParameterValueException("LB service is not supported in network id= " + networkId); - + InvalidParameterValueException ex = new InvalidParameterValueException("LB service is not supported in specified network id"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } Transaction txn = Transaction.currentTxn(); @@ -784,13 +827,14 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa newRule = _lbDao.persist(newRule); if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId()); + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), + lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); } boolean success = true; try { - _firewallMgr.detectRulesConflict(newRule, ipAddr); + _firewallMgr.detectRulesConflict(newRule); if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } @@ -812,7 +856,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa txn.start(); _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - _lbDao.remove(newRule.getId()); + removeLBRule(newRule); txn.commit(); } @@ -867,7 +911,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa boolean checkForReleaseElasticIp = false; txn.start(); if (lb.getState() == FirewallRule.State.Revoke) { - _lbDao.remove(lb.getId()); + removeLBRule(lb); s_logger.debug("LB " + lb.getId() + " is successfully removed"); checkForReleaseElasticIp = true; } else if (lb.getState() == FirewallRule.State.Add) { @@ -931,7 +975,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa boolean success = true; if (ip.getSystem()) { s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule"); - if (!_networkMgr.releasePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { + if (!_networkMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); success = false; } else { @@ -1260,4 +1304,17 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa return _lbDao.findById(lbId); } + @DB + protected void removeLBRule(LoadBalancerVO rule) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + _lbDao.remove(rule.getId()); + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); + if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } + + txn.commit(); + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 052cd0f7389..b2c1cd02df1 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -22,9 +22,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VpnUser; -import com.cloud.network.Network.Provider; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; import com.cloud.user.Account; @@ -33,7 +33,6 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; -import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; /** @@ -58,35 +57,41 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA * @param routers TODO * */ - boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException; - - boolean getRouterStatistics(long vmId, Map netStats, Map diskStats); - - List getRouters(long accountId, long zoneId); + boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, + List routers) throws ResourceUnavailableException; + + List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + Map params, boolean isRedundant) throws InsufficientCapacityException, + ResourceUnavailableException, ConcurrentOperationException; - List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; + boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException; - boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; - - boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; + boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException; - boolean associateIP (Network network, final List ipAddress, List routers) throws ResourceUnavailableException; + boolean associateIP (Network network, final List ipAddress, + List routers) throws ResourceUnavailableException; - boolean applyFirewallRules(Network network, final List rules, List routers) throws ResourceUnavailableException; + boolean applyFirewallRules(Network network, final List rules, + List routers) throws ResourceUnavailableException; List getRoutersForNetwork(long networkId); - String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException; + String[] applyVpnUsers(Network network, List users, List routers) + throws ResourceUnavailableException; - VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) throws ConcurrentOperationException, ResourceUnavailableException; + VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) + throws ConcurrentOperationException, ResourceUnavailableException; String getDnsBasicZoneUpdate(); - boolean applyStaticNats(Network network, final List rules, List routers) throws ResourceUnavailableException; + boolean applyStaticNats(Network network, final List rules, List routers) + throws ResourceUnavailableException; - boolean applyDhcpEntry(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; + boolean applyDhcpEntry(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, + List routers) throws ResourceUnavailableException; - boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; - - long getDefaultVirtualRouterServiceOfferingId(); + boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, + List routers) throws ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d044d4f3525..6bbc24cc546 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -61,14 +61,18 @@ import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.commands.UpgradeRouterCmd; @@ -95,10 +99,10 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; @@ -125,6 +129,9 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGatewayVO; import com.cloud.network.SshKeysDistriMonitor; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VirtualRouterProvider; @@ -132,7 +139,6 @@ import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.VpnUser; import com.cloud.network.VpnUserVO; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -140,6 +146,9 @@ import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.lb.LoadBalancingRule; @@ -163,13 +172,11 @@ import com.cloud.resource.ResourceManager; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -197,6 +204,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -214,13 +222,13 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; /** * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack. */ @Local(value = { VirtualNetworkApplianceManager.class, VirtualNetworkApplianceService.class }) -public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, VirtualMachineGuru, Listener { +public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, + VirtualMachineGuru, Listener { private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class); String _name; @@ -245,24 +253,16 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject UserStatisticsDao _userStatsDao = null; @Inject - VolumeDao _volsDao = null; - @Inject HostDao _hostDao = null; @Inject - EventDao _eventDao = null; - @Inject ConfigurationDao _configDao; @Inject HostPodDao _podDao = null; @Inject - VMTemplateHostDao _vmTemplateHostDao = null; - @Inject UserStatsLogDao _userStatsLogDao = null; @Inject AgentManager _agentMgr; @Inject - StorageManager _storageMgr; - @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @@ -273,8 +273,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject UserVmDao _userVmDao; @Inject - FirewallRulesDao _firewallRulesDao; - @Inject UserStatisticsDao _statsDao = null; @Inject NetworkOfferingDao _networkOfferingDao = null; @@ -299,14 +297,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject RemoteAccessVpnDao _vpnDao; @Inject - VMInstanceDao _instanceDao; - @Inject NicDao _nicDao; @Inject VolumeDao _volumeDao = null; @Inject - FirewallRulesCidrsDao _firewallCidrsDao; - @Inject UserVmDetailsDao _vmDetailsDao; @Inject ClusterDao _clusterDao; @@ -318,6 +312,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian VirtualRouterProviderDao _vrProviderDao; @Inject ManagementServerHostDao _msHostDao; + @Inject + Site2SiteCustomerGatewayDao _s2sCustomerGatewayDao; + @Inject + Site2SiteVpnGatewayDao _s2sVpnGatewayDao; + @Inject + Site2SiteVpnConnectionDao _s2sVpnConnectionDao; int _routerRamSize; int _routerCpuMHz; @@ -328,7 +328,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int _routerStatsInterval = 300; int _routerCheckInterval = 30; - private ServiceOfferingVO _offering; + protected ServiceOfferingVO _offering; private String _dnsBasicZoneUpdates = "all"; private boolean _disable_rp_filter = false; @@ -344,11 +344,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Account _systemAcct; - @Override - public List getRouters(long accountId, long dataCenterId) { - return _routerDao.findBy(accountId, dataCenterId); - } - @Override public boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey) { ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey); @@ -426,7 +421,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service // offering if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { - throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.getUseLocalStorage() + " is different from " + throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + + newServiceOffering.getUseLocalStorage() + " is different from " + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage()); } @@ -500,70 +496,36 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian final Transaction txn = Transaction.currentTxn(); try { txn.start(); - final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); + //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNtwkId : routerGuestNtwkIds) { + final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), + guestNtwkId, null, router.getId(), router.getType().toString()); if (userStats != null) { - final RebootAnswer sa = (RebootAnswer) answer; - final Long received = sa.getBytesReceived(); - long netBytes = 0; - if (received != null) { - if (received.longValue() >= userStats.getCurrentBytesReceived()) { - netBytes = received.longValue(); - } else { - netBytes = userStats.getCurrentBytesReceived() + received; - } - } else { - netBytes = userStats.getCurrentBytesReceived(); - } + final long currentBytesRcvd = userStats.getCurrentBytesReceived(); userStats.setCurrentBytesReceived(0); - userStats.setNetBytesReceived(userStats.getNetBytesReceived() + netBytes); + userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); - final Long sent = sa.getBytesSent(); - - if (sent != null) { - if (sent.longValue() >= userStats.getCurrentBytesSent()) { - netBytes = sent.longValue(); - } else { - netBytes = userStats.getCurrentBytesSent() + sent; - } - } else { - netBytes = userStats.getCurrentBytesSent(); - } - userStats.setNetBytesSent(userStats.getNetBytesSent() + netBytes); + final long currentBytesSent = userStats.getCurrentBytesSent(); userStats.setCurrentBytesSent(0); + userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); _userStatsDao.update(userStats.getId(), userStats); s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); } else { s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn()); } + } + txn.commit(); } catch (final Exception e) { txn.rollback(); - throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e); + throw new CloudRuntimeException("Problem updating stats after reboot/stop ", e); } } - @Override - public boolean getRouterStatistics(final long vmId, final Map netStats, final Map diskStats) { - final DomainRouterVO router = _routerDao.findById(vmId); - - if (router == null || router.getState() != State.Running || router.getHostId() == null) { - return true; - } - - /* - * final GetVmStatsCommand cmd = new GetVmStatsCommand(router, router.getInstanceName()); final Answer answer = - * _agentMgr.easySend(router.getHostId(), cmd); if (answer == null) { return false; } - * - * final GetVmStatsAnswer stats = (GetVmStatsAnswer)answer; - * - * netStats.putAll(stats.getNetworkStats()); diskStats.putAll(stats.getDiskStats()); - */ - - return true; - } - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) - public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { Account caller = UserContext.current().getCaller(); // verify parameters @@ -577,7 +539,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Can reboot domain router only in Running state if (router == null || router.getState() != State.Running) { s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); - throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), + DataCenter.class, router.getDataCenterIdToDeployIn()); } UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); @@ -640,7 +603,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this); boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); - _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); + _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, + null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); _offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); @@ -708,7 +672,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian endDate = cal.getTime().getTime(); } - _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); + _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), + (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); if (_routerCheckInterval > 0) { _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS); @@ -736,12 +701,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return VirtualMachineName.getRouterId(vmName); } - private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, - String vmInstanceName, long vmId, String publicKey) { + private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, + String serviceOffering, String zoneName, String guestIpAddress, String vmName, + String vmInstanceName, long vmId, String publicKey, long guestNetworkId) { VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); @@ -755,7 +721,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (dcVo.getNetworkType() == NetworkType.Basic) { cmd.addVmData("metadata", "public-ipv4", guestIpAddress); cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vmName)); - }else + } else { if (router.getPublicIpAddress() == null) { cmd.addVmData("metadata", "public-ipv4", guestIpAddress); @@ -792,68 +758,91 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (DomainRouterVO router : routers) { String privateIP = router.getPrivateIpAddress(); + if (privateIP != null) { - final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName()); - UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); - NetworkUsageAnswer answer = null; - try { - answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); - } catch (Exception e) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); - continue; - } + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); - if (answer != null) { - if (!answer.getResult()) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + for (Long guestNtwkId : routerGuestNtwkIds) { + boolean forVpc = router.getVpcId() != null; + Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); + Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), + guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); + final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), + forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + NetworkUsageAnswer answer = null; + try { + answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); continue; } - Transaction txn = Transaction.open(Transaction.CLOUD_DB); - try { - if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { - s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + + if (answer != null) { + if (!answer.getResult()) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); continue; } - txn.start(); - UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); - if (stats == null) { - s_logger.warn("unable to find stats for account: " + router.getAccountId()); - continue; - } - - if(previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); - continue; - } - - if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesReceived() - + " Stored: " + stats.getCurrentBytesReceived()); + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { + s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + continue; } - stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); - } - stats.setCurrentBytesReceived(answer.getBytesReceived()); - if (stats.getCurrentBytesSent() > answer.getBytesSent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesSent() - + " Stored: " + stats.getCurrentBytesSent()); + txn.start(); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + continue; } - stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + + if(previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + continue; + } + + if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answer.getBytesReceived()); + if (stats.getCurrentBytesSent() > answer.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answer.getBytesSent()); + _statsDao.update(stats.getId(), stats); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + } finally { + txn.close(); } - stats.setCurrentBytesSent(answer.getBytesSent()); - _statsDao.update(stats.getId(), stats); - txn.commit(); - } catch (Exception e) { - txn.rollback(); - s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); - } finally { - txn.close(); } - } } } + } } catch (Exception e) { s_logger.warn("Error while collecting network stats", e); } @@ -909,9 +898,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } finally { scanLock.releaseRef(); } - } - } @@ -1038,12 +1025,15 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (!router.getIsRedundantRouter()) { continue; } - long networkId = router.getNetworkId(); - if (checkedNetwork.contains(networkId)) { + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { + if (checkedNetwork.contains(routerGuestNtwkId)) { continue; } - checkedNetwork.add(networkId); - List checkingRouters = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER); + checkedNetwork.add(routerGuestNtwkId); + List checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER); if (checkingRouters.size() != 2) { continue; } @@ -1072,13 +1062,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } } + } private void checkDuplicateMaster(List routers) { Map networkRouterMaps = new HashMap(); for (DomainRouterVO router : routers) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { if (router.getRedundantState() == RedundantState.MASTER) { - if (networkRouterMaps.containsKey(router.getNetworkId())) { - DomainRouterVO dupRouter = networkRouterMaps.get(router.getNetworkId()); + if (networkRouterMaps.containsKey(routerGuestNtwkId)) { + DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId); String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName(); String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. "; @@ -1086,7 +1080,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context); } else { - networkRouterMaps.put(router.getNetworkId(), router); + networkRouterMaps.put(routerGuestNtwkId, router); + } } } } @@ -1095,7 +1090,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public void run() { try { - final List routers = _routerDao.listVirtualByHostId(null); + final List routers = _routerDao.listIsolatedByHostId(null); s_logger.debug("Found " + routers.size() + " routers. "); updateRoutersRedundantState(routers); @@ -1110,9 +1105,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - public static boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)); - } + private final int DEFAULT_PRIORITY = 100; private final int DEFAULT_DELTA = 2; @@ -1165,7 +1158,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (HostVO h : hosts) { if (h.getStatus() == Status.Up) { - s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router for OVM"); + s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + + cv.getId() + " to start domain router for OVM"); return h.getHypervisorType(); } } @@ -1173,51 +1167,33 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String errMsg = "Cannot find an available cluster in Pod " + podId - + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod with Ovm cluster. And there is at least one host in UP status in that cluster."; + + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, " + + "please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod" + + " with Ovm cluster. And there is at least one host in UP status in that cluster."; throw new CloudRuntimeException(errMsg); } @DB - protected List findOrDeployVirtualRouters(Network guestNetwork, DeployDestination dest, Account owner, boolean isRedundant, Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + boolean isRedundant, Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { - Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); - if (network == null) { - throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); - } + assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || + guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " + + guestNetwork; + assert guestNetwork.getTrafficType() == TrafficType.Guest; - long dcId = dest.getDataCenter().getId(); - DataCenterDeployment plan = new DataCenterDeployment(dcId); - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) && guestNetwork.getTrafficType() == TrafficType.Guest; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (isRedundant && !publicNetwork) { - s_logger.error("Didn't support redundant virtual router without public network!"); - return null; - } - List routers; - Long podId = null; - if (isPodBased) { - Pod pod = dest.getPod(); - if (pod != null) { - podId = pod.getId(); - } - } - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - } else { - if (isPodBased && podId != null) { - routers = _routerDao.listByNetworkAndPodAndRole(guestNetwork.getId(), podId, Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId, podId, null, null, null, null); - } else { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId); - } - } - try { + //1) Get deployment plan and find out the list of routers + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || + _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) + && guestNetwork.getTrafficType() == TrafficType.Guest; + Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + + //2) Figure out required routers count int routerCount = 1; if (isRedundant) { routerCount = 2; @@ -1231,7 +1207,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ - if (routers.size() >= routerCount || (isPodBased && podId == null)) { + if (routers.size() >= routerCount || (isPodBased)) { return routers; } @@ -1239,89 +1215,95 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.error("Too much redundant routers!"); } - NicProfile defaultNic = new NicProfile(); - //if source nat service is supported by the network, get the source nat ip address - if (publicNetwork) { - PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddress(owner, guestNetwork, _accountMgr.getSystemUser().getId()); - defaultNic.setDefaultNic(true); - defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); - defaultNic.setGateway(sourceNatIp.getGateway()); - defaultNic.setNetmask(sourceNatIp.getNetmask()); - defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setDeviceId(2); + Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); + if (network == null) { + throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); } + try { + //Check if providers are supported in the physical networks + VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); + } + + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } + + //Check if public network has to be set on VR + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { + publicNetwork = true; + } + if (isRedundant && !publicNetwork) { + s_logger.error("Didn't support redundant virtual router without public network!"); + return null; + } + + Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + + PublicIp sourceNatIp = null; + if (publicNetwork) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + } + + //Check if control network has to be set on VR + boolean controlNetwork = true; + if ( dest.getDataCenter().getNetworkType() == NetworkType.Basic ) { + // in basic mode, use private network as control network + controlNetwork = false; + } + + //3) deploy virtual router(s) int count = routerCount - routers.size(); - for (int i = 0; i < count; i++) { - long id = _routerDao.getNextInSequence(Long.class, "id"); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating the router " + id); + DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, + null, sourceNatIp, publicNetwork, controlNetwork, guestNetwork, new Pair(publicNetwork, sourceNatIp)); + //add router to router network map + if (!_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + _routerDao.addRouterToGuestNetwork(routerVO, network); + } + routers.add(router); + } + } finally { + if (network != null) { + _networkDao.releaseFromLockTable(network.getId()); + } + } + return routers; } - DomainRouterVO router = null; + protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, + Long vpcId, PublicIp sourceNatIp, boolean setupPublicNetwork, boolean setupControlNetwork, Network guestNetwork, + Pair publicNetwork) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + long id = _routerDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the router " + id + " in datacenter " + dest.getDataCenter()); + } + + //1) Create router networks + List> networks = createRouterNetworks(owner, isRedundant, plan, setupControlNetwork, + guestNetwork, publicNetwork); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); - NetworkOfferingVO controlOffering = offerings.get(0); - NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); - List> networks = new ArrayList>(3); - if (publicNetwork) { - NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); - List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); - networks.add(new Pair(publicNetworks.get(0), defaultNic)); - } - - String defaultNetworkStartIp = null; - if (guestNetwork.getCidr() != null && !publicNetwork) { - String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); - if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { - defaultNetworkStartIp = startIp; - } else if (s_logger.isDebugEnabled()){ - s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + " is already allocated, can't use it for domain router; will get random ip address from the range"); - } - } - - NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); - if (publicNetwork) { - if (isRedundant) { - gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); - } else { - gatewayNic.setIp4Address(guestNetwork.getGateway()); - } - gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); - gatewayNic.setMode(guestNetwork.getMode()); - String gatewayCidr = guestNetwork.getCidr(); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - } else { - gatewayNic.setDefaultNic(true); - } - - networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); - networks.add(new Pair(controlConfig, null)); - - Long offering_id = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offering_id == null) { - offering_id = _offering.getId(); - } - VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); - } - ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(offering_id); - - //Router is the network element, we don't know the hypervisor type yet. + //2) Router is the network element, we don't know the hypervisor type yet. //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up List supportedHypervisors = new ArrayList(); HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); @@ -1336,20 +1318,22 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian supportedHypervisors.add(dest.getCluster().getHypervisorType()); } } else { - supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, podId); + supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); } if (supportedHypervisors.isEmpty()) { - if (podId != null) { - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the pod ", Pod.class, podId); + if (plan.getPodId() != null) { + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the pod ", Pod.class, plan.getPodId()); } - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); } int allocateRetry = 0; int startRetry = 0; - - + DomainRouterVO router = null; for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { HypervisorType hType = iter.next(); try { @@ -1367,8 +1351,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian offerHA = false; } - router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), - template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), isRedundant, 0, false, RedundantState.UNKNOWN, offerHA, false); + router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), + VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), isRedundant, 0, false, + RedundantState.UNKNOWN, offerHA, false, vpcId); router.setRole(Role.VIRTUAL_ROUTER); router = _itMgr.allocate(router, template, routerOffering, networks, plan, null, owner); } catch (InsufficientCapacityException ex) { @@ -1387,7 +1373,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian break; } catch (InsufficientCapacityException ex) { if (startRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", destroying it and recreating one more time"); + s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", " + + "destroying it and recreating one more time"); //destroy the router destroyRouter(router.getId()); continue; @@ -1399,18 +1386,118 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - routers.add(router); - - } - } finally { - if (network != null) { - _networkDao.releaseFromLockTable(network.getId()); - } - } - return routers; + return router; } - private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) throws StorageUnavailableException, InsufficientCapacityException, + protected List> createRouterNetworks(Account owner, boolean isRedundant, + DeploymentPlan plan, boolean setupControlNetwork, Network guestNetwork, Pair publicNetwork) throws ConcurrentOperationException, + InsufficientAddressCapacityException { + + + boolean setupPublicNetwork = false; + if (publicNetwork != null) { + setupPublicNetwork = publicNetwork.first(); + } + + //Form networks + List> networks = new ArrayList>(3); + + //1) Guest network + boolean hasGuestNetwork = false; + if (guestNetwork != null) { + s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); + String defaultNetworkStartIp = null; + if (guestNetwork.getCidr() != null && !setupPublicNetwork) { + String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); + if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { + defaultNetworkStartIp = startIp; + } else if (s_logger.isDebugEnabled()){ + s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ip address from the range"); + } + } + + NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); + if (setupPublicNetwork) { + if (isRedundant) { + gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); + } else { + gatewayNic.setIp4Address(guestNetwork.getGateway()); + } + gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); + gatewayNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + } else { + gatewayNic.setDefaultNic(true); + } + networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); + hasGuestNetwork = true; + } + + //2) Control network + if (setupControlNetwork) { + s_logger.debug("Adding nic for Virtual Router in Control network "); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); + NetworkOfferingVO controlOffering = offerings.get(0); + NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + networks.add(new Pair(controlConfig, null)); + } + + //3) Public network + if (setupPublicNetwork) { + PublicIp sourceNatIp = publicNetwork.second(); + s_logger.debug("Adding nic for Virtual Router in Public network "); + //if source nat service is supported by the network, get the source nat ip address + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); + defaultNic.setGateway(sourceNatIp.getGateway()); + defaultNic.setNetmask(sourceNatIp.getNetmask()); + defaultNic.setMacAddress(sourceNatIp.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + if (hasGuestNetwork) { + defaultNic.setDeviceId(2); + } + NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); + List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); + networks.add(new Pair(publicNetworks.get(0), defaultNic)); + } + + + return networks; + } + + + protected Pair> getDeploymentPlanAndRouters(boolean isPodBased, + DeployDestination dest, long guestNetworkId) { + long dcId = dest.getDataCenter().getId(); + List routers = null; + DeploymentPlan plan = new DataCenterDeployment(dcId); + if (isPodBased) { + Pod pod = dest.getPod(); + Long podId = null; + if (pod != null) { + podId = pod.getId(); + } else { + throw new CloudRuntimeException("Pod id is expected in deployment destination"); + } + routers = _routerDao.listByNetworkAndPodAndRole(guestNetworkId, podId, Role.VIRTUAL_ROUTER); + plan = new DataCenterDeployment(dcId, podId, null, null, null, null); + } else { + routers = _routerDao.listByNetworkAndRole(guestNetworkId, Role.VIRTUAL_ROUTER); + } + + return new Pair>(plan, routers); + } + + + private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { @@ -1477,23 +1564,18 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, + public List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + Map params, boolean isRedundant) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } - if(dest != null){ - if (s_logger.isDebugEnabled()) { - s_logger.debug("Starting a router for " + guestNetwork + " in datacenter:" + dest.getDataCenter()); - } - } + List routers = findOrDeployVirtualRouterInGuestNetwork + (guestNetwork, dest, owner, isRedundant, params); - assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " - + guestNetwork; - assert guestNetwork.getTrafficType() == TrafficType.Guest; + return startRouters(params, routers); + } - List routers = findOrDeployVirtualRouters(guestNetwork, dest, owner, isRedundant, params); + protected List startRouters(Map params, List routers) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException { List runningRouters = null; if (routers != null) { @@ -1522,97 +1604,53 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, + ReservationContext context) { + + boolean dnsProvided = true; + boolean dhcpProvided = true; + boolean publicNetwork = false; + DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); + _dcDao.loadDetails(dc); + //1) Set router details DomainRouterVO router = profile.getVirtualMachine(); Map details = _vmDetailsDao.findDetails(router.getId()); router.setDetails(details); - NetworkVO network = _networkDao.findById(router.getNetworkId()); - String type = null; - String dhcpRange = null; - String rpFilter = " "; - DataCenter dc = dest.getDataCenter(); - DataCenterVO dcVO = _dcDao.findById(dc.getId()); - _dcDao.loadDetails(dcVO); - - if (dc.getNetworkType() == NetworkType.Advanced) { - String cidr = network.getCidr(); - if (cidr != null) { - dhcpRange = NetUtils.getDhcpRange(cidr); - } - } - - String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); - if (rpValue != null && rpValue.equalsIgnoreCase("true")) { - _disable_rp_filter = true; - }else - { - _disable_rp_filter = false; - } - - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (!publicNetwork) { - type = "dhcpsrvr"; - } else { - type = "router"; - if (_disable_rp_filter) { - rpFilter=" disable_rp_filter=true"; - } - } + //2) Prepare boot loader elements related with Control network StringBuilder buf = profile.getBootArgsBuilder(); - buf.append(" template=domP type=" + type+rpFilter); + buf.append(" template=domP"); buf.append(" name=").append(profile.getHostName()); if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); } - boolean isRedundant = router.getIsRedundantRouter(); - if (isRedundant) { - buf.append(" redundant_router=1"); - List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - try { - int priority = getUpdatedPriority(network, routers, router); - router.setPriority(priority); - } catch (InsufficientVirtualNetworkCapcityException e) { - s_logger.error("Failed to get update priority!", e); - throw new CloudRuntimeException("Failed to get update priority!"); - } - } NicProfile controlNic = null; String defaultDns1 = null; String defaultDns2 = null; - for (NicProfile nic : profile.getNics()) { int deviceId = nic.getDeviceId(); buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + if (nic.isDefaultNic()) { buf.append(" gateway=").append(nic.getGateway()); defaultDns1 = nic.getDns1(); defaultDns2 = nic.getDns2(); - - if (dc.getNetworkType() == NetworkType.Basic) { - long cidrSize = NetUtils.getCidrSize(nic.getNetmask()); - String cidr = NetUtils.getCidrSubNet(nic.getGateway(), cidrSize); - if (cidr != null) { - dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); - } - } } + if (nic.getTrafficType() == TrafficType.Management) { buf.append(" localgw=").append(dest.getPod().getGateway()); } else if (nic.getTrafficType() == TrafficType.Control) { - + controlNic = nic; // DOMR control command is sent over management server in VMware if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { if (s_logger.isInfoEnabled()) { - s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmt_host); } @@ -1633,47 +1671,62 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // ask domR to setup SSH on guest network buf.append(" sshonguest=true"); } - } - controlNic = nic; - } else if (nic.getTrafficType() == TrafficType.Guest && isRedundant) { - Network net = _networkMgr.getNetwork(nic.getNetworkId()); - buf.append(" guestgw=").append(net.getGateway()); - String brd = NetUtils.long2Ip(NetUtils.ip2Long(nic.getIp4Address()) | ~NetUtils.ip2Long(nic.getNetmask())); - buf.append(" guestbrd=").append(brd); - buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(nic.getNetmask())); - buf.append(" router_pr=").append(router.getPriority()); + } + } else if (nic.getTrafficType() == TrafficType.Guest) { + dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter); + dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter); + //build bootloader parameter for the guest + buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router)); + } else if (nic.getTrafficType() == TrafficType.Public) { + publicNetwork = true; } } - if (dhcpRange != null) { - buf.append(" dhcprange=" + dhcpRange); + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); + } + + String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); + if (rpValue != null && rpValue.equalsIgnoreCase("true")) { + _disable_rp_filter = true; + }else { + _disable_rp_filter = false; } - String domain = network.getNetworkDomain(); - if (domain != null) { - buf.append(" domain=" + domain); + + String rpFilter = " "; + String type = null; + if (router.getVpcId() != null) { + type = "vpcrouter"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + } else if (!publicNetwork) { + type = "dhcpsrvr"; + } else { + type = "router"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; } - String domain_suffix = dcVO.getDetail(ZoneConfig.DnsSearchOrder.getName()); + } + + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + + buf.append(" type=" + type + rpFilter); + + String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName()); if (domain_suffix != null) { buf.append(" dnssearchorder=").append(domain_suffix); } -// if (!network.isDefault() && network.getGuestType() == Network.GuestType.Shared) { -// buf.append(" defaultroute=false"); -// -// String virtualNetworkElementNicIP = _networkMgr.getIpOfNetworkElementInVirtualNetwork(network.getAccountId(), network.getDataCenterId()); -// if (network.getGuestType() != Network.GuestType.Shared && virtualNetworkElementNicIP != null) { -// defaultDns1 = virtualNetworkElementNicIP; -// } else { -// s_logger.debug("No Virtual network found for account id=" + network.getAccountId() + " so setting dns to the dns of the network id=" + network.getId()); -// } -// } else { -// buf.append(" defaultroute=true"); -// } - - boolean dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter); - boolean dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter); - /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response to return DNS server rather than + if (profile.getHypervisorType() == HypervisorType.VMware) { + buf.append(" extra_pubnics=" + _routerExtraPublicNics); + } + + /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response + * to return DNS server rather than * virtual router itself. */ if (dnsProvided || dhcpProvided) { buf.append(" dns1=").append(defaultDns1); @@ -1693,23 +1746,93 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - if(profile.getHypervisorType() == HypervisorType.VMware) { - buf.append(" extra_pubnics=" + _routerExtraPublicNics); - } - if (s_logger.isDebugEnabled()) { s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); } - if (controlNic == null) { - throw new CloudRuntimeException("Didn't start a control port"); + return true; } - return true; + + protected StringBuilder createGuestBootLoadArgs(NicProfile guestNic, String defaultDns1, + String defaultDns2, DomainRouterVO router) { + long guestNetworkId = guestNic.getNetworkId(); + NetworkVO guestNetwork = _networkDao.findById(guestNetworkId); + String dhcpRange = null; + DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId()); + + StringBuilder buf = new StringBuilder(); + + boolean isRedundant = router.getIsRedundantRouter(); + if (isRedundant) { + buf.append(" redundant_router=1"); + List routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); + try { + int priority = getUpdatedPriority(guestNetwork, routers, router); + router.setPriority(priority); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.error("Failed to get update priority!", e); + throw new CloudRuntimeException("Failed to get update priority!"); + } + Network net = _networkMgr.getNetwork(guestNic.getNetworkId()); + buf.append(" guestgw=").append(net.getGateway()); + String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); + buf.append(" guestbrd=").append(brd); + buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getNetmask())); + buf.append(" router_pr=").append(router.getPriority()); + } + + //setup network domain + String domain = guestNetwork.getNetworkDomain(); + if (domain != null) { + buf.append(" domain=" + domain); + } + + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + if (guestNic.isDefaultNic()) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + + if (dhcpRange != null) { + buf.append(" dhcprange=" + dhcpRange); + } + + return buf; + } + + + protected String getGuestDhcpRange(NicProfile guestNic, Network guestNetwork, DataCenter dc) { + String dhcpRange = null; + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + return dhcpRange; } @Override - public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { DomainRouterVO router = profile.getVirtualMachine(); List nics = profile.getNics(); @@ -1718,8 +1841,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian router.setPublicIpAddress(nic.getIp4Address()); router.setPublicNetmask(nic.getNetmask()); router.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Guest) { - router.setGuestIpAddress(nic.getIp4Address()); } else if (nic.getTrafficType() == TrafficType.Control) { router.setPrivateIpAddress(nic.getIp4Address()); router.setPrivateMacAddress(nic.getMacAddress()); @@ -1733,12 +1854,50 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + DomainRouterVO router = profile.getVirtualMachine(); + NicProfile controlNic = getControlNic(profile); + + if (controlNic == null) { + s_logger.error("Control network doesn't exist for the router " + router); + return false; + } + + finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic); + + // restart network if restartNetwork = false is not specified in profile parameters + boolean reprogramGuestNtwks = true; + if (profile.getParameter(Param.ReProgramGuestNetworks) != null + && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { + reprogramGuestNtwks = false; + } + + VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName()); + } + Provider provider = Network.Provider.getProvider(vrProvider.getType().toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); + } + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNetworkId : routerGuestNtwkIds) { + if (reprogramGuestNtwks) { + finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId); + finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); + } + + finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); + } + + return true; + } + + protected NicProfile getControlNic(VirtualMachineProfile profile) { DomainRouterVO router = profile.getVirtualMachine(); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); - NicProfile controlNic = null; - - if(profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { + if (profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { // TODO this is a ugly to test hypervisor type here // for basic network mode, we will use the guest NIC for control NIC for (NicProfile nic : profile.getNics()) { @@ -1753,12 +1912,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } } + return controlNic; + } - if (controlNic == null) { - s_logger.error("Control network doesn't exist for the router " + router); - return false; - } - + protected void finalizeSshAndVersionAndNetworkUsageOnStart(Commands cmds, VirtualMachineProfile profile, DomainRouterVO router, NicProfile controlNic) { cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); // Update router template/scripts version @@ -1768,161 +1925,160 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmds.addCommand("getDomRVersion", command); // Network usage command to create iptables rules - cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create")); + boolean forVpc = profile.getVirtualMachine().getVpcId() != null; + cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); + } - // restart network if restartNetwork = false is not specified in profile parameters - boolean reprogramNetwork = true; - if (profile.getParameter(Param.ReProgramNetwork) != null && (Boolean) profile.getParameter(Param.ReProgramNetwork) == false) { - reprogramNetwork = false; - } - - VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName()); - } - Provider provider = Network.Provider.getProvider(vrProvider.getType().toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); - } - - if (reprogramNetwork) { - s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); - long networkId = router.getNetworkId(); - long ownerId = router.getAccountId(); - long zoneId = router.getDataCenterIdToDeployIn(); - - final List userIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(ownerId, zoneId, null, networkId); - List allPublicIps = new ArrayList(); - if (userIps != null && !userIps.isEmpty()) { - for (IPAddressVO userIp : userIps) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); - allPublicIps.add(publicIp); - } - } - - //Get public Ips that should be handled by router - Network network = _networkDao.findById(networkId); - Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); - Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); - // Only cover virtual router for now, if ELB use it this need to be modified - ArrayList publicIps = providerToIpList.get(Provider.VirtualRouter); - - s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); - - if (!publicIps.isEmpty()) { - - List vpns = new ArrayList(); - List pfRules = new ArrayList(); - List staticNatFirewallRules = new ArrayList(); - List staticNats = new ArrayList(); - List firewallRules = new ArrayList(); - - // Re-apply public ip addresses - should come before PF/LB/VPN - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) { - createAssociateIPCommands(router, publicIps, cmds, 0); - } - - //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) - for (PublicIp ip : publicIps) { - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.PortForwarding, provider)) { - pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); - } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) { - staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); - } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) { - firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall)); - } - - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Vpn, provider)) { - RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); - if (vpn != null) { - vpns.add(vpn); - } - } - - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) { - if (ip.isOneToOneNat()) { - String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId); - StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false); - staticNats.add(staticNat); - } - } - } - - //Re-apply static nats - s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); - if (!staticNats.isEmpty()) { - createApplyStaticNatCommands(staticNats, router, cmds); - } - - //Re-apply firewall rules - s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start."); - if (!firewallRules.isEmpty()) { - createFirewallRulesCommands(firewallRules, router, cmds); - } - - // Re-apply port forwarding rules - s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start."); - if (!pfRules.isEmpty()) { - createApplyPortForwardingRulesCommands(pfRules, router, cmds); - } - - // Re-apply static nat rules - s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start."); - if (!staticNatFirewallRules.isEmpty()) { - List staticNatRules = new ArrayList(); - for (FirewallRule rule : staticNatFirewallRules) { - staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); - } - createApplyStaticNatRulesCommands(staticNatRules, router, cmds); - } - - // Re-apply vpn rules - s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start."); - if (!vpns.isEmpty()) { - for (RemoteAccessVpn vpn : vpns) { - createApplyVpnCommands(vpn, router, cmds); - } - } - - List lbs = _loadBalancerDao.listByNetworkId(networkId); - List lbRules = new ArrayList(); - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Lb, provider)) { - // Re-apply load balancing rules - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); - lbRules.add(loadBalancing); - } - } - - s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start."); - if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, router, cmds); - } - } - } - - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Dhcp, provider)) { + protected void finalizeUserDataAndDhcpOnStart(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) { // Resend dhcp s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start..."); - createDhcpEntryCommandsForVMs(router, cmds); + createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId); } - - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.UserData, provider)) { + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) { // Resend user data s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start..."); - createVmDataCommandForVMs(router, cmds); + createVmDataCommandForVMs(router, cmds, guestNetworkId); } + } - return true; + protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { + s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + List vpns = new ArrayList(); + List pfRules = new ArrayList(); + List staticNatFirewallRules = new ArrayList(); + List staticNats = new ArrayList(); + List firewallRules = new ArrayList(); + + //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) + for (PublicIpAddress ip : publicIps) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) { + pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); + } + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { + staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); + } + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall)); + } + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) { + RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); + if (vpn != null) { + vpns.add(vpn); + } + } + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { + if (ip.isOneToOneNat()) { + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId); + StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false); + staticNats.add(staticNat); + } + } + } + + //Re-apply static nats + s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); + if (!staticNats.isEmpty()) { + createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId); + } + + //Re-apply firewall rules + s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start."); + if (!firewallRules.isEmpty()) { + createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId); + } + + // Re-apply port forwarding rules + s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start."); + if (!pfRules.isEmpty()) { + createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId); + } + + // Re-apply static nat rules + s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start."); + if (!staticNatFirewallRules.isEmpty()) { + List staticNatRules = new ArrayList(); + for (FirewallRule rule : staticNatFirewallRules) { + staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); + } + createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); + } + + // Re-apply vpn rules + s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start."); + if (!vpns.isEmpty()) { + for (RemoteAccessVpn vpn : vpns) { + createApplyVpnCommands(vpn, router, cmds); + } + } + + List lbs = _loadBalancerDao.listByNetworkId(guestNetworkId); + List lbRules = new ArrayList(); + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) { + // Re-apply load balancing rules + for (LoadBalancerVO lb : lbs) { + List dstList = _lbMgr.getExistingDestinations(lb.getId()); + List policyList = _lbMgr.getStickinessPolicies(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList); + lbRules.add(loadBalancing); + } + } + + s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start."); + if (!lbRules.isEmpty()) { + createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId); + } + } + } + + protected void finalizeIpAssocForNetwork(Commands cmds, VirtualRouter router, Provider provider, + Long guestNetworkId) { + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); + // Re-apply public ip addresses - should come before PF/LB/VPN + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + createAssociateIPCommands(router, publicIps, cmds, 0); + } + } + } + + protected ArrayList getPublicIpsToApply(VirtualRouter router, Provider provider, Long guestNetworkId) { + long ownerId = router.getAccountId(); + final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); + List allPublicIps = new ArrayList(); + if (userIps != null && !userIps.isEmpty()) { + for (IPAddressVO userIp : userIps) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + allPublicIps.add(publicIp); + } + } + + //Get public Ips that should be handled by router + Network network = _networkDao.findById(guestNetworkId); + Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); + Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); + // Only cover virtual router for now, if ELB use it this need to be modified + + ArrayList publicIps = providerToIpList.get(provider); + return publicIps; } @Override - public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, + ReservationContext context) { DomainRouterVO router = profile.getVirtualMachine(); + boolean result = true; Answer answer = cmds.getAnswer("checkSsh"); @@ -1938,16 +2094,29 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (result == false) { return result; } + + //Get guest networks info + List guestNetworks = new ArrayList(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNetworks.add(network); + } + } + answer = cmds.getAnswer("getDomRVersion"); if (answer != null && answer instanceof GetDomRVersionAnswer) { GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + " due to: " + versionAnswer.getDetails()); + s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + + " due to: " + versionAnswer.getDetails()); result = false; } else { router.setTemplateVersion(versionAnswer.getTemplateVersion()); router.setScriptsVersion(versionAnswer.getScriptsVersion()); - router = _routerDao.persist(router); + router = _routerDao.persist(router, guestNetworks); } } else { result = false; @@ -1971,16 +2140,19 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to start remote access VPN: no router found for account and zone"); - throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", + DataCenter.class, network.getDataCenterId()); } for (VirtualRouter router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Stop); @@ -1994,16 +2166,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } Answer answer = cmds.getAnswer("users"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } answer = cmds.getAnswer("startVpn"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } @@ -2013,7 +2189,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to delete remote access VPN: no router found for account and zone"); throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId()); @@ -2025,9 +2202,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Commands cmds = new Commands(OnError.Continue); IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); @@ -2041,7 +2219,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian continue; } else { s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } } @@ -2049,7 +2228,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) throws StorageUnavailableException, InsufficientCapacityException, + private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting router " + router); if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { @@ -2074,7 +2254,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, List routers) + public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, + DeployDestination dest, List routers) throws ResourceUnavailableException { _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); @@ -2084,7 +2265,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2137,7 +2319,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2160,15 +2343,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public DomainRouterVO persist(DomainRouterVO router) { DomainRouterVO virtualRouter = _routerDao.persist(router); - // Creating stats entry for router - UserStatisticsVO stats = _userStatsDao.findBy(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); - if (stats == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating user statistics for the account: " + virtualRouter.getAccountId() + " Router Id: " + router.getId()); - } - stats = new UserStatisticsVO(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), null, router.getId(), router.getType().toString(), router.getNetworkId()); - _userStatsDao.persist(stats); - } return virtualRouter; } @@ -2177,7 +2351,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + + network.getId(), DataCenter.class, network.getDataCenterId()); } boolean agentResults = true; @@ -2185,7 +2360,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (DomainRouterVO router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to add/remove VPN users: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Continue); @@ -2203,7 +2379,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2249,7 +2425,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, + InsufficientCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); @@ -2284,9 +2461,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); Map params = new HashMap(); if (reprogramNetwork) { - params.put(Param.ReProgramNetwork, true); + params.put(Param.ReProgramGuestNetworks, true); } else { - params.put(Param.ReProgramNetwork, false); + params.put(Param.ReProgramGuestNetworks, false); } VirtualRouter virtualRouter = startVirtualRouter(router, user, caller, params); if(virtualRouter == null){ @@ -2348,7 +2525,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String vmGuestAddress = null; - IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, + sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); ip.setTrafficType(network.getTrafficType()); ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); @@ -2360,7 +2538,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } IpAssocCommand cmd = new IpAssocCommand(ipsToSend); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2369,7 +2547,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2380,9 +2558,16 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rulesTO); + SetPortForwardingRulesCommand cmd = null; + + if (router.getVpcId() != null) { + cmd = new SetPortForwardingRulesVpcCommand(rulesTO); + } else { + cmd = new SetPortForwardingRulesCommand(rulesTO); + } + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2390,7 +2575,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmds.addCommand(cmd); } - private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2401,16 +2586,16 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); cmds.addCommand(cmd); } - private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; int i = 0; @@ -2432,8 +2617,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian DomainRouterVO domr = (DomainRouterVO)router; RouterPublicIp = domr.getPublicIpAddress(); } + + Network guestNetwork = _networkMgr.getNetwork(guestNetworkId); + Nic nic = _nicDao.findByInstanceIdAndNetworkId(guestNetwork.getId(), router.getId()); + NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), + _networkMgr.getNetworkRate(guestNetwork.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNetwork), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNetwork)); - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,RouterPublicIp, router.getGuestIpAddress(),router.getPrivateIpAddress()); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,RouterPublicIp, + getRouterIpInNetwork(guestNetworkId, router.getId()),router.getPrivateIpAddress(), + _itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId()); cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); @@ -2442,7 +2636,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2464,14 +2658,15 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers); addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2489,7 +2684,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian final String encodedPassword = PasswordGenerator.rot13(password); SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2503,13 +2698,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); cmds.addCommand("vmdata", generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), - vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey)); + vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey, nic.getNetworkId())); } - private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds) { - long networkId = router.getNetworkId(); - List vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping); + private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { boolean createVmData = true; @@ -2518,7 +2712,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } if (createVmData) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); createVmDataCommand(router, vm, nic, null, cmds); @@ -2544,23 +2738,23 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); cmds.addCommand("dhcp", dhcpCommand); } - private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds) { - long networkId = router.getNetworkId(); - List vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping); + private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { boolean createDhcp = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() + && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { createDhcp = false; } if (createDhcp) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + "."); createDhcpEntryCommand(router, vm, nic, cmds); @@ -2569,7 +2763,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - private boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { + protected boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { Answer[] answers = null; try { answers = _agentMgr.send(router.getHostId(), cmds); @@ -2609,10 +2803,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return; } if (!connectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); } if (!disconnectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); } DomainRouterVO connectedRouter = (DomainRouterVO)connectedRouters.get(0); @@ -2649,7 +2845,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean associateIP(Network network, final List ipAddress, List routers) throws ResourceUnavailableException { + public boolean associateIP(Network network, final List ipAddress, List routers) + throws ResourceUnavailableException { if (ipAddress == null || ipAddress.isEmpty()) { s_logger.debug("No ip association rules to be applied for network " + network.getId()); return true; @@ -2683,13 +2880,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList,policyList); lbRules.add(loadBalancing); } - return sendLBRules(router, lbRules); + return sendLBRules(router, lbRules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.PortForwarding) { - return sendPortForwardingRules(router, (List) rules); + return sendPortForwardingRules(router, (List) rules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.StaticNat) { - return sendStaticNatRules(router, (List) rules); + return sendStaticNatRules(router, (List) rules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.Firewall) { - return sendFirewallRules(router, (List) rules); + return sendFirewallRules(router, (List) rules, network.getId()); } else { s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); return false; @@ -2698,21 +2895,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian }); } - protected boolean sendLBRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendLBRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, router, cmds); + createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - protected boolean sendPortForwardingRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendPortForwardingRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyPortForwardingRulesCommands(rules, router, cmds); + createApplyPortForwardingRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - protected boolean sendStaticNatRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendStaticNatRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatRulesCommands(rules, router, cmds); + createApplyStaticNatRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } @@ -2726,7 +2923,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return vrs; } - private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2739,7 +2936,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2747,9 +2944,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - protected boolean sendFirewallRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendFirewallRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createFirewallRulesCommands(rules, router, cmds); + createFirewallRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } @@ -2758,11 +2955,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return _dnsBasicZoneUpdates; } - private interface RuleApplier { + protected interface RuleApplier { boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; } - private boolean applyRules(Network network, List routers, String typeString, boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { + protected boolean applyRules(Network network, List routers, String typeString, + boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); throw new ResourceUnavailableException("Unable to apply " + typeString , DataCenter.class, network.getDataCenterId()); @@ -2784,10 +2982,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (router.isStopPending()) { if (_hostDao.findById(router.getHostId()).getStatus() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + " haven't been stopped after it's host coming back!", + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + + router.getInstanceName() + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterIdToDeployIn()); } - s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + + typeString + " commands to the backend"); continue; } try { @@ -2803,17 +3003,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (isZoneBasic && isPodLevelException) { throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, + router.getDataCenterIdToDeployIn()); } } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { - s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + + ", so not sending apply " + typeString + " commands to the backend"); } else { s_logger.warn("Unable to apply " + typeString +", virtual router is not in the right state " + router.getState()); if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); } } @@ -2850,32 +3054,34 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return applyRules(network, routers, "static nat rules", false, null, false, new RuleApplier() { @Override public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - return applyStaticNat(router, rules); + return applyStaticNat(router, rules, network.getId()); } }); } - protected boolean applyStaticNat(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean applyStaticNat(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatCommands(rules, router, cmds); + createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds, + long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); for (StaticNat rule : rules) { IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, + null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); } } - SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); + SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2906,7 +3112,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { UserContext context = UserContext.current(); context.setAccountId(1); - List routers = _routerDao.listVirtualByHostId(host.getId()); + List routers = _routerDao.listIsolatedByHostId(host.getId()); for (DomainRouterVO router : routers) { if (router.isStopPending()) { State state = router.getState(); @@ -2933,6 +3139,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override + public boolean processDisconnect(long agentId, Status state) { return false; } @@ -2942,15 +3149,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } - @Override - public long getDefaultVirtualRouterServiceOfferingId() { - if (_offering != null) { - return _offering.getId(); - } - return 0; - } - - private String getRouterControlIp(long routerId) { + protected String getRouterControlIp(long routerId) { String routerControlIpAddress = null; List nics = _nicDao.listByVmId(routerId); for (NicVO n : nics) { @@ -2968,4 +3167,120 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return routerControlIpAddress; } + + + protected String getRouterIpInNetwork(long networkId, long instanceId) { + return _nicDao.getIpAddress(networkId, instanceId); + } + + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile){ + //Collect network usage before stopping Vm + VMInstanceVO vm = profile.getVirtualMachine(); + DomainRouterVO router = _routerDao.findById(vm.getId()); + if(router == null){ + return; + } + String privateIP = router.getPrivateIpAddress(); + + if (privateIP != null) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long guestNtwkId : routerGuestNtwkIds) { + boolean forVpc = router.getVpcId() != null; + Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); + Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), + guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); + final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), + forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + NetworkUsageAnswer answer = null; + try { + answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); + continue; + } + + if (answer != null) { + if (!answer.getResult()) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + continue; + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { + s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + continue; + } + txn.start(); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + continue; + } + + if(previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + continue; + } + + if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answer.getBytesReceived()); + if (stats.getCurrentBytesSent() > answer.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answer.getBytesSent()); + _statsDao.update(stats.getId(), stats); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + } finally { + txn.close(); + } + } + } + } + } } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java new file mode 100644 index 00000000000..f0a3cececd3 --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -0,0 +1,103 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.router; + +import java.util.List; +import java.util.Map; + +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.Site2SiteVpnConnection; +import com.cloud.network.VpcVirtualNetworkApplianceService; +import com.cloud.network.rules.NetworkACL; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.user.Account; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineProfile.Param; + +/** + * @author Alena Prokharchyk + */ +public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplianceManager, VpcVirtualNetworkApplianceService{ + + /** + * @param vpc + * @param dest + * @param owner + * @param params + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, Map params) + throws InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException; + + /** + * @param network + * @param rules + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean applyNetworkACLs(Network network, List rules, List routers) + throws ResourceUnavailableException; + + /** + * @param gateway + * @param router TODO + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean setupPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param gateway + * @param router + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean destroyPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param routes + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean applyStaticRoutes(List routes, List routers) throws ResourceUnavailableException; + + /** + * @param conn + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException; + + /** + * @param conn + * @param routers + * @return + * @throws ResourceUnavailableException + */ + boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException; +} diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java new file mode 100644 index 00000000000..9de38537b66 --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -0,0 +1,1087 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.router; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; +import com.cloud.agent.api.SetSourceNatAnswer; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SetNetworkACLCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; +import com.cloud.agent.api.routing.SetStaticRouteCommand; +import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NetworkACLTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenterVO; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkService; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.VpcVirtualNetworkApplianceService; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.rules.NetworkACL; +import com.cloud.network.vpc.NetworkACLManager; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcGateway; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.Dao.StaticRouteDao; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.user.Account; +import com.cloud.utils.Pair; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.VMInstanceDao; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class}) +public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{ + private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class); + + @Inject + VpcDao _vpcDao; + @Inject + VpcOfferingDao _vpcOffDao; + @Inject + PhysicalNetworkDao _pNtwkDao; + @Inject + NetworkService _ntwkService; + @Inject + NetworkACLManager _networkACLMgr; + @Inject + VMInstanceDao _vmDao; + @Inject + StaticRouteDao _staticRouteDao; + @Inject + VpcManager _vpcMgr; + + @Override + public List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + List routers = findOrDeployVirtualRouterInVpc(vpc, dest, owner, params); + + return startRouters(params, routers); + } + + @DB + protected List findOrDeployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + s_logger.debug("Deploying Virtual Router in VPC "+ vpc); + Vpc vpcLock = _vpcDao.acquireInLockTable(vpc.getId()); + if (vpcLock == null) { + throw new ConcurrentOperationException("Unable to lock vpc " + vpc.getId()); + } + + //1) Get deployment plan and find out the list of routers + Pair> planAndRouters = getDeploymentPlanAndRouters(vpc.getId(), dest); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + try { + //2) Return routers if exist + if (routers.size() >= 1) { + return routers; + } + + Long offeringId = _vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + //3) Deploy Virtual Router + List pNtwks = _pNtwkDao.listByZone(vpc.getZoneId()); + + VirtualRouterProvider vpcVrProvider = null; + + for (PhysicalNetwork pNtwk : pNtwks) { + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(pNtwk.getId(), + VirtualRouterProviderType.VPCVirtualRouter.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + + VirtualRouterProviderType.VPCVirtualRouter.toString() + " in physical network " + pNtwk.getId()); + } + vpcVrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), + VirtualRouterProviderType.VPCVirtualRouter); + if (vpcVrProvider != null) { + break; + } + } + + PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddressToVpc(owner, vpc); + + DomainRouterVO router = deployVpcRouter(owner, dest, plan, params, false, vpcVrProvider, offeringId, + vpc.getId(), sourceNatIp); + routers.add(router); + + } finally { + if (vpcLock != null) { + _vpcDao.releaseFromLockTable(vpc.getId()); + } + } + return routers; + } + + protected Pair> getDeploymentPlanAndRouters(long vpcId, DeployDestination dest) { + long dcId = dest.getDataCenter().getId(); + + DeploymentPlan plan = new DataCenterDeployment(dcId); + List routers = _routerDao.listByVpcId(vpcId); + + return new Pair>(plan, routers); + } + + + @Override + public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + + if (network.getTrafficType() != TrafficType.Guest) { + s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest); + return false; + } + + //Add router to the Guest network + boolean result = true; + try { + if (!_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + _routerDao.addRouterToGuestNetwork(routerVO, network); + } + + NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null); + //setup guest network + if (guestNic != null) { + result = setupVpcGuestNetwork(network, router, true, guestNic); + } else { + s_logger.warn("Failed to add router " + router + " to guest network " + network); + result = false; + } + } catch (Exception ex) { + s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex); + result = false; + } finally { + if (!result) { + s_logger.debug("Removing the router " + router + " from network " + network + " as a part of cleanup"); + if (removeRouterFromGuestNetwork(router, network, isRedundant)) { + s_logger.debug("Removed the router " + router + " from network " + network + " as a part of cleanup"); + } else { + s_logger.warn("Failed to remove the router " + router + " from network " + network + " as a part of cleanup"); + } + } + } + + return result; + } + + @Override + public boolean removeRouterFromGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException { + if (network.getTrafficType() != TrafficType.Guest) { + s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest); + return false; + } + + //Check if router is a part of the Guest network + if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { + s_logger.debug("Router " + router + " is not a part of the Guest network " + network); + return true; + } + + boolean result = setupVpcGuestNetwork(network, router, false, _networkMgr.getNicProfile(router, network.getId())); + if (!result) { + s_logger.warn("Failed to destroy guest network config " + network + " on router " + router); + return false; + } + + result = result && _itMgr.removeVmFromNetwork(router, network, null); + + if (result) { + if (result) { + //check if router is already part of network + if (_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + s_logger.debug("Removing router " + router + " from network" + network); + _routerDao.removeRouterFromNetwork(router.getId(), network.getId()); + } + } + } + return result; + } + + protected boolean addPublicIpToVpc(VirtualRouter router, Network publicNetwork, PublicIp ipAddress) + throws ConcurrentOperationException,ResourceUnavailableException, InsufficientCapacityException { + + if (publicNetwork.getTrafficType() != TrafficType.Public) { + s_logger.warn("Network " + publicNetwork + " is not of type " + TrafficType.Public); + return false; + } + + //Add router to the Public network + boolean result = true; + try { + NicProfile defaultNic = new NicProfile(); + if (ipAddress.isSourceNat()) { + defaultNic.setDefaultNic(true); + } + defaultNic.setIp4Address(ipAddress.getAddress().addr()); + defaultNic.setGateway(ipAddress.getGateway()); + defaultNic.setNetmask(ipAddress.getNetmask()); + defaultNic.setMacAddress(ipAddress.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ipAddress.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ipAddress.getVlanTag())); + + NicProfile publicNic = _itMgr.addVmToNetwork(router, publicNetwork, defaultNic); + //setup public network + if (publicNic != null) { + if (ipAddress.isSourceNat()) { + if (router.getPublicIpAddress() == null) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + routerVO.setPublicIpAddress(ipAddress.getAddress().toString()); + routerVO.setPublicNetmask(ipAddress.getNetmask()); + routerVO.setPublicMacAddress(ipAddress.getMacAddress()); + _routerDao.update(routerVO.getId(), routerVO); + } + } + publicNic.setDefaultNic(true); + if (ipAddress != null) { + IPAddressVO ipVO = _ipAddressDao.findById(ipAddress.getId()); + PublicIp publicIp = new PublicIp(ipVO, _vlanDao.findById(ipVO.getVlanId()), + NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())); + result = associtePublicIpInVpc(publicNetwork, router, false, publicIp); + } + } else { + result = false; + s_logger.warn("Failed to add public ip " + ipAddress + " to VPC router " + router); + } + } catch (Exception ex) { + s_logger.warn("Failed to add ip address " + ipAddress + " from the public network " + publicNetwork + + " to VPC router " + router + " due to ", ex); + result = false; + } + + return result; + } + + + protected boolean removePublicIpFromVpcRouter(VirtualRouter router, Network publicNetwork, PublicIp ipAddress) + throws ConcurrentOperationException, ResourceUnavailableException { + + if (publicNetwork.getTrafficType() != TrafficType.Public) { + s_logger.warn("Network " + publicNetwork + " is not of type " + TrafficType.Public); + return false; + } + + boolean result = true; + IPAddressVO ipVO = _ipAddressDao.findById(ipAddress.getId()); + _networkMgr.markIpAsUnavailable(ipVO.getId()); + PublicIp publicIp = new PublicIp(ipVO, _vlanDao.findById(ipVO.getVlanId()), + NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())); + result = associtePublicIpInVpc(publicNetwork, router, false, publicIp); + + if (!result) { + s_logger.warn("Failed to disassociate public ip " + ipAddress + " from router " + router); + return false; + } + + URI broadcastUri = BroadcastDomainType.Vlan.toUri(ipAddress.getVlanTag()); + if (_itMgr.removeVmFromNetwork(router, publicNetwork, broadcastUri)) { + s_logger.debug("Successfully removed router " + router + " from vlan " + ipAddress.getVlanTag() +" of public network " + publicNetwork); + return true; + } else { + s_logger.warn("Failed to remove router " + router + " from vlan " + ipAddress.getVlanTag() +" of public network " + publicNetwork); + return false; + } + } + + protected boolean associtePublicIpInVpc(Network network, VirtualRouter router, boolean add, PublicIp ipAddress) + throws ConcurrentOperationException, ResourceUnavailableException{ + + List publicIps = new ArrayList(1); + publicIps.add(ipAddress); + Commands cmds = new Commands(OnError.Stop); + createVpcAssociateIPCommands(router, publicIps, cmds); + + if (sendCommandsToRouter(router, cmds)) { + s_logger.debug("Successfully applied ip association for ip " + ipAddress + " in vpc network " + network); + return true; + } else { + s_logger.warn("Failed to associate ip address " + ipAddress + " in vpc network " + network); + return false; + } + } + + protected DomainRouterVO deployVpcRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, + Long vpcId, PublicIp sourceNatIp) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + DomainRouterVO router = + super.deployRouter(owner, dest, plan, params, isRedundant, vrProvider, svcOffId, vpcId, sourceNatIp, + false, true, null, null); + + //Plug public nic + if (router != null && sourceNatIp != null) { + Network publicNetwork = _networkDao.listByZoneAndTrafficType(dest.getDataCenter().getId(), TrafficType.Public).get(0); + if (!addPublicIpToVpc(router, publicNetwork, sourceNatIp)) { + s_logger.warn("Failed to add router " + router + " to public network in zone " + dest.getDataCenter() + " cleaninig up"); + destroyRouter(router.getId()); + return null; + } + + } + + return router; + } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + boolean result = true; + + try { + PlugNicCommand plugNicCmd = new PlugNicCommand(vm, nic); + + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("plugnic", plugNicCmd); + _agentMgr.send(dest.getHost().getId(), cmds); + + PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class); + if (!(plugNicAnswer != null && plugNicAnswer.getResult())) { + s_logger.warn("Unable to plug nic for vm " + vm.getHostName()); + result = false; + } + + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Unable to plug nic for router " + vm.getHostName() + " in network " + network, + dest.getHost().getId(), e); + } + + return result; + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + + boolean result = true; + DomainRouterVO router = _routerDao.findById(vm.getId()); + try { + UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(vm, nic); + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("unplugnic", unplugNicCmd); + _agentMgr.send(dest.getHost().getId(), cmds); + + UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class); + if (!(unplugNicAnswer != null && unplugNicAnswer.getResult())) { + s_logger.warn("Unable to unplug nic from router " + router); + result = false; + } + + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Unable to unplug nic from rotuer " + router + " from network " + network, + dest.getHost().getId(), e); + } + + return result; + } + + protected boolean setupVpcGuestNetwork(Network network, VirtualRouter router, boolean add, NicProfile guestNic) + throws ConcurrentOperationException, ResourceUnavailableException{ + + boolean result = true; + + SetupGuestNetworkCommand setupCmd = createSetupGuestNetworkCommand(router, add, guestNic); + + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("setupguestnetwork", setupCmd); + sendCommandsToRouter(router, cmds); + + SetupGuestNetworkAnswer setupAnswer = cmds.getAnswer(SetupGuestNetworkAnswer.class); + String setup = add ? "set" : "destroy"; + if (!(setupAnswer != null && setupAnswer.getResult())) { + s_logger.warn("Unable to " + setup + " guest network on router " + router); + result = false; + } + + return result; + } + + protected SetupGuestNetworkCommand createSetupGuestNetworkCommand(VirtualRouter router, boolean add, NicProfile guestNic) { + Network network = _networkMgr.getNetwork(guestNic.getNetworkId()); + + String defaultDns1 = null; + String defaultDns2 = null; + + boolean dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter); + boolean dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, + Provider.VPCVirtualRouter); + + boolean setupDns = dnsProvided || dhcpProvided; + + if (setupDns) { + defaultDns1 = guestNic.getDns1(); + defaultDns2 = guestNic.getDns2(); + } + + Nic nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); + String networkDomain = network.getNetworkDomain(); + String dhcpRange = getGuestDhcpRange(guestNic, network, _configMgr.getZone(network.getDataCenterId())); + + VirtualMachine vm = _vmDao.findById(router.getId()); + NicProfile nicProfile = _networkMgr.getNicProfile(router, nic.getNetworkId()); + + SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, false, null, + defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile, router.getHypervisorType())); + long guestVlanTag = Long.parseLong(network.getBroadcastUri().getHost()); + String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, network.getGateway()); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_BRIDGE, brd); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + + return setupCmd; + } + + private void createVpcAssociateIPCommands(final VirtualRouter router, final List ips, + Commands cmds) { + + Pair sourceNatIpAdd = null; + Boolean addSourceNat = null; + // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc.. + Map> vlanIpMap = new HashMap>(); + for (final PublicIpAddress ipAddress : ips) { + String vlanTag = ipAddress.getVlanTag(); + ArrayList ipList = vlanIpMap.get(vlanTag); + if (ipList == null) { + ipList = new ArrayList(); + } + //VR doesn't support release for sourceNat IP address; so reset the state + if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) { + ipAddress.setState(IpAddress.State.Allocated); + } + ipList.add(ipAddress); + vlanIpMap.put(vlanTag, ipList); + } + + for (Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { + List ipAddrList = vlanAndIp.getValue(); + + // Get network rate - required for IpAssoc + Integer networkRate = _networkMgr.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); + Network network = _networkMgr.getNetwork(ipAddrList.get(0).getNetworkId()); + + IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; + int i = 0; + + for (final PublicIpAddress ipAddr : ipAddrList) { + boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); + + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, + ipAddr.isSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(), + null, networkRate, ipAddr.isOneToOneNat()); + + ip.setTrafficType(network.getTrafficType()); + ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); + ipsToSend[i++] = ip; + if (ipAddr.isSourceNat()) { + sourceNatIpAdd = new Pair(ip, ipAddr.getNetworkId()); + addSourceNat = add; + } + } + IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("IPAssocVpcCommand", cmd); + } + + //set source nat ip + if (sourceNatIpAdd != null) { + IpAddressTO sourceNatIp = sourceNatIpAdd.first(); + SetSourceNatCommand cmd = new SetSourceNatCommand(sourceNatIp, addSourceNat); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("SetSourceNatCommand", cmd); + } + } + + protected NicTO getNicTO(final VirtualRouter router, Long guestNetworkId) { + VirtualMachine vm = _vmDao.findById(router.getId()); + NicProfile nicProfile = _networkMgr.getNicProfile(router, guestNetworkId); + + return _itMgr.toNicTO(nicProfile, router.getHypervisorType()); + } + + @Override + public boolean associateIP(Network network, final List ipAddress, List routers) + throws ResourceUnavailableException { + if (ipAddress == null || ipAddress.isEmpty()) { + s_logger.debug("No ip association rules to be applied for network " + network.getId()); + return true; + } + + //1) check which nics need to be plugged and plug them + for (PublicIpAddress ip : ipAddress) { + for (VirtualRouter router : routers) { + URI broadcastUri = BroadcastDomainType.Vlan.toUri(ip.getVlanTag()); + Nic nic = _nicDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), router.getId(), + broadcastUri.toString()); + if (nic != null) { + //have to plug the nic(s) + NicProfile defaultNic = new NicProfile(); + if (ip.isSourceNat()) { + defaultNic.setDefaultNic(true); + } + defaultNic.setIp4Address(ip.getAddress().addr()); + defaultNic.setGateway(ip.getGateway()); + defaultNic.setNetmask(ip.getNetmask()); + defaultNic.setMacAddress(ip.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + + NicProfile publicNic = null; + Network publicNtwk = null; + try { + publicNtwk = _networkMgr.getNetwork(ip.getNetworkId()); + publicNic = _itMgr.addVmToNetwork(router, publicNtwk, defaultNic); + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk + " due to ", e); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk + " due to ", e); + } finally { + if (publicNic == null) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk); + return false; + } + } + } + } + } + + //2) apply the ips + return applyRules(network, routers, "vpc ip association", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createVpcAssociateIPCommands(router, ipAddress, cmds); + return sendCommandsToRouter(router, cmds); + } + }); + } + + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, + ReservationContext context) { + + if (profile.getVirtualMachine().getVpcId() != null) { + //remove public and guest nics as we will plug them later + Iterator it = profile.getNics().iterator(); + while (it.hasNext()) { + NicProfile nic = it.next(); + if (nic.getTrafficType() == TrafficType.Public || nic.getTrafficType() == TrafficType.Guest) { + s_logger.debug("Removing nic of type " + nic.getTrafficType() + " from the nics passed on vm start. " + + "The nic will be plugged later"); + it.remove(); + } + } + + //add vpc cidr to the boot load args + StringBuilder buf = profile.getBootArgsBuilder(); + Vpc vpc = _vpcMgr.getVpc(profile.getVirtualMachine().getVpcId()); + buf.append(" vpccidr=" + vpc.getCidr()); + } + + return super.finalizeVirtualMachineProfile(profile, dest, context); + } + + @Override + public boolean applyNetworkACLs(Network network, final List rules, List routers) + throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No network ACLs to be applied for network " + network.getId()); + return true; + } + return applyRules(network, routers, "network acls", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + return sendNetworkACLs(router, (List)rules, network.getId()); + } + }); + } + + + protected boolean sendNetworkACLs(VirtualRouter router, List rules, long guestNetworkId) + throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createNetworkACLsCommands(rules, router, cmds, guestNetworkId); + return sendCommandsToRouter(router, cmds); + } + + private void createNetworkACLsCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { + List rulesTO = null; + String guestVlan = null; + Network guestNtwk = _networkDao.findById(guestNetworkId); + URI uri = guestNtwk.getBroadcastUri(); + if (uri != null) { + guestVlan = guestNtwk.getBroadcastUri().getHost(); + } + + if (rules != null) { + rulesTO = new ArrayList(); + + for (NetworkACL rule : rules) { + NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType()); + rulesTO.add(ruleTO); + } + } + + + SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, getNicTO(router, guestNetworkId)); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + protected void finalizeSshAndVersionOnStart(Commands cmds, VirtualMachineProfile profile, DomainRouterVO router, NicProfile controlNic) { + cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922)); + + // Update router template/scripts version + final GetDomRVersionCmd command = new GetDomRVersionCmd(); + command.setAccessDetail(NetworkElementCommand.ROUTER_IP, controlNic.getIp4Address()); + command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmds.addCommand("getDomRVersion", command); + } + + @Override + public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + DomainRouterVO router = profile.getVirtualMachine(); + + boolean isVpc = (router.getVpcId() != null); + if (!isVpc) { + return super.finalizeCommandsOnStart(cmds, profile); + } + + //1) FORM SSH CHECK COMMAND + NicProfile controlNic = getControlNic(profile); + if (controlNic == null) { + s_logger.error("Control network doesn't exist for the router " + router); + return false; + } + + finalizeSshAndVersionOnStart(cmds, profile, router, controlNic); + + + //2) FORM PLUG NIC COMMANDS + Map guestNics = new HashMap(); + Map publicNics = new HashMap(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNics.put(routerNic, network); + } else if (network.getTrafficType() == TrafficType.Public) { + publicNics.put(routerNic, network); + } + } + + try { + //add VPC router to public networks + List sourceNat = new ArrayList(1); + for (Nic publicNic : publicNics.keySet()) { + Network publicNtwk = publicNics.get(publicNic); + IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), + publicNic.getIp4Address()); + + if (userIp.isSourceNat()) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + sourceNat.add(publicIp); + + if (router.getPublicIpAddress() == null) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + routerVO.setPublicIpAddress(publicNic.getIp4Address()); + routerVO.setPublicNetmask(publicNic.getNetmask()); + routerVO.setPublicMacAddress(publicNic.getMacAddress()); + _routerDao.update(routerVO.getId(), routerVO); + } + } + + PlugNicCommand plugNicCmd = new PlugNicCommand(_itMgr.toVmTO(profile), getNicTO(router, publicNic.getNetworkId())); + cmds.addCommand(plugNicCmd); + } + + // create ip assoc for source nat + if (!sourceNat.isEmpty()) { + createVpcAssociateIPCommands(router, sourceNat, cmds); + } + + for (Nic guestNic : guestNics.keySet()) { + //plug guest nic + PlugNicCommand plugNicCmd = new PlugNicCommand(_itMgr.toVmTO(profile), getNicTO(router, guestNic.getNetworkId())); + cmds.addCommand(plugNicCmd); + + if (!_networkMgr.isPrivateGateway(guestNic)) { + //set guest network + VirtualMachine vm = _vmDao.findById(router.getId()); + NicProfile nicProfile = _networkMgr.getNicProfile(vm, guestNic.getNetworkId()); + SetupGuestNetworkCommand setupCmd = createSetupGuestNetworkCommand(router, true, nicProfile); + cmds.addCommand(setupCmd); + } else { + //set source nat + Integer networkRate = _networkMgr.getNetworkRate(guestNic.getNetworkId(), router.getId()); + IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, guestNic.getIp4Address(), true, false, + true, guestNic.getBroadcastUri().getHost(), guestNic.getGateway(), guestNic.getNetmask(), guestNic.getMacAddress(), + null, networkRate, false); + Network network = _networkMgr.getNetwork(guestNic.getNetworkId()); + ip.setTrafficType(network.getTrafficType()); + SetSourceNatCommand cmd = new SetSourceNatCommand(ip, true); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + cmds.addCommand(cmd); + } + } + } catch (Exception ex) { + s_logger.warn("Failed to add router " + router + " to network due to exception ", ex); + return false; + } + + //3) RE-APPLY ALL STATIC ROUTE RULES + List routes = _staticRouteDao.listByVpcId(router.getVpcId()); + List staticRouteProfiles = new ArrayList(routes.size()); + Map gatewayMap = new HashMap(); + for (StaticRoute route : routes) { + VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId()); + if (gateway == null) { + gateway = _vpcMgr.getVpcGateway(route.getVpcGatewayId()); + gatewayMap.put(gateway.getId(), gateway); + } + staticRouteProfiles.add(new StaticRouteProfile(route, gateway)); + } + + s_logger.debug("Found " + staticRouteProfiles.size() + " static routes to apply as a part of vpc route " + + router + " start"); + if (!staticRouteProfiles.isEmpty()) { + createStaticRouteCommands(staticRouteProfiles, router, cmds); + } + + //4) REISSUE VPN CONNECTION + + //5) REPROGRAM GUEST NETWORK + boolean reprogramGuestNtwks = true; + if (profile.getParameter(Param.ReProgramGuestNetworks) != null + && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { + reprogramGuestNtwks = false; + } + + VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName()); + } + Provider provider = Network.Provider.getProvider(vrProvider.getType().toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); + } + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNetworkId : routerGuestNtwkIds) { + if (reprogramGuestNtwks) { + finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId); + finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); + } + + finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); + } + + return true; + } + + + @Override + protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { + + super.finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); + + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, Provider.VPCVirtualRouter)) { + List networkACLs = _networkACLMgr.listNetworkACLs(guestNetworkId); + s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + router + + " start for guest network id=" + guestNetworkId); + if (!networkACLs.isEmpty()) { + createNetworkACLsCommands((List)networkACLs, router, cmds, guestNetworkId); + } + } + } + + @Override + public boolean setupPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException { + boolean result = true; + try { + Network network = _networkMgr.getNetwork(gateway.getNetworkId()); + NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null); + + //setup source nat + if (guestNic != null) { + result = setupVpcPrivateNetwork(router, true, guestNic); + } else { + s_logger.warn("Failed to setup gateway " + gateway + " on router " + router + " with the source nat"); + result = false; + } + } catch (Exception ex) { + s_logger.warn("Failed to create private gateway " + gateway + " on router " + router + " due to ", ex); + result = false; + } finally { + if (!result) { + s_logger.debug("Removing gateway " + gateway + " from router " + router + " as a part of cleanup"); + if (destroyPrivateGateway(gateway, router)) { + s_logger.debug("Removed the gateway " + gateway + " from router " + router + " as a part of cleanup"); + } else { + s_logger.warn("Failed to remove the gateway " + gateway + " from router " + router + " as a part of cleanup"); + } + } + } + return result; + } + + /** + * @param router + * @param add + * @param privateNic + * @return + * @throws AgentUnavailableException + */ + protected boolean setupVpcPrivateNetwork(VirtualRouter router, boolean add, NicProfile privateNic) + throws AgentUnavailableException { + boolean result = true; + Commands cmds = new Commands(OnError.Stop); + + Integer networkRate = _networkMgr.getNetworkRate(privateNic.getNetworkId(), router.getId()); + IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, privateNic.getIp4Address(), add, false, + true, privateNic.getBroadCastUri().getHost(), privateNic.getGateway(), privateNic.getNetmask(), privateNic.getMacAddress(), + null, networkRate, false); + Network network = _networkMgr.getNetwork(privateNic.getNetworkId()); + ip.setTrafficType(network.getTrafficType()); + + SetSourceNatCommand cmd = new SetSourceNatCommand(ip, add); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("SetSourceNatCommand", cmd); + sendCommandsToRouter(router, cmds); + + SetSourceNatAnswer setupAnswer = cmds.getAnswer(SetSourceNatAnswer.class); + String setup = add ? "set" : "destroy"; + if (!(setupAnswer != null && setupAnswer.getResult())) { + s_logger.warn("Unable to " + setup + " source nat for private gateway " + privateNic + " on router " + router); + result = false; + } + + return result; + } + + @Override + public boolean destroyPrivateGateway(PrivateGateway gateway, VirtualRouter router) + throws ConcurrentOperationException, ResourceUnavailableException { + + if (!_networkMgr.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) { + s_logger.debug("Router doesn't have nic for gateway " + gateway + " so no need to removed it"); + return true; + } + + Network privateNetwork = _networkMgr.getNetwork(gateway.getNetworkId()); + + s_logger.debug("Unsetting source nat for " + router + "'s private gateway " + gateway + " as a part of delete private gateway"); + boolean result = setupVpcPrivateNetwork(router, false, _networkMgr.getNicProfile(router, privateNetwork.getId())); + if (!result) { + s_logger.warn("Failed to delete private gateway " + gateway + " on router " + router); + return false; + } + + s_logger.debug("Removing router " + router + " from private network " + privateNetwork + " as a part of delete private gateway"); + result = result && _itMgr.removeVmFromNetwork(router, privateNetwork, null); + s_logger.debug("Private gateawy " + gateway + " is removed from router " + router); + + return result; + } + + @Override + protected void finalizeIpAssocForNetwork(Commands cmds, VirtualRouter router, Provider provider, + Long guestNetworkId) { + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); + // Re-apply public ip addresses - should come before PF/LB/VPN + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + createVpcAssociateIPCommands(router, publicIps, cmds); + } + } + } + + @Override + public boolean applyStaticRoutes(List staticRoutes, List routers) throws ResourceUnavailableException { + if (staticRoutes == null || staticRoutes.isEmpty()) { + s_logger.debug("No static routes to apply"); + return true; + } + + //send commands to only one router as there is only one in the VPC + return sendStaticRoutes(staticRoutes, routers.get(0)); + + } + + protected boolean sendStaticRoutes(List staticRoutes, DomainRouterVO router) + throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createStaticRouteCommands(staticRoutes, router, cmds); + return sendCommandsToRouter(router, cmds); + } + + /** + * @param staticRoutes + * @param router + * @param cmds + */ + private void createStaticRouteCommands(List staticRoutes, DomainRouterVO router, Commands cmds) { + SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + @Override + public boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException { + return applySite2SiteVpn(true, router, conn); + } + + @Override + public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException { + return applySite2SiteVpn(false, router, conn); + } + + protected boolean applySite2SiteVpn(boolean isCreate, VirtualRouter router, Site2SiteVpnConnection conn) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createApplySite2SiteVpnCommands(conn, isCreate, router, cmds); + return sendCommandsToRouter(router, cmds); + } + + private void createApplySite2SiteVpnCommands(Site2SiteVpnConnection conn, boolean isCreate, VirtualRouter router, Commands cmds) { + Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId()); + Site2SiteVpnGatewayVO vpnGw = _s2sVpnGatewayDao.findById(conn.getVpnGatewayId()); + IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId()); + Vpc vpc = _vpcDao.findById(ip.getVpcId()); + String localPublicIp = ip.getAddress().toString(); + String localGuestCidr = vpc.getCidr(); + String localPublicGateway = _vlanDao.findById(ip.getVlanId()).getVlanGateway(); + String peerGatewayIp = gw.getGatewayIp(); + String peerGuestCidrList = gw.getGuestCidrList(); + String ipsecPsk = gw.getIpsecPsk(); + String ikePolicy = gw.getIkePolicy(); + String espPolicy = gw.getEspPolicy(); + Long lifetime = gw.getLifetime(); + + Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, + peerGatewayIp, peerGuestCidrList, ikePolicy, espPolicy, lifetime, ipsecPsk); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("applyS2SVpn", cmd); + } +} diff --git a/server/src/com/cloud/network/rules/FirewallManager.java b/server/src/com/cloud/network/rules/FirewallManager.java index 2de4d062087..1f9e0e8094e 100644 --- a/server/src/com/cloud/network/rules/FirewallManager.java +++ b/server/src/com/cloud/network/rules/FirewallManager.java @@ -17,7 +17,6 @@ import java.util.List; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; import com.cloud.network.firewall.FirewallService; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; @@ -37,13 +36,12 @@ public interface FirewallManager extends FirewallService { * * @param newRule * the new rule created. - * @param ipAddress - * ip address that back up the new rule. * @throws NetworkRuleConflictException */ - void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException; + void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException; - void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type); + void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, + Purpose purpose, FirewallRuleType type); boolean applyRules(List rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException; @@ -67,10 +65,10 @@ public interface FirewallManager extends FirewallService { boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId); FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId, - FirewallRule.FirewallRuleType type) + FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException; - FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId) throws NetworkRuleConflictException; + FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException; boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException; @@ -78,4 +76,9 @@ public interface FirewallManager extends FirewallService { boolean addSystemFirewallRules(IPAddressVO ip, Account acct); + /** + * @param rule + */ + void removeRule(FirewallRule rule); + } diff --git a/server/src/com/cloud/network/rules/FirewallRuleVO.java b/server/src/com/cloud/network/rules/FirewallRuleVO.java index 7917463008a..4440c31d6f2 100644 --- a/server/src/com/cloud/network/rules/FirewallRuleVO.java +++ b/server/src/com/cloud/network/rules/FirewallRuleVO.java @@ -40,7 +40,7 @@ import com.cloud.utils.net.NetUtils; @Table(name="firewall_rules") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="purpose", discriminatorType=DiscriminatorType.STRING, length=32) -public class FirewallRuleVO implements FirewallRule, Identity { +public class FirewallRuleVO implements Identity, NetworkACL { protected final FirewallRulesCidrsDaoImpl _firewallRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class); @Id @@ -59,7 +59,7 @@ public class FirewallRuleVO implements FirewallRule, Identity { long accountId; @Column(name="ip_address_id", updatable=false) - long sourceIpAddressId; + Long sourceIpAddressId; @Column(name="start_port", updatable=false) Integer sourcePortStart; @@ -98,6 +98,10 @@ public class FirewallRuleVO implements FirewallRule, Identity { @Enumerated(value=EnumType.STRING) FirewallRuleType type; + @Column(name="traffic_type") + @Enumerated(value=EnumType.STRING) + TrafficType trafficType; + // This is a delayed load value. If the value is null, // then this field has not been loaded yet. @@ -114,7 +118,7 @@ public class FirewallRuleVO implements FirewallRule, Identity { @Override public List getSourceCidrList() { - if (sourceCidrs == null && purpose == Purpose.Firewall) { + if (sourceCidrs == null && (purpose == Purpose.Firewall || purpose == Purpose.NetworkACL)) { return _firewallRulesCidrsDao.getSourceCidrs(id); } return sourceCidrs; @@ -141,7 +145,7 @@ public class FirewallRuleVO implements FirewallRule, Identity { } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return sourceIpAddressId; } @@ -191,13 +195,20 @@ public class FirewallRuleVO implements FirewallRule, Identity { this.uuid = UUID.randomUUID().toString(); } - public FirewallRuleVO(String xId, long ipAddressId, Integer portStart, Integer portEnd, String protocol, long networkId, long accountId, long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, Integer icmpType, Long related) { + public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, + long networkId, long accountId, long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, + Integer icmpType, Long related, TrafficType trafficType) { this.xId = xId; if (xId == null) { this.xId = UUID.randomUUID().toString(); } this.accountId = accountId; this.domainId = domainId; + + if (ipAddressId == null) { + assert (purpose == Purpose.NetworkACL) : "ipAddressId can be null for " + Purpose.NetworkACL + " only"; + } + this.sourceIpAddressId = ipAddressId; this.sourcePortStart = portStart; this.sourcePortEnd = portEnd; @@ -216,10 +227,13 @@ public class FirewallRuleVO implements FirewallRule, Identity { this.related = related; this.uuid = UUID.randomUUID().toString(); this.type = FirewallRuleType.User; + this.trafficType = trafficType; } - public FirewallRuleVO(String xId, long ipAddressId, int port, String protocol, long networkId, long accountId, long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, Integer icmpType, Long related) { - this(xId, ipAddressId, port, port, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType, related); + + public FirewallRuleVO(String xId, long ipAddressId, int port, String protocol, long networkId, long accountId, + long domainId, Purpose purpose, List sourceCidrs, Integer icmpCode, Integer icmpType, Long related) { + this(xId, ipAddressId, port, port, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType, related, null); } @Override @@ -254,4 +268,9 @@ public class FirewallRuleVO implements FirewallRule, Identity { public void setType(FirewallRuleType type) { this.type = type; } + + @Override + public TrafficType getTrafficType() { + return trafficType; + } } diff --git a/server/src/com/cloud/network/rules/PortForwardingRuleVO.java b/server/src/com/cloud/network/rules/PortForwardingRuleVO.java index a3ea0e83626..05ca1e4e6a9 100644 --- a/server/src/com/cloud/network/rules/PortForwardingRuleVO.java +++ b/server/src/com/cloud/network/rules/PortForwardingRuleVO.java @@ -47,7 +47,7 @@ public class PortForwardingRuleVO extends FirewallRuleVO implements PortForwardi } public PortForwardingRuleVO(String xId, long srcIpId, int srcPortStart, int srcPortEnd, Ip dstIp, int dstPortStart, int dstPortEnd, String protocol, long networkId, long accountId, long domainId, long instanceId) { - super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding, null, null, null, null); + super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding, null, null, null, null, null); this.destinationIpAddress = dstIp; this.virtualMachineId = instanceId; this.destinationPortStart = dstPortStart; diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index eeed00118fb..0d8ef4f16b6 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -65,6 +65,7 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; +import com.cloud.utils.AnnotationHelper; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; @@ -154,7 +155,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true) - public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException { + public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) + throws NetworkRuleConflictException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); @@ -169,80 +171,115 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled"); } - _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User); - - Long networkId = ipAddress.getAssociatedWithNetworkId(); - Long accountId = ipAddress.getAllocatedToAccountId(); - Long domainId = ipAddress.getAllocatedInDomainId(); - - // start port can't be bigger than end port - if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) { - throw new InvalidParameterValueException("Start port can't be bigger than end port"); - } - - // check that the port ranges are of equal size - if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) { - throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes."); - } - - // validate user VM exists - UserVm vm = _vmDao.findById(vmId); - if (vm == null) { - throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ")."); + Long networkId = rule.getNetworkId(); + //associate ip address to network (if needed) + boolean performedIpAssoc = false; + if (ipAddress.getAssociatedWithNetworkId() == null) { + //set networkId just for verification purposes + ipAddress.setAssociatedWithNetworkId(networkId); + _networkMgr.checkIpForService(ipAddress, Service.PortForwarding); + + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + ipAddress = _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId); + performedIpAssoc = true; + } catch (Exception ex) { + throw new CloudRuntimeException("Failed to associate ip to network as " + + "a part of port forwarding rule creation"); + } } else { - checkRuleAndUserVm(rule, vm, caller); + _networkMgr.checkIpForService(ipAddress, Service.PortForwarding); } - - _networkMgr.checkIpForService(ipAddress, Service.PortForwarding); - - // Verify that vm has nic in the network - Ip dstIp = rule.getDestinationIpAddress(); - Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId); - if (guestNic == null || guestNic.getIp4Address() == null) { - throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress"); - } else { - dstIp = new Ip(guestNic.getIp4Address()); - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(), - rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId); - newRule = _portForwardingDao.persist(newRule); - - // create firewallRule for 0.0.0.0/0 cidr - if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId()); - } - + try { - _firewallMgr.detectRulesConflict(newRule, ipAddress); - if (!_firewallDao.setStateToAdd(newRule)) { - throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User); + + Long accountId = ipAddress.getAllocatedToAccountId(); + Long domainId = ipAddress.getAllocatedInDomainId(); + + // start port can't be bigger than end port + if (rule.getDestinationPortStart() > rule.getDestinationPortEnd()) { + throw new InvalidParameterValueException("Start port can't be bigger than end port"); } - UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), ipAddress.getDataCenterId(), newRule.getId(), null); - _usageEventDao.persist(usageEvent); - txn.commit(); - return newRule; - } catch (Exception e) { - if (newRule != null) { + // check that the port ranges are of equal size + if ((rule.getDestinationPortEnd() - rule.getDestinationPortStart()) != (rule.getSourcePortEnd() - rule.getSourcePortStart())) { + throw new InvalidParameterValueException("Source port and destination port ranges should be of equal sizes."); + } - txn.start(); - // no need to apply the rule as it wasn't programmed on the backend yet - _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - _portForwardingDao.remove(newRule.getId()); + // validate user VM exists + UserVm vm = _vmDao.findById(vmId); + if (vm == null) { + throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + + ", invalid virtual machine id specified (" + vmId + ")."); + } else { + checkRuleAndUserVm(rule, vm, caller); + } + + // Verify that vm has nic in the network + Ip dstIp = rule.getDestinationIpAddress(); + Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId); + if (guestNic == null || guestNic.getIp4Address() == null) { + throw new InvalidParameterValueException("Vm doesn't belong to network associated with ipAddress"); + } else { + dstIp = new Ip(guestNic.getIp4Address()); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), + rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(), + rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId); + newRule = _portForwardingDao.persist(newRule); + + // create firewallRule for 0.0.0.0/0 cidr + if (openFirewall) { + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getProtocol(), null, null, newRule.getId(), networkId); + } + + try { + _firewallMgr.detectRulesConflict(newRule); + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), + ipAddress.getDataCenterId(), newRule.getId(), null); + _usageEventDao.persist(usageEvent); txn.commit(); - } + return newRule; + } catch (Exception e) { + if (newRule != null) { + txn.start(); + // no need to apply the rule as it wasn't programmed on the backend yet + _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); + removePFRule(newRule); + txn.commit(); + } - if (e instanceof NetworkRuleConflictException) { - throw (NetworkRuleConflictException) e; + if (e instanceof NetworkRuleConflictException) { + throw (NetworkRuleConflictException) e; + } + + throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e); + } + } finally { + // release ip address if ipassoc was perfored + if (performedIpAssoc) { + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + IpAddress ip = _ipAddressDao.findById(ipAddress.getId()); + if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + s_logger.debug("Releasing VPC ip address " + ip + " as PF rule failed to create"); + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } } - throw new CloudRuntimeException("Unable to add rule for the ip id=" + ipAddrId, e); } + + } @Override @@ -282,17 +319,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { txn.start(); FirewallRuleVO newRule = new FirewallRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol().toLowerCase(), - networkId, accountId, domainId, rule.getPurpose(), null, null, null, null); + networkId, accountId, domainId, rule.getPurpose(), null, null, null, null, null); newRule = _firewallDao.persist(newRule); // create firewallRule for 0.0.0.0/0 cidr if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId()); + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId); } try { - _firewallMgr.detectRulesConflict(newRule, ipAddress); + _firewallMgr.detectRulesConflict(newRule); if (!_firewallDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } @@ -310,7 +347,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { txn.start(); // no need to apply the rule as it wasn't programmed on the backend yet _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); - _portForwardingDao.remove(newRule.getId()); + _firewallMgr.removeRule(newRule); txn.commit(); } @@ -322,31 +359,45 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } @Override - public boolean enableStaticNat(long ipId, long vmId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException { + public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) + throws NetworkRuleConflictException, ResourceUnavailableException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); + // Verify input parameters + UserVmVO vm = _vmDao.findById(vmId); + if (vm == null) { + throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + + ", invalid virtual machine id specified (" + vmId + ")."); + } + IPAddressVO ipAddress = _ipAddressDao.findById(ipId); if (ipAddress == null) { throw new InvalidParameterValueException("Unable to find ip address by id " + ipId); } // Verify input parameters + boolean setNetworkId = false; if (!isSystemVm) { - UserVmVO vm = _vmDao.findById(vmId); - if (vm == null) { - throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + ", invalid virtual machine id specified (" + vmId + ")."); + //associate ip address to network (if needed) + if (ipAddress.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + ipAddress = _networkMgr.associateIPToGuestNetwork(ipId, networkId); + } catch (Exception ex) { + s_logger.warn("Failed to associate ip id=" + ipId + " to network id=" + networkId + " as " + + "a part of enable static nat"); + return false; } + setNetworkId = true; + } + + _networkMgr.checkIpForService(ipAddress, Service.StaticNat); + // Check permissions checkIpAndUserVm(ipAddress, vm, caller); } - // Verify that the ip is associated with the network and static nat service is supported for the network - Long networkId = ipAddress.getAssociatedWithNetworkId(); - if (networkId == null) { - throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipId + " as ip is not associated with any network"); - } - // Check that vm has a nic in the network Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId); if (guestNic == null) { @@ -355,14 +406,12 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Network network = _networkMgr.getNetwork(networkId); if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) { - throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not supported in network id=" + networkId); + throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " + + "supported in network id=" + networkId); } // Verify ip address parameter isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId()); - - _networkMgr.checkIpForService(ipAddress, Service.StaticNat); - ipAddress.setOneToOneNat(true); ipAddress.setAssociatedWithVmId(vmId); @@ -374,6 +423,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } else { ipAddress.setOneToOneNat(false); ipAddress.setAssociatedWithVmId(null); + if (setNetworkId) { + ipAddress.setAssociatedWithNetworkId(null); + } _ipAddressDao.update(ipAddress.getId(), ipAddress); s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend"); return false; @@ -384,7 +436,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } } - protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId) throws NetworkRuleConflictException, ResourceUnavailableException { + protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId) + throws NetworkRuleConflictException, ResourceUnavailableException { if (ipAddress.isSourceNat()) { throw new InvalidParameterValueException("Can't enable static, ip address " + ipAddress + " is a sourceNat ip address"); } @@ -957,7 +1010,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override @DB - public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException { + public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, + boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException { FirewallRuleVO[] rules = new FirewallRuleVO[ports.length]; Transaction txn = Transaction.currentTxn(); @@ -968,7 +1022,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { rules[i] = _firewallDao.persist(rules[i]); if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, rules[i].getId()); + _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, + rules[i].getId(), ip.getAssociatedWithNetworkId()); } } txn.commit(); @@ -976,7 +1031,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { boolean success = false; try { for (FirewallRuleVO newRule : rules) { - _firewallMgr.detectRulesConflict(newRule, ip); + _firewallMgr.detectRulesConflict(newRule); } success = true; return rules; @@ -985,7 +1040,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { txn.start(); for (FirewallRuleVO newRule : rules) { - _portForwardingDao.remove(newRule.getId()); + _firewallMgr.removeRule(newRule); } txn.commit(); } @@ -1026,17 +1081,20 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { checkIpAndUserVm(ipAddress, null, caller); if (ipAddress.getSystem()) { - throw new InvalidParameterValueException("Can't disable static nat for system IP address " + ipAddress); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't disable static nat for system IP address with specified id"); + ex.addProxyObject(ipAddress, ipId, "ipId"); + throw ex; } Long vmId = ipAddress.getAssociatedWithVmId(); if (vmId == null) { - throw new InvalidParameterValueException("IP address " + ipAddress + " is not associated with any vm Id"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified IP address id is not associated with any vm Id"); + ex.addProxyObject(ipAddress, ipId, "ipId"); + throw ex; } // if network has elastic IP functionality supported, we first have to disable static nat on old ip in order to -// re-enable it on the new one - // enable static nat takes care of that + // re-enable it on the new one enable static nat takes care of that Network guestNetwork = _networkMgr.getNetwork(ipAddress.getAssociatedWithNetworkId()); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); if (offering.getElasticIp()) { @@ -1056,7 +1114,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { checkIpAndUserVm(ipAddress, null, caller); if (!ipAddress.isOneToOneNat()) { - throw new InvalidParameterValueException("One to one nat is not enabled for the ip id=" + ipId); + InvalidParameterValueException ex = new InvalidParameterValueException("One to one nat is not enabled for the specified ip id"); + ex.addProxyObject(ipAddress, ipId, "ipId"); + throw ex; } // Revoke all firewall rules for the ip @@ -1077,14 +1137,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } if (success) { + Transaction txn = Transaction.currentTxn(); + txn.start(); boolean isIpSystem = ipAddress.getSystem(); - ipAddress.setOneToOneNat(false); ipAddress.setAssociatedWithVmId(null); if (isIpSystem && !releaseIpIfElastic) { ipAddress.setSystem(false); } _ipAddressDao.update(ipAddress.getId(), ipAddress); + _networkMgr.unassignIPFromVpcNetwork(ipAddress.getId()); + txn.commit(); if (isIpSystem && releaseIpIfElastic && !_networkMgr.handleSystemIpRelease(ipAddress)) { s_logger.warn("Failed to release system ip address " + ipAddress); @@ -1114,7 +1177,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId()); if (ip == null || !ip.isOneToOneNat() || ip.getAssociatedWithVmId() == null) { - throw new InvalidParameterValueException("Source ip address of the rule id=" + rule.getId() + " is not static nat enabled"); + InvalidParameterValueException ex = new InvalidParameterValueException("Source ip address of the specified firewall rule id is not static nat enabled"); + ex.addProxyObject(ruleVO, rule.getId(), "ruleId"); + throw ex; } String dstIp; @@ -1146,7 +1211,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { UserVmVO vm = _vmDao.findById(sourceIp.getAssociatedWithVmId()); Network network = _networkMgr.getNetwork(networkId); if (network == null) { - throw new CloudRuntimeException("Unable to find ip address to map to in vm id=" + vm.getId()); + CloudRuntimeException ex = new CloudRuntimeException("Unable to find an ip address to map to specified vm id"); + ex.addProxyObject(vm, vm.getId(), "vmId"); + throw ex; } if (caller != null) { @@ -1163,7 +1230,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { dstIp = _networkMgr.getIpInNetwork(sourceIp.getAssociatedWithVmId(), networkId); } - StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIpId, dstIp, forRevoke); + StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), + networkId, sourceIpId, dstIp, forRevoke); staticNats.add(staticNat); try { @@ -1198,19 +1266,21 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { s_logger.debug("Allocating system ip and enabling static nat for it for the vm " + vm + " in guest network " + guestNetwork); IpAddress ip = _networkMgr.assignSystemIp(guestNetwork.getId(), _accountMgr.getAccount(vm.getAccountId()), false, true); if (ip == null) { - throw new CloudRuntimeException("Failed to allocate system ip for vm " + vm + " in guest network " + guestNetwork); + throw new CloudRuntimeException("Failed to allocate system ip for vm " + vm + " in guest network " + guestNetwork); } s_logger.debug("Allocated system ip " + ip + ", now enabling static nat on it for vm " + vm); boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm); try { - success = enableStaticNat(ip.getId(), vm.getId(), isSystemVM); + success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM); } catch (NetworkRuleConflictException ex) { - s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + + vm + " in guest network " + guestNetwork + " due to exception ", ex); success = false; } catch (ResourceUnavailableException ex) { - s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + + vm + " in guest network " + guestNetwork + " due to exception ", ex); success = false; } @@ -1224,5 +1294,18 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } } } - + + @DB + protected void removePFRule(PortForwardingRuleVO rule) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + _portForwardingDao.remove(rule.getId()); + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); + if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } + + txn.commit(); + } } diff --git a/server/src/com/cloud/network/rules/StaticNatRuleImpl.java b/server/src/com/cloud/network/rules/StaticNatRuleImpl.java index 8cbf2b3dad7..cf6783926c4 100644 --- a/server/src/com/cloud/network/rules/StaticNatRuleImpl.java +++ b/server/src/com/cloud/network/rules/StaticNatRuleImpl.java @@ -90,7 +90,7 @@ public class StaticNatRuleImpl implements StaticNatRule{ } @Override - public long getSourceIpAddressId() { + public Long getSourceIpAddressId() { return sourceIpAddressId; } diff --git a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java index 2bdaea58e44..e4fbbb0e77e 100644 --- a/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java +++ b/server/src/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java @@ -16,8 +16,6 @@ import java.util.List; import javax.ejb.Local; -import org.apache.log4j.Logger; - import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; @@ -30,7 +28,6 @@ import com.cloud.utils.db.SearchCriteria.Op; @Local(value=PortForwardingRulesDao.class) public class PortForwardingRulesDaoImpl extends GenericDaoBase implements PortForwardingRulesDao { - private static final Logger s_logger = Logger.getLogger(PortForwardingRulesDaoImpl.class); protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder ApplicationSearch; diff --git a/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java b/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java new file mode 100644 index 00000000000..9f8d8114d83 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java @@ -0,0 +1,65 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface PrivateIpDao extends GenericDao{ + + /** + * @param dcId + * @param networkId + * @return + */ + PrivateIpVO allocateIpAddress(long dcId, long networkId); + + /** + * @param ipAddress + * @param networkId + */ + void releaseIpAddress(String ipAddress, long networkId); + + /** + * @param networkId + * @param ip4Address + * @return + */ + PrivateIpVO findByIpAndSourceNetworkId(long networkId, String ip4Address); + + /** + * @param networkId + * @return + */ + List listByNetworkId(long networkId); + + /** + * @param ntwkId + * @return + */ + int countAllocatedByNetworkId(long ntwkId); + + /** + * @param networkId + */ + void deleteByNetworkId(long networkId); + + int countByNetworkId(long ntwkId); + + +} diff --git a/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java new file mode 100644 index 00000000000..7fc626c5b8b --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java @@ -0,0 +1,143 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.Date; +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.utils.db.DB; +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.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = PrivateIpDao.class) +@DB(txn = false) +public class PrivateIpDaoImpl extends GenericDaoBase implements PrivateIpDao { + private static final Logger s_logger = Logger.getLogger(PrivateIpDaoImpl.class); + + private final SearchBuilder AllFieldsSearch; + private final GenericSearchBuilder CountAllocatedByNetworkId; + private final GenericSearchBuilder CountByNetworkId; + + + protected PrivateIpDaoImpl() { + super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("ip", AllFieldsSearch.entity().getIpAddress(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("ipAddress", AllFieldsSearch.entity().getIpAddress(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("taken", AllFieldsSearch.entity().getTakenAt(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + + CountAllocatedByNetworkId = createSearchBuilder(Integer.class); + CountAllocatedByNetworkId.select(null, Func.COUNT, CountAllocatedByNetworkId.entity().getId()); + CountAllocatedByNetworkId.and("networkId", CountAllocatedByNetworkId.entity().getNetworkId(), Op.EQ); + CountAllocatedByNetworkId.and("taken", CountAllocatedByNetworkId.entity().getTakenAt(), Op.NNULL); + CountAllocatedByNetworkId.done(); + + CountByNetworkId = createSearchBuilder(Integer.class); + CountByNetworkId.select(null, Func.COUNT, CountByNetworkId.entity().getId()); + CountByNetworkId.and("networkId", CountByNetworkId.entity().getNetworkId(), Op.EQ); + CountByNetworkId.done(); + } + + @Override + public PrivateIpVO allocateIpAddress(long dcId, long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + sc.setParameters("taken", (Date)null); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + PrivateIpVO vo = lockOneRandomRow(sc, true); + if (vo == null) { + txn.rollback(); + return null; + } + vo.setTakenAt(new Date()); + update(vo.getId(), vo); + txn.commit(); + return vo; + } + + @Override + public void releaseIpAddress(String ipAddress, long networkId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing private ip address: " + ipAddress + " network id " + networkId); + } + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ip", ipAddress); + sc.setParameters("networkId", networkId); + + PrivateIpVO vo = createForUpdate(); + + vo.setTakenAt(null); + update(vo, sc); + } + + /* (non-Javadoc) + * @see com.cloud.network.vpc.Dao.PrivateIpDao#findByIpAndSourceNetworkId(long, java.lang.String) + */ + @Override + public PrivateIpVO findByIpAndSourceNetworkId(long networkId, String ip4Address) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ip", ip4Address); + sc.setParameters("networkId", networkId); + return findOneBy(sc); + } + + @Override + public List listByNetworkId(long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + return listBy(sc); + } + + @Override + public int countAllocatedByNetworkId(long ntwkId) { + SearchCriteria sc = CountAllocatedByNetworkId.create(); + sc.setParameters("networkId", ntwkId); + List results = customSearch(sc, null); + return results.get(0); + } + + + @Override + public void deleteByNetworkId(long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + remove(sc); + } + + @Override + public int countByNetworkId(long ntwkId) { + SearchCriteria sc = CountByNetworkId.create(); + sc.setParameters("networkId", ntwkId); + List results = customSearch(sc, null); + return results.get(0); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java new file mode 100644 index 00000000000..a9515e8baab --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java @@ -0,0 +1,34 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface StaticRouteDao extends GenericDao{ + + boolean setStateToAdd(StaticRouteVO rule); + + List listByGatewayIdAndNotRevoked(long gatewayId); + + List listByVpcId(long vpcId); + + long countRoutesByGateway(long gatewayId); + +} diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java new file mode 100644 index 00000000000..d4b195b00e8 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java @@ -0,0 +1,95 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.utils.db.DB; +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.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = StaticRouteDao.class) +@DB(txn = false) +public class StaticRouteDaoImpl extends GenericDaoBase implements StaticRouteDao{ + protected final SearchBuilder AllFieldsSearch; + protected final SearchBuilder NotRevokedSearch; + protected final GenericSearchBuilder RoutesByGatewayCount; + + protected StaticRouteDaoImpl() { + super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("gatewayId", AllFieldsSearch.entity().getVpcGatewayId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.done(); + + NotRevokedSearch = createSearchBuilder(); + NotRevokedSearch.and("gatewayId", NotRevokedSearch.entity().getVpcGatewayId(), Op.EQ); + NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ); + NotRevokedSearch.done(); + + RoutesByGatewayCount = createSearchBuilder(Long.class); + RoutesByGatewayCount.select(null, Func.COUNT, RoutesByGatewayCount.entity().getId()); + RoutesByGatewayCount.and("gatewayId", RoutesByGatewayCount.entity().getVpcGatewayId(), Op.EQ); + RoutesByGatewayCount.done(); + } + + + @Override + public boolean setStateToAdd(StaticRouteVO rule) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("id", rule.getId()); + sc.setParameters("state", StaticRoute.State.Staged); + + rule.setState(StaticRoute.State.Add); + + return update(rule, sc) > 0; + } + + + @Override + public List listByGatewayIdAndNotRevoked(long gatewayId) { + SearchCriteria sc = NotRevokedSearch.create(); + sc.setParameters("gatewayId", gatewayId); + sc.setParameters("state", StaticRoute.State.Revoke); + return listBy(sc); + } + + @Override + public List listByVpcId(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + return listBy(sc); + } + + @Override + public long countRoutesByGateway(long gatewayId) { + SearchCriteria sc = RoutesByGatewayCount.create(); + sc.setParameters("gatewayId", gatewayId); + return customSearch(sc, null).get(0); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDao.java b/server/src/com/cloud/network/vpc/Dao/VpcDao.java new file mode 100644 index 00000000000..ac8b0d4ad51 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcDao.java @@ -0,0 +1,38 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcDao extends GenericDao{ + + /** + * @param offId + * @return + */ + int getVpcCountByOfferingId(long offId); + + Vpc getActiveVpcById(long vpcId); + + List listByAccountId(long accountId); + + List listInactiveVpcs(); + +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java new file mode 100644 index 00000000000..e0ea5d920f3 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -0,0 +1,86 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcVO; +import com.cloud.utils.db.DB; +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.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = VpcDao.class) +@DB(txn = false) +public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ + final GenericSearchBuilder CountByOfferingId; + final SearchBuilder AllFieldsSearch; + + protected VpcDaoImpl() { + super(); + + CountByOfferingId = createSearchBuilder(Integer.class); + CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); + CountByOfferingId.and("offeringId", CountByOfferingId.entity().getVpcOfferingId(), Op.EQ); + CountByOfferingId.and("removed", CountByOfferingId.entity().getRemoved(), Op.NULL); + CountByOfferingId.done(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); + AllFieldsSearch.done(); + } + + + @Override + public int getVpcCountByOfferingId(long offId) { + SearchCriteria sc = CountByOfferingId.create(); + sc.setParameters("offeringId", offId); + List results = customSearch(sc, null); + return results.get(0); + } + + @Override + public Vpc getActiveVpcById(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("id", vpcId); + sc.setParameters("state", Vpc.State.Enabled); + return findOneBy(sc); + } + + @Override + public List listByAccountId(long accountId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("accountId", accountId); + return listBy(sc, null); + } + + @Override + public List listInactiveVpcs() { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("state", Vpc.State.Inactive); + return listBy(sc, null); + } +} + diff --git a/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java new file mode 100644 index 00000000000..add2f4228ad --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java @@ -0,0 +1,23 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import com.cloud.network.vpc.VpcGatewayVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcGatewayDao extends GenericDao{ + VpcGatewayVO getPrivateGateway(long vpcId); +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcGatewayDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDaoImpl.java new file mode 100644 index 00000000000..f19ff569f22 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDaoImpl.java @@ -0,0 +1,50 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import javax.ejb.Local; + +import com.cloud.network.vpc.VpcGateway; +import com.cloud.network.vpc.VpcGatewayVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = VpcGatewayDao.class) +@DB(txn = false) +public class VpcGatewayDaoImpl extends GenericDaoBase implements VpcGatewayDao{ + protected final SearchBuilder AllFieldsSearch; + + protected VpcGatewayDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("type", AllFieldsSearch.entity().getType(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + } + + + @Override + public VpcGatewayVO getPrivateGateway(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + sc.setParameters("type", VpcGateway.Type.Private); + + return findOneBy(sc); + } + +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java new file mode 100644 index 00000000000..b5c8b47933d --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java @@ -0,0 +1,30 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcOfferingDao extends GenericDao{ + /** + * Returns the VPC offering that matches the unique name. + * + * @param uniqueName + * name + * @return VpcOfferingVO + */ + VpcOfferingVO findByUniqueName(String uniqueName); +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java new file mode 100644 index 00000000000..b5e6c6ede8a --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java @@ -0,0 +1,68 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import javax.ejb.Local; + +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; + +/** + * @author Alena Prokharchyk + */ +@Local(value = VpcOfferingDao.class) +@DB(txn = false) +public class VpcOfferingDaoImpl extends GenericDaoBase implements VpcOfferingDao{ + final SearchBuilder AllFieldsSearch; + + + protected VpcOfferingDaoImpl() { + super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ); + AllFieldsSearch.and("uName", AllFieldsSearch.entity().getUniqueName(), Op.EQ); + AllFieldsSearch.and("displayText", AllFieldsSearch.entity().getDisplayText(), Op.EQ); + AllFieldsSearch.and("svcOffId", AllFieldsSearch.entity().getServiceOfferingId(), Op.EQ); + AllFieldsSearch.done(); + + } + + @Override + @DB + public boolean remove(Long vpcOffId) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + VpcOfferingVO offering = findById(vpcOffId); + offering.setUniqueName(null); + update(vpcOffId, offering); + boolean result = super.remove(vpcOffId); + txn.commit(); + return result; + } + + + @Override + public VpcOfferingVO findByUniqueName(String uniqueName) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("uName", uniqueName); + return findOneBy(sc); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java new file mode 100644 index 00000000000..af896220da9 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java @@ -0,0 +1,37 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.Network.Service; +import com.cloud.network.vpc.VpcOfferingServiceMapVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcOfferingServiceMapDao extends GenericDao{ + + List listByVpcOffId(long vpcOffId); + + /** + * @param networkOfferingId + * @param services + * @return + */ + boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service[] services); + + List listServicesForVpcOffering(long vpcOfferingId); + +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java new file mode 100644 index 00000000000..9fbc1fff556 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java @@ -0,0 +1,104 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.Network.Service; +import com.cloud.network.vpc.VpcOfferingServiceMapVO; +import com.cloud.utils.db.DB; +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.SearchCriteria.Func; + +/** + * @author Alena Prokharchyk + */ +@Local(value = VpcOfferingServiceMapDao.class) +@DB(txn = false) +public class VpcOfferingServiceMapDaoImpl extends GenericDaoBase implements VpcOfferingServiceMapDao{ + final SearchBuilder AllFieldsSearch; + final SearchBuilder MultipleServicesSearch; + final GenericSearchBuilder ServicesSearch; + + + protected VpcOfferingServiceMapDaoImpl() { + super(); + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("vpcOffId", AllFieldsSearch.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("service", AllFieldsSearch.entity().getService(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("provider", AllFieldsSearch.entity().getProvider(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + + + MultipleServicesSearch = createSearchBuilder(); + MultipleServicesSearch.and("vpcOffId", MultipleServicesSearch.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + MultipleServicesSearch.and("service", MultipleServicesSearch.entity().getService(), SearchCriteria.Op.IN); + MultipleServicesSearch.and("provider", MultipleServicesSearch.entity().getProvider(), SearchCriteria.Op.EQ); + MultipleServicesSearch.done(); + + ServicesSearch = createSearchBuilder(String.class); + ServicesSearch.and("offeringId", ServicesSearch.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + ServicesSearch.select(null, Func.DISTINCT, ServicesSearch.entity().getService()); + ServicesSearch.done(); + } + + @Override + public List listByVpcOffId(long vpcOffId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcOffId", vpcOffId); + return listBy(sc); + } + + + @Override + public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) { + SearchCriteria sc = MultipleServicesSearch.create(); + sc.setParameters("vpcOffId", networkOfferingId); + + if (services != null) { + String[] servicesStr = new String[services.length]; + + int i = 0; + for (Service service : services) { + servicesStr[i] = service.getName(); + i++; + } + + sc.setParameters("service", (Object[])servicesStr); + } + + List offeringServices = listBy(sc); + + if (services != null) { + if (offeringServices.size() == services.length) { + return true; + } + } else if (!offeringServices.isEmpty()) { + return true; + } + + return false; + } + + @Override + public List listServicesForVpcOffering(long offId) { + SearchCriteria sc = ServicesSearch.create();; + sc.setParameters("offeringId", offId); + return customSearch(sc, null); + } +} diff --git a/server/src/com/cloud/network/vpc/NetworkACLManager.java b/server/src/com/cloud/network/vpc/NetworkACLManager.java new file mode 100644 index 00000000000..01f54f01b2f --- /dev/null +++ b/server/src/com/cloud/network/vpc/NetworkACLManager.java @@ -0,0 +1,38 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.List; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.firewall.NetworkACLService; +import com.cloud.network.rules.NetworkACL; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public interface NetworkACLManager extends NetworkACLService{ + + /** + * @param networkId + * @param userId + * @param caller + * @return + * @throws ResourceUnavailableException + */ + boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException; + + List listNetworkACLs(long guestNtwkId); + +} diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java new file mode 100644 index 00000000000..6e3ba66e21c --- /dev/null +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -0,0 +1,394 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.acl.SecurityChecker.AccessType; +import com.cloud.api.commands.ListNetworkACLsCmd; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.Networks; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.firewall.NetworkACLService; +import com.cloud.network.rules.FirewallManager; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; +import com.cloud.network.rules.FirewallRule.TrafficType; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.NetworkACL; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.UserContext; +import com.cloud.utils.Ternary; +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.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = { NetworkACLService.class, NetworkACLManager.class}) +public class NetworkACLManagerImpl implements Manager,NetworkACLManager{ + String _name; + private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class); + + + @Inject + AccountManager _accountMgr; + @Inject + FirewallManager _firewallMgr; + @Inject + FirewallRulesDao _firewallDao; + @Inject + NetworkManager _networkMgr; + @Inject + VpcManager _vpcMgr; + + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + return true; + } + + @Override + public boolean start() { + return true; + } + + + @Override + public boolean stop() { + return true; + } + + + @Override + public String getName() { + return _name; + } + + @Override + public boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException { + List rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL); + return _firewallMgr.applyFirewallRules(rules, false, caller); + } + + @Override + public NetworkACL createNetworkACL(NetworkACL acl) throws NetworkRuleConflictException { + return createNetworkACL(UserContext.current().getCaller(), acl.getXid(), acl.getSourcePortStart(), + acl.getSourcePortEnd(), acl.getProtocol(), acl.getSourceCidrList(), acl.getIcmpCode(), + acl.getIcmpType(), null, acl.getType(), acl.getNetworkId(), acl.getTrafficType()); + } + + @DB + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true) + protected NetworkACL createNetworkACL(Account caller, String xId, Integer portStart, + Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, + Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId, TrafficType trafficType) throws NetworkRuleConflictException { + + Network network = _networkMgr.getNetwork(networkId); + if (network == null) { + throw new InvalidParameterValueException("Can't find network by id"); + } + + if (network.getVpcId() == null) { + throw new UnsupportedOperationException("Network ACL rules are supported just for VPC networks"); + } + + Vpc vpc = _vpcMgr.getVpc(network.getVpcId()); + Account aclOwner = _accountMgr.getAccount(vpc.getAccountId()); + + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + + + if (!_networkMgr.areServicesSupportedInNetwork(networkId, Service.Firewall)) { + throw new InvalidParameterValueException("Service " + Service.Firewall + " is not supported in network " + network); + } + + // icmp code and icmp type can't be passed in for any other protocol rather than icmp + if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) { + throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only"); + } + + if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) { + throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP"); + } + + validateNetworkACL(caller, network, portStart, portEnd, protocol); + + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + FirewallRuleVO newRule = new FirewallRuleVO(xId, null, portStart, portEnd, protocol.toLowerCase(), networkId, + aclOwner.getAccountId(), aclOwner.getDomainId(), Purpose.NetworkACL, sourceCidrList, icmpCode, icmpType, + relatedRuleId, trafficType); + newRule.setType(type); + newRule = _firewallDao.persist(newRule); + + if (type == FirewallRule.FirewallRuleType.User) { + detectNetworkACLConflict(newRule); + } + + if (!_firewallDao.setStateToAdd(newRule)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRule); + } + UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); + + txn.commit(); + + return newRule; + } + + + protected void validateNetworkACL(Account caller, Network network, Integer portStart, Integer portEnd, + String proto) { + + if (portStart != null && !NetUtils.isValidPort(portStart)) { + throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart); + } + if (portEnd != null && !NetUtils.isValidPort(portEnd)) { + throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd); + } + + // start port can't be bigger than end port + if (portStart != null && portEnd != null && portStart > portEnd) { + throw new InvalidParameterValueException("Start port can't be bigger than end port"); + } + + if (network.getTrafficType() != Networks.TrafficType.Guest) { + throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest); + } + + // Verify that the network guru supports the protocol specified + Map caps = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall); + + + if (caps != null) { + String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); + if (!supportedProtocols.contains(proto.toLowerCase())) { + throw new InvalidParameterValueException("Protocol " + proto + " is not supported by the network " + network); + } + + String firewallType = caps.get(Capability.FirewallType); + if (!firewallType.equalsIgnoreCase("networkacl")) { + throw new UnsupportedOperationException("Network ACLS are not supported in network " + network); + } + } else { + throw new InvalidParameterValueException("No capabilities are found for network " + network); + } + } + + protected void detectNetworkACLConflict(NetworkACL newRule) throws NetworkRuleConflictException { + + List rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.NetworkACL, newRule.getTrafficType()); + assert (rules.size() >= 1) : "For network ACLs, we now always first persist the rule and then check for " + + "network conflicts so we should at least have one rule at this point."; + + for (FirewallRuleVO rule : rules) { + if (rule.getId() == newRule.getId()) { + continue; // Skips my own rule. + } + + // if rules cidrs are different, we can skip port ranges verification + boolean duplicatedCidrs = false; + // Verify that the rules have different cidrs + List ruleCidrList = rule.getSourceCidrList(); + List newRuleCidrList = newRule.getSourceCidrList(); + + if (ruleCidrList == null || newRuleCidrList == null) { + continue; + } + + Collection similar = new HashSet(ruleCidrList); + similar.retainAll(newRuleCidrList); + + if (similar.size() > 0) { + duplicatedCidrs = true; + } + + + if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) { + if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() + && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() + && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) { + throw new InvalidParameterValueException("New network ACL conflicts with existing network ACL id=" + rule.getId()); + } + } + + boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && + rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null); + if (!notNullPorts) { + continue; + } else if (duplicatedCidrs + && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) + || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) { + + throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId() + + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd()); + + } + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing network ACLs"); + } + } + + @Override + public boolean revokeNetworkACL(long ruleId, boolean apply) { + Account caller = UserContext.current().getCaller(); + long userId = UserContext.current().getCallerUserId(); + return revokeNetworkACL(ruleId, apply, caller, userId); + } + + @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true) + protected boolean revokeNetworkACL(long ruleId, boolean apply, Account caller, long userId) { + + FirewallRuleVO rule = _firewallDao.findById(ruleId); + if (rule == null || rule.getPurpose() != Purpose.NetworkACL) { + throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.NetworkACL); + } + + _accountMgr.checkAccess(caller, null, true, rule); + + _firewallMgr.revokeRule(rule, caller, userId, false); + + boolean success = false; + + if (apply) { + List rules = _firewallDao.listByNetworkAndPurpose(rule.getNetworkId(), Purpose.NetworkACL); + success = _firewallMgr.applyFirewallRules(rules, false, caller); + } else { + success = true; + } + + return success; + } + + @Override + public NetworkACL getNetworkACL(long ACLId) { + FirewallRuleVO rule = _firewallDao.findById(ACLId); + if (rule != null && rule.getPurpose() == Purpose.NetworkACL) { + return rule; + } + return null; + } + + @Override + public List listNetworkACLs(ListNetworkACLsCmd cmd) { + Long networkId = cmd.getNetworkId(); + Long id = cmd.getId(); + String trafficType = cmd.getTrafficType(); + + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = + new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, + domainIdRecursiveListProject, cmd.listAll(), false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _firewallDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("id", sb.entity().getId(), Op.EQ); + sb.and("network", sb.entity().getNetworkId(), Op.EQ); + sb.and("purpose", sb.entity().getPurpose(), Op.EQ); + sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ); + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (id != null) { + sc.setParameters("id", id); + } + + if (networkId != null) { + sc.setParameters("networkId", networkId); + } + + if (trafficType != null) { + sc.setParameters("trafficType", trafficType); + } + + sc.setParameters("purpose", Purpose.NetworkACL); + + return _firewallDao.search(sc, filter); + } + + + @Override + public List listNetworkACLs(long guestNtwkId) { + return _firewallDao.listByNetworkAndPurpose(guestNtwkId, Purpose.NetworkACL); + } + + @Override + public boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException { + + List ACLs = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing " + ACLs.size() + " Network ACLs for network id=" + networkId); + } + + for (FirewallRuleVO ACL : ACLs) { + // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no + // need to send them one by one + revokeNetworkACL(ACL.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM); + } + + // now send everything to the backend + boolean success = _firewallMgr.applyFirewallRules(ACLs, false, caller); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " + ACLs.size()); + } + + return success; + } + +} diff --git a/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java new file mode 100644 index 00000000000..62e7e22eef2 --- /dev/null +++ b/server/src/com/cloud/network/vpc/PrivateGatewayProfile.java @@ -0,0 +1,96 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +/** + * @author Alena Prokharchyk + */ +public class PrivateGatewayProfile implements PrivateGateway{ + VpcGateway vpcGateway; + long physicalNetworkId; + + /** + * @param vpcGateway + * @param physicalNetworkId TODO + */ + public PrivateGatewayProfile(VpcGateway vpcGateway, long physicalNetworkId) { + super(); + this.vpcGateway = vpcGateway; + this.physicalNetworkId = physicalNetworkId; + } + + @Override + public long getId() { + return vpcGateway.getId(); + } + + @Override + public String getIp4Address() { + return vpcGateway.getIp4Address(); + } + + @Override + public Type getType() { + return vpcGateway.getType(); + } + + @Override + public Long getVpcId() { + return vpcGateway.getVpcId(); + } + + @Override + public long getZoneId() { + return vpcGateway.getZoneId(); + } + + @Override + public Long getNetworkId() { + return vpcGateway.getNetworkId(); + } + + @Override + public String getUuid() { + return vpcGateway.getUuid(); + } + + @Override + public String getVlanTag() { + return vpcGateway.getVlanTag(); + } + + @Override + public String getGateway() { + return vpcGateway.getGateway(); + } + + @Override + public String getNetmask() { + return vpcGateway.getNetmask(); + } + + @Override + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + @Override + public long getAccountId() { + return vpcGateway.getAccountId(); + } + + @Override + public long getDomainId() { + return vpcGateway.getDomainId(); + } +} diff --git a/server/src/com/cloud/network/vpc/PrivateIpAddress.java b/server/src/com/cloud/network/vpc/PrivateIpAddress.java new file mode 100644 index 00000000000..7a568c17157 --- /dev/null +++ b/server/src/com/cloud/network/vpc/PrivateIpAddress.java @@ -0,0 +1,68 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import com.cloud.utils.net.NetUtils; + +/** + * @author Alena Prokharchyk + */ +public class PrivateIpAddress implements PrivateIp{ + String vlanTag; + String gateway; + String netmask; + String ipAddress; + String macAddress; + + /** + * @param privateIp + * @param vlanTag + * @param gateway + * @param netmask + * @param macAddress TODO + * @param physicalNetworkId TODO + */ + public PrivateIpAddress(PrivateIpVO privateIp, String vlanTag, String gateway, String netmask, long macAddress) { + super(); + this.ipAddress = privateIp.getIpAddress(); + this.vlanTag = vlanTag; + this.gateway = gateway; + this.netmask = netmask; + this.macAddress = NetUtils.long2Mac(macAddress); + } + + @Override + public String getVlanTag() { + return vlanTag; + } + + @Override + public String getGateway() { + return gateway; + } + + @Override + public String getNetmask() { + return netmask; + } + + @Override + public String getIpAddress() { + return ipAddress; + } + + @Override + public String getMacAddress() { + return macAddress; + } +} diff --git a/server/src/com/cloud/network/vpc/PrivateIpVO.java b/server/src/com/cloud/network/vpc/PrivateIpVO.java new file mode 100644 index 00000000000..48397559cfd --- /dev/null +++ b/server/src/com/cloud/network/vpc/PrivateIpVO.java @@ -0,0 +1,84 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="private_ip_address") +public class PrivateIpVO { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="ip_address", updatable=false, nullable=false) + String ipAddress; + + @Column(name="mac_address") + private long macAddress; + + @Column(name="taken") + @Temporal(value=TemporalType.TIMESTAMP) + private Date takenAt; + + @Column(name="network_id", updatable=false, nullable=false) + private long networkId; + + public PrivateIpVO() { + } + + public PrivateIpVO(String ipAddress, long networkId, long macAddress) { + this.ipAddress = ipAddress; + this.networkId = networkId; + this.macAddress = macAddress; + } + + public void setTakenAt(Date takenDate) { + this.takenAt = takenDate; + } + + public String getIpAddress() { + return ipAddress; + } + + public long getNetworkId() { + return networkId; + } + + public Date getTakenAt() { + return takenAt; + } + + public long getId() { + return id; + } + + public long getMacAddress() { + return macAddress; + } +} diff --git a/server/src/com/cloud/network/vpc/StaticRouteVO.java b/server/src/com/cloud/network/vpc/StaticRouteVO.java new file mode 100644 index 00000000000..8859aa8c8d6 --- /dev/null +++ b/server/src/com/cloud/network/vpc/StaticRouteVO.java @@ -0,0 +1,139 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +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 com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="static_routes") +public class StaticRouteVO implements Identity, StaticRoute{ + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="uuid") + String uuid; + + @Column(name="vpc_gateway_id", updatable=false) + long vpcGatewayId; + + @Column(name="cidr") + private String cidr; + + @Enumerated(value=EnumType.STRING) + @Column(name="state") + State state; + + @Column(name="vpc_id") + private Long vpcId; + + @Column(name = "account_id") + long accountId; + + @Column(name = "domain_id") + long domainId; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + protected StaticRouteVO(){ + this.uuid = UUID.randomUUID().toString(); + } + + /** + * @param vpcGatewayId + * @param cidr + * @param vpcId + * @param accountId TODO + * @param domainId TODO + */ + public StaticRouteVO(long vpcGatewayId, String cidr, Long vpcId, long accountId, long domainId) { + super(); + this.vpcGatewayId = vpcGatewayId; + this.cidr = cidr; + this.state = State.Staged; + this.vpcId = vpcId; + this.accountId = accountId; + this.domainId = domainId; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getVpcGatewayId() { + return vpcGatewayId; + } + + @Override + public String getCidr() { + return cidr; + } + + @Override + public State getState() { + return state; + } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public String getUuid() { + return this.uuid; + } + + @Override + public long getId() { + return id; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getDomainId() { + return domainId; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("StaticRoute["); + buf.append(uuid).append("|").append(cidr).append("|").append(vpcGatewayId).append("]"); + return buf.toString(); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/vpc/VpcGatewayVO.java b/server/src/com/cloud/network/vpc/VpcGatewayVO.java new file mode 100644 index 00000000000..2178be327ad --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcGatewayVO.java @@ -0,0 +1,180 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +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 com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc_gateways") +public class VpcGatewayVO implements VpcGateway{ + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name = "ip4_address") + String ip4Address; + + @Column(name="gateway") + String gateway; + + @Column(name="netmask") + String netmask; + + @Column(name="vlan_tag") + String vlanTag; + + @Column(name = "type") + @Enumerated(value = EnumType.STRING) + VpcGateway.Type type; + + @Column(name="vpc_id") + Long vpcId; + + @Column(name="zone_id") + long zoneId; + + @Column(name="network_id") + Long networkId; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + @Column(name=GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name="uuid") + private String uuid; + + @Column(name = "account_id") + long accountId; + + @Column(name = "domain_id") + long domainId; + + protected VpcGatewayVO(){ + this.uuid = UUID.randomUUID().toString(); + } + + /** + * @param ip4Address + * @param type + * @param vpcId + * @param zoneId + * @param networkId + * @param vlanTag TODO + * @param gateway TODO + * @param netmask TODO + * @param accountId TODO + * @param domainId TODO + * @param account_id + */ + public VpcGatewayVO(String ip4Address, Type type, Long vpcId, long zoneId, Long networkId, String vlanTag, + String gateway, String netmask, long accountId, long domainId) { + this.ip4Address = ip4Address; + this.type = type; + this.vpcId = vpcId; + this.zoneId = zoneId; + this.networkId = networkId; + this.vlanTag = vlanTag; + this.gateway = gateway; + this.netmask = netmask; + this.uuid = UUID.randomUUID().toString(); + this.accountId = accountId; + this.domainId = domainId; + } + + @Override + public String getUuid() { + return this.uuid; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getIp4Address() { + return ip4Address; + } + + @Override + public VpcGateway.Type getType() { + return type; + } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public long getZoneId() { + return zoneId; + } + + @Override + public Long getNetworkId() { + return networkId; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("VpcGateway["); + buf.append(id).append("|").append(ip4Address.toString()).append("|").append(vpcId).append("]"); + return buf.toString(); + } + + @Override + public String getGateway() { + return gateway; + } + + @Override + public String getNetmask() { + return netmask; + } + + @Override + public String getVlanTag() { + return vlanTag; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getDomainId() { + return domainId; + } +} diff --git a/server/src/com/cloud/network/vpc/VpcManager.java b/server/src/com/cloud/network/vpc/VpcManager.java new file mode 100644 index 00000000000..55a607f2779 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcManager.java @@ -0,0 +1,99 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.VpcOffering.State; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.vm.DomainRouterVO; + + +/** + * @author Alena Prokharchyk + */ +public interface VpcManager extends VpcService{ + + /** + * @param name + * @param displayText + * @param svcProviderMap + * @param isDefault + * @param state TODO + * @return + */ + VpcOffering createVpcOffering(String name, String displayText, Map> svcProviderMap, + boolean isDefault, State state); + + /** + * @param vpcOffId + * @param services + * @return + */ + boolean areServicesSupportedByVpcOffering(long vpcOffId, Service[] services); + + /** + * @param zoneId + * @param vpcOffId + * @param vpcOwner + * @param vpcName + * @param displayText + * @param cidr + * @param networkDomain TODO + * @return + */ + Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, String networkDomain); + + List getSupportedServices(); + + /** + * @param guestNtwkOff + * @param cidr + * @param networkDomain + * @param networkOwner + * @param vpc TODO + * @return + * @throws ConcurrentOperationException + */ + void validateGuestNtkwForVpc(NetworkOffering guestNtwkOff, String cidr, String networkDomain, Account networkOwner, + Vpc vpc) throws ConcurrentOperationException; + + /** + * @return + */ + VpcProvider getVpcElement(); + + List getVpcsForAccount(long accountId); + + /** + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param vpcId + * @return + */ + List getVpcRouters(long vpcId); +} diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java new file mode 100644 index 00000000000..ab658980ae5 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -0,0 +1,1466 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.api.commands.ListPrivateGatewaysCmd; +import com.cloud.api.commands.ListStaticRoutesCmd; +import com.cloud.configuration.Config; +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeployDestination; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.UnsupportedServiceException; +import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.VpcOffering.State; +import com.cloud.network.vpc.Dao.PrivateIpDao; +import com.cloud.network.vpc.Dao.StaticRouteDao; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.network.vpc.Dao.VpcGatewayDao; +import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.org.Grouping; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GlobalLock; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; +import com.cloud.vm.dao.DomainRouterDao; + + +/** + * @author Alena Prokharchyk + */ + +@Local(value = { VpcManager.class, VpcService.class }) +public class VpcManagerImpl implements VpcManager, Manager{ + private static final Logger s_logger = Logger.getLogger(VpcManagerImpl.class); + @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcOfferingServiceMapDao _vpcOffSvcMapDao; + @Inject + VpcDao _vpcDao; + @Inject + ConfigurationDao _configDao; + @Inject + ConfigurationManager _configMgr; + @Inject + AccountManager _accountMgr; + @Inject + NetworkDao _ntwkDao; + @Inject + NetworkManager _ntwkMgr; + @Inject + IPAddressDao _ipAddressDao; + @Inject + DomainRouterDao _routerDao; + @Inject + VpcGatewayDao _vpcGatewayDao; + @Inject + PrivateIpDao _privateIpDao; + @Inject + StaticRouteDao _staticRouteDao; + @Inject + NetworkOfferingServiceMapDao _ntwkOffServiceDao ; + + private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); + + private VpcProvider vpcElement = null; + + String _name; + int _cleanupInterval; + + @Override + @DB + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + + //configure default vpc offering + Transaction txn = Transaction.currentTxn(); + txn.start(); + + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { + s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); + + Map> svcProviderMap = new HashMap>(); + Set provider = new HashSet(); + provider.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + svcProviderMap.put(svc, provider); + } + createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, + true, State.Enabled); + } + + txn.commit(); + + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + ConfigurationDao configDao = locator.getDao(ConfigurationDao.class); + Map configs = configDao.getConfiguration(params); + String value = configs.get(Config.VpcCleanupInterval.key()); + _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60); // 1 hour + + return true; + } + + @Override + public boolean start() { + _executor.scheduleAtFixedRate(new VpcCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS); + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public List getVpcNetworks(long vpcId) { + return _ntwkDao.listByVpc(vpcId); + } + + @Override + public VpcOffering getVpcOffering(long vpcOffId) { + return _vpcOffDao.findById(vpcOffId); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create=true) + public VpcOffering createVpcOffering(String name, String displayText, List supportedServices) { + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + + boolean sourceNatSvc = false; + boolean firewallSvs = false; + // populate the services first + for (String serviceName : supportedServices) { + // validate if the service is supported + Service service = Network.Service.getService(serviceName); + if (service == null || service == Service.Gateway) { + throw new InvalidParameterValueException("Invalid service " + serviceName); + } + + //don't allow security group service for vpc + if (service == Service.SecurityGroup) { + throw new UnsupportedServiceException("Service " + Service.SecurityGroup.getName() + " is not supported by VPC"); + } + svcProviderMap.put(service, defaultProviders); + } + + if (!sourceNatSvc) { + s_logger.debug("Automatically adding source nat service to the list of VPC services"); + svcProviderMap.put(Service.SourceNat, defaultProviders); + } + + if (!firewallSvs) { + s_logger.debug("Automatically adding firewall service to the list of VPC services"); + svcProviderMap.put(Service.Firewall, defaultProviders); + } + + svcProviderMap.put(Service.Gateway, defaultProviders); + + return createVpcOffering(name, displayText, svcProviderMap, false, null); + } + + + @Override + @DB + public VpcOffering createVpcOffering(String name, String displayText, Map> svcProviderMap, boolean isDefault, State state) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + // create vpc offering object + VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, null); + + if (state != null) { + offering.setState(state); + } + s_logger.debug("Adding vpc offering " + offering); + offering = _vpcOffDao.persist(offering); + // populate services and providers + if (svcProviderMap != null) { + for (Network.Service service : svcProviderMap.keySet()) { + Set providers = svcProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + for (Network.Provider provider : providers) { + VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); + _vpcOffSvcMapDao.persist(offService); + s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); + } + } else { + throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); + } + } + } + txn.commit(); + + UserContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); + return offering; + } + + @Override + public Vpc getVpc(long vpcId) { + return _vpcDao.findById(vpcId); + } + + @Override + public Vpc getActiveVpc(long vpcId) { + return _vpcDao.getActiveVpcById(vpcId); + } + + @Override + public Map> getVpcOffSvcProvidersMap(long vpcOffId) { + Map> serviceProviderMap = new HashMap>(); + List map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId); + + for (VpcOfferingServiceMapVO instance : map) { + String service = instance.getService(); + Set providers; + providers = serviceProviderMap.get(service); + if (providers == null) { + providers = new HashSet(); + } + providers.add(Provider.getProvider(instance.getProvider())); + serviceProviderMap.put(Service.getService(service), providers); + } + + return serviceProviderMap; + } + + + @Override + public List listVpcOfferings(Long id, String name, String displayText, List supportedServicesStr, + Boolean isDefault, String keyword, String state, Long startIndex, Long pageSizeVal) { + Filter searchFilter = new Filter(VpcOfferingVO.class, "created", false, startIndex, pageSizeVal); + SearchCriteria sc = _vpcOffDao.createSearchCriteria(); + + if (keyword != null) { + SearchCriteria ssc = _vpcOffDao.createSearchCriteria(); + ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); + } + + if (displayText != null) { + sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); + } + + if (isDefault != null) { + sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); + } + + if (state != null) { + sc.addAnd("state", SearchCriteria.Op.EQ, state); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + + List offerings = _vpcOffDao.search(sc, searchFilter); + + // filter by supported services + boolean listBySupportedServices = (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty()); + + if (listBySupportedServices) { + List supportedOfferings = new ArrayList(); + Service[] supportedServices = null; + + if (listBySupportedServices) { + supportedServices = new Service[supportedServicesStr.size()]; + int i = 0; + for (String supportedServiceStr : supportedServicesStr) { + Service service = Service.getService(supportedServiceStr); + if (service == null) { + throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr); + } else { + supportedServices[i] = service; + } + i++; + } + } + + for (VpcOfferingVO offering : offerings) { + if (areServicesSupportedByVpcOffering(offering.getId(), supportedServices)) { + supportedOfferings.add(offering); + } + } + + return supportedOfferings; + } else { + return offerings; + } + } + + @Override + public boolean areServicesSupportedByVpcOffering(long vpcOffId, Service... services) { + return (_vpcOffSvcMapDao.areServicesSupportedByNetworkOffering(vpcOffId, services)); + } + + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_DELETE, eventDescription = "deleting vpc offering") + public boolean deleteVpcOffering(long offId) { + UserContext.current().setEventDetails(" Id: " + offId); + + // Verify vpc offering id + VpcOfferingVO offering = _vpcOffDao.findById(offId); + if (offering == null) { + throw new InvalidParameterValueException("unable to find vpc offering " + offId); + } + + // Don't allow to delete default vpc offerings + if (offering.isDefault() == true) { + throw new InvalidParameterValueException("Default network offering can't be deleted"); + } + + // don't allow to delete vpc offering if it's in use by existing vpcs (the offering can be disabled though) + int vpcCount = _vpcDao.getVpcCountByOfferingId(offId); + if (vpcCount > 0) { + throw new InvalidParameterValueException("Can't delete vpc offering " + offId + " as its used by " + vpcCount + " vpcs. " + + "To make the network offering unavaiable, disable it"); + } + + if (_vpcOffDao.remove(offId)) { + return true; + } else { + return false; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_UPDATE, eventDescription = "updating vpc offering") + public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state) { + UserContext.current().setEventDetails(" Id: " + vpcOffId); + + // Verify input parameters + VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId); + if (offeringToUpdate == null) { + throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId); + } + + VpcOfferingVO offering = _vpcOffDao.createForUpdate(vpcOffId); + + if (vpcOfferingName != null) { + offering.setName(vpcOfferingName); + } + + if (displayText != null) { + offering.setDisplayText(displayText); + } + + if (state != null) { + boolean validState = false; + for (VpcOffering.State st : VpcOffering.State.values()) { + if (st.name().equalsIgnoreCase(state)) { + validState = true; + offering.setState(st); + } + } + if (!validState) { + throw new InvalidParameterValueException("Incorrect state value: " + state); + } + } + + if (_vpcOffDao.update(vpcOffId, offering)) { + s_logger.debug("Updated VPC offeirng id=" + vpcOffId); + return _vpcOffDao.findById(vpcOffId); + } else { + return null; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create=true) + public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, + String networkDomain) { + Account caller = UserContext.current().getCaller(); + Account owner = _accountMgr.getAccount(vpcOwnerId); + + //Verify that caller can perform actions in behalf of vpc owner + _accountMgr.checkAccess(caller, null, false, owner); + + // Validate vpc offering + VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId); + if (vpcOff == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find vpc offering by specified id"); + ex.addProxyObject("vpc_offerings", vpcOffId, "vpcOfferingId"); + throw ex; + } + + //Validate zone + DataCenter zone = _configMgr.getZone(zoneId); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { + // See DataCenterVO.java + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled"); + ex.addProxyObject("data_center", zone.getId(), "zoneId"); + throw ex; + } + + if (networkDomain == null) { + // 1) Get networkDomain from the corresponding account + networkDomain = _ntwkMgr.getAccountNetworkDomain(owner.getId(), zoneId); + + + // 2) If null, generate networkDomain using domain suffix from the global config variables + if (networkDomain == null) { + networkDomain = "cs" + Long.toHexString(owner.getId()) + _ntwkMgr.getDefaultNetworkDomain(); + } + } + + return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain); + } + + @Override + public Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, + String networkDomain) { + + //Validate CIDR + if (!NetUtils.isValidCIDR(cidr)) { + throw new InvalidParameterValueException("Invalid CIDR specified " + cidr); + } + + // validate network domain + if (!NetUtils.verifyDomainName(networkDomain)) { + throw new InvalidParameterValueException( + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', " + + "the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); + } + + + VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, + networkDomain); + vpc = _vpcDao.persist(vpc); + + if (vpc != null) { + s_logger.debug("Created VPC " + vpc); + } else { + s_logger.debug("Failed to create VPC"); + } + return vpc; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC") + public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext.current().setEventDetails(" Id: " + vpcId); + Account caller = UserContext.current().getCaller(); + + // Verify vpc id + Vpc vpc = getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("unable to find VPC id=" + vpcId); + } + + //verify permissions + _accountMgr.checkAccess(caller, null, false, vpc); + + return destroyVpc(vpc); + } + + @Override + public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext ctx = UserContext.current(); + + //don't allow to delete vpc if it's in use by existing networks + int networksCount = _ntwkDao.getNetworkCountByVpcId(vpc.getId()); + if (networksCount > 0) { + throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks"); + } + + //mark VPC as disabled + s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete"); + VpcVO vpcVO = _vpcDao.findById(vpc.getId()); + vpcVO.setState(Vpc.State.Inactive); + _vpcDao.update(vpc.getId(), vpcVO); + + //shutdown VPC + if (!shutdownVpc(vpc.getId())) { + s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process"); + return false; + } + + //cleanup vpc resources + if (!cleanupVpcResources(vpc.getId(), ctx.getCaller(), ctx.getCallerUserId())) { + s_logger.warn("Failed to cleanup resources for vpc " + vpc); + return false; + } + + //update the instance with removed flag only when the cleanup is executed successfully + if (_vpcDao.remove(vpc.getId())) { + s_logger.debug("Vpc " + vpc + " is removed succesfully"); + return true; + } else { + return false; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc") + public Vpc updateVpc(long vpcId, String vpcName, String displayText) { + UserContext.current().setEventDetails(" Id: " + vpcId); + Account caller = UserContext.current().getCaller(); + + // Verify input parameters + VpcVO vpcToUpdate = _vpcDao.findById(vpcId); + if (vpcToUpdate == null) { + throw new InvalidParameterValueException("Unable to find vpc offering " + vpcId); + } + + _accountMgr.checkAccess(caller, null, false, vpcToUpdate); + + VpcVO vpc = _vpcDao.createForUpdate(vpcId); + + if (vpcName != null) { + vpc.setName(vpcName); + } + + if (displayText != null) { + vpc.setDisplayText(displayText); + } + + if (_vpcDao.update(vpcId, vpc)) { + s_logger.debug("Updated VPC id=" + vpcId); + return _vpcDao.findById(vpcId); + } else { + return null; + } + } + + + @Override + public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, + String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, + Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired) { + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(VpcVO.class, "created", false, startIndex, pageSizeVal); + + SearchBuilder sb = _vpcDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("displayText", sb.entity().getDisplayText(), SearchCriteria.Op.LIKE); + sb.and("vpcOfferingId", sb.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); + sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ); + + // now set the SC criteria... + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (keyword != null) { + SearchCriteria ssc = _vpcDao.createSearchCriteria(); + ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (vpcName != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + vpcName + "%"); + } + + if (displayText != null) { + sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + if (vpcOffId != null) { + sc.addAnd("vpcOfferingId", SearchCriteria.Op.EQ, vpcOffId); + } + + if (zoneId != null) { + sc.addAnd("zoneId", SearchCriteria.Op.EQ, zoneId); + } + + if (state != null) { + sc.addAnd("state", SearchCriteria.Op.EQ, state); + } + + if (restartRequired != null) { + sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired); + } + + List vpcs = _vpcDao.search(sc, searchFilter); + + // filter by supported services + boolean listBySupportedServices = (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !vpcs.isEmpty()); + + if (listBySupportedServices) { + List supportedVpcs = new ArrayList(); + Service[] supportedServices = null; + + if (listBySupportedServices) { + supportedServices = new Service[supportedServicesStr.size()]; + int i = 0; + for (String supportedServiceStr : supportedServicesStr) { + Service service = Service.getService(supportedServiceStr); + if (service == null) { + throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr); + } else { + supportedServices[i] = service; + } + i++; + } + } + + for (VpcVO vpc : vpcs) { + if (areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), supportedServices)) { + supportedVpcs.add(vpc); + } + } + + return supportedVpcs; + } else { + return vpcs; + } + } + + @Override + public List getSupportedServices() { + List services = new ArrayList(); + services.add(Network.Service.Dhcp); + services.add(Network.Service.Dns); + services.add(Network.Service.UserData); + services.add(Network.Service.Firewall); + services.add(Network.Service.PortForwarding); + services.add(Network.Service.Lb); + services.add(Network.Service.SourceNat); + services.add(Network.Service.StaticNat); + services.add(Network.Service.Gateway); + services.add(Network.Service.Vpn); + return services; + } + + @Override + public boolean startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + User callerUser = _accountMgr.getActiveUser(ctx.getCallerUserId()); + + //check if vpc exists + Vpc vpc = getActiveVpc(vpcId); + if (vpc == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified"); + ex.addProxyObject("vpc", vpcId, "VPC"); + throw ex; + } + + //permission check + _accountMgr.checkAccess(caller, null, false, vpc); + + DataCenter dc = _configMgr.getZone(vpc.getZoneId()); + + DeployDestination dest = new DeployDestination(dc, null, null, null); + ReservationContext context = new ReservationContextImpl(null, null, callerUser, + _accountMgr.getAccount(vpc.getAccountId())); + + boolean result = true; + try { + if (!startVpc(vpc, dest, context)) { + s_logger.warn("Failed to start vpc " + vpc); + result = false; + } + } catch (Exception ex) { + s_logger.warn("Failed to start vpc " + vpc + " due to ", ex); + result = false; + } finally { + //do cleanup + if (!result) { + s_logger.debug("Destroying vpc " + vpc + " that failed to start"); + if (destroyVpc(vpc)) { + s_logger.warn("Successfully destroyed vpc " + vpc + " that failed to start"); + } else { + s_logger.warn("Failed to destroy vpc " + vpc + " that failed to start"); + } + } + } + return result; + } + + protected boolean startVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + //deploy provider + if (getVpcElement().implementVpc(vpc, dest, context)) { + s_logger.debug("Vpc " + vpc + " has started succesfully"); + return true; + } else { + s_logger.warn("Vpc " + vpc + " failed to start"); + return false; + } + } + + @Override + public boolean shutdownVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + + //check if vpc exists + Vpc vpc = getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); + } + + //permission check + _accountMgr.checkAccess(caller, null, false, vpc); + + //shutdown provider + boolean success = getVpcElement().shutdownVpc(vpc); + + //FIXME - once more features are added to vpc (gateway/firewall rules, etc - cleanup them here) + if (success) { + s_logger.debug("Vpc " + vpc + " has been shutdown succesfully"); + } else { + s_logger.warn("Vpc " + vpc + " failed to shutdown"); + } + return success; + } + + @Override + @DB + public void validateGuestNtkwForVpc(NetworkOffering guestNtwkOff, String cidr, String networkDomain, + Account networkOwner, Vpc vpc) throws ConcurrentOperationException { + + Vpc locked = _vpcDao.acquireInLockTable(vpc.getId()); + if (locked == null) { + throw new ConcurrentOperationException("Unable to acquire lock on " + vpc); + } + + try { + //1) CIDR is required + if (cidr == null) { + throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC"); + } + + //2) Network cidr should be within vpcCidr + if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) { + throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr"); + } + + //3) Network cidr shouldn't cross the cidr of other vpc network cidrs + List ntwks = _ntwkDao.listByVpc(vpc.getId()); + for (Network ntwk : ntwks) { + assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?"; + + if (NetUtils.isNetworksOverlap(ntwk.getCidr(), cidr)) { + throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + + " belonging to the same vpc " + vpc); + } + } + + //4) vpc and network should belong to the same owner + if (vpc.getAccountId() != networkOwner.getId()) { + throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + + networkOwner); + } + + //5) Only Isolated networks with Source nat service enabled can be added to vpc + if (!(guestNtwkOff.getGuestType() == GuestType.Isolated + && _ntwkMgr.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.SourceNat))) { + + throw new InvalidParameterValueException("Only networks of type " + GuestType.Isolated + " with service " + + Service.SourceNat + + " can be added as a part of VPC"); + } + + //6) Only VPC VR can be a provider for the network offering + List ntwkOffProviders = _ntwkMgr.getNtwkOffDistinctProviders(guestNtwkOff.getId()); + for (Provider provider : ntwkOffProviders) { + if (provider != Provider.VPCVirtualRouter) { + throw new InvalidParameterValueException("Only VPCVirtualRouter provider is supported in VPC network;" + + " while network offering " + guestNtwkOff + " has " + provider.getName() + " enabled."); + } + } + + //7) No redundant router support + if (guestNtwkOff.getRedundantRouter()) { + throw new InvalidParameterValueException("No redunant router support when network belnogs to VPC"); + } + + //8) Conserve mode should be off + if (guestNtwkOff.isConserveMode()) { + throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC"); + } + + //9) list supported services should be within VPC supported services + List ntwkOffServices = _ntwkOffServiceDao.listServicesForNetworkOffering(guestNtwkOff.getId()); + List vpcOffServices = _vpcOffSvcMapDao.listServicesForVpcOffering(vpc.getVpcOfferingId()); + + if (!vpcOffServices.containsAll(ntwkOffServices)) { + throw new InvalidParameterValueException("VPC doesn't support some of the services specified in the network offering"); + } + + } finally { + s_logger.debug("Releasing lock for " + locked); + _vpcDao.releaseFromLockTable(locked.getId()); + } + } + + @Override + public VpcProvider getVpcElement() { + if (vpcElement == null) { + vpcElement = ((VpcProvider)_ntwkMgr.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); + } + + return vpcElement; + } + + @Override + public List getVpcsForAccount(long accountId) { + return _vpcDao.listByAccountId(accountId); + } + + public boolean cleanupVpcResources(long vpcId, Account caller, long callerUserId) + throws ResourceUnavailableException, ConcurrentOperationException { + s_logger.debug("Cleaning up resources for vpc id=" + vpcId); + boolean success = true; + + //1) release all ip addresses + List ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null); + s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup"); + for (IPAddressVO ipToRelease : ipsToRelease) { + success = success && _ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller); + if (!success) { + s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup"); + } + } + + if (success) { + s_logger.debug("Released ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process"); + } else { + s_logger.warn("Failed to release ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process"); + //although it failed, proceed to the next cleanup step as it doesn't depend on the public ip release + } + + //2) Delete all static route rules + if (!revokeStaticRoutesForVpc(vpcId, caller)) { + s_logger.warn("Failed to revoke static routes for vpc " + vpcId + " as a part of cleanup vpc process"); + return false; + } + + //3) Delete private gateway + PrivateGateway gateway = getVpcPrivateGateway(vpcId); + if (gateway != null) { + s_logger.debug("Deleting private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup"); + if (!deleteVpcPrivateGateway(gateway.getId())) { + success = false; + s_logger.debug("Failed to delete private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup"); + } else { + s_logger.debug("Deleted private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup"); + } + } + + return success; + } + + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc") + public boolean restartVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + Account caller = UserContext.current().getCaller(); + + // Verify input parameters + Vpc vpc = getActiveVpc(vpcId); + if (vpc == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified"); + ex.addProxyObject("vpc", vpcId, "VPC"); + throw ex; + } + + _accountMgr.checkAccess(caller, null, false, vpc); + + s_logger.debug("Restarting VPC " + vpc); + boolean restartRequired = false; + try { + s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process"); + if (!shutdownVpc(vpcId)) { + s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process"); + restartRequired = true; + return false; + } + + s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process"); + if (!startVpc(vpcId)) { + s_logger.warn("Failed to start vpc as a part of VPC " + vpc + " restart process"); + restartRequired = true; + return false; + } + s_logger.debug("VPC " + vpc + " was restarted successfully"); + return true; + } finally { + s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired); + VpcVO vo = _vpcDao.findById(vpcId); + vo.setRestartRequired(restartRequired); + _vpcDao.update(vpc.getId(), vo); + } + } + + @Override + public List getVpcRouters(long vpcId) { + return _routerDao.listByVpcId(vpcId); + } + + @Override + public PrivateGateway getVpcPrivateGateway(long id) { + VpcGateway gateway = _vpcGatewayDao.findById(id); + + if (gateway == null || gateway.getType() != VpcGateway.Type.Private) { + return null; + } + return getPrivateGatewayProfile(gateway); + } + + @Override + public VpcGateway getVpcGateway(long id) { + return _vpcGatewayDao.findById(id); + } + + protected PrivateGateway getPrivateGatewayProfile(VpcGateway gateway) { + Network network = _ntwkMgr.getNetwork(gateway.getNetworkId()); + return new PrivateGatewayProfile(gateway, network.getPhysicalNetworkId()); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating vpc private gateway", create=true) + public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, + String gateway, String netmask, long gatewayOwnerId) throws ResourceAllocationException, + ConcurrentOperationException, InsufficientCapacityException { + + //Validate parameters + Vpc vpc = getActiveVpc(vpcId); + if (vpc == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified"); + ex.addProxyObject("vpc", vpcId, "VPC"); + throw ex; + } + + //allow only one private gateway per vpc + VpcGatewayVO gatewayVO = _vpcGatewayDao.getPrivateGateway(vpcId); + if (gatewayVO != null) { + throw new InvalidParameterValueException("Private ip address already exists for vpc " + vpc); + } + + //Validate physical network + if (physicalNetworkId == null) { + List pNtwks = _ntwkMgr.getPhysicalNtwksSupportingTrafficType(vpc.getZoneId(), TrafficType.Guest); + if (pNtwks.isEmpty() || pNtwks.size() != 1) { + throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id"); + } + physicalNetworkId = pNtwks.get(0).getId(); + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + s_logger.debug("Creating Private gateway for VPC " + vpc); + //1) create private network + String networkName = "vpc-" + vpc.getName() + "-privateNetwork"; + Network privateNtwk = _ntwkMgr.createPrivateNetwork(networkName, networkName, physicalNetworkId, + vlan, ipAddress, null, gateway, netmask, gatewayOwnerId); + + //2) create gateway entry + gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), + privateNtwk.getId(), vlan, gateway, netmask, vpc.getAccountId(), vpc.getDomainId()); + _vpcGatewayDao.persist(gatewayVO); + + s_logger.debug("Created vpc gateway entry " + gatewayVO); + + txn.commit(); + + return getVpcPrivateGateway(gatewayVO.getId()); + } + + + @Override + public PrivateGateway applyVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { + PrivateGateway gateway = getVpcPrivateGateway(gatewayId); + if (getVpcElement().createPrivateGateway(gateway)) { + s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); + return gateway; + } else { + s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); + return null; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_DELETE, eventDescription = "deleting private gateway") + public boolean deleteVpcPrivateGateway(Long gatewayId) throws ConcurrentOperationException, ResourceUnavailableException { + VpcGatewayVO gatewayVO = _vpcGatewayDao.findById(gatewayId); + if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) { + throw new InvalidParameterValueException("Can't find private gateway by id specified"); + } + + //don't allow to remove gateway when there are static routes associated with it + long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId()); + if (routeCount > 0) { + throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount + + " static routes applied. Remove the routes first"); + } + + //1) delete the gateway on the backend + PrivateGateway gateway = getVpcPrivateGateway(gatewayId); + if (getVpcElement().deletePrivateGateway(gateway)) { + s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend"); + } else { + s_logger.warn("Private gateway " + gateway + " failed to apply on the backend"); + return false; + } + + //2) Delete private gateway from the DB + return deletePrivateGatewayFromTheDB(gateway); + } + + @DB + protected boolean deletePrivateGatewayFromTheDB(PrivateGateway gateway) { + //check if there are ips allocted in the network + long networkId = gateway.getNetworkId(); + + boolean deleteNetwork = true; + List privateIps = _privateIpDao.listByNetworkId(networkId); + if (privateIps.size() > 1 || !privateIps.get(0).getIpAddress().equalsIgnoreCase(gateway.getIp4Address())) { + s_logger.debug("Not removing network id=" + gateway.getNetworkId() + " as it has private ip addresses for other gateways"); + deleteNetwork = false; + } + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(gateway.getNetworkId(), gateway.getIp4Address()); + if (ip != null) { + _privateIpDao.remove(ip.getId()); + s_logger.debug("Deleted private ip " + ip); + } + + if (deleteNetwork) { + User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + Account owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner); + _ntwkMgr.destroyNetwork(networkId, context); + s_logger.debug("Deleted private network id=" + networkId); + } + + _vpcGatewayDao.remove(gateway.getId()); + s_logger.debug("Deleted private gateway " + gateway); + + txn.commit(); + return true; + } + + @Override + public List listPrivateGateway(ListPrivateGatewaysCmd cmd) { + String ipAddress = cmd.getIpAddress(); + String vlan = cmd.getVlan(); + Long vpcId = cmd.getVpcId(); + Long id = cmd.getId(); + Boolean isRecursive = cmd.isRecursive(); + Boolean listAll = cmd.listAll(); + Long domainId = cmd.getDomainId(); + String accountName = cmd.getAccountName(); + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Filter searchFilter = new Filter(VpcGatewayVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, null, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + + SearchBuilder sb = _vpcGatewayDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (vlan != null) { + SearchBuilder ntwkSearch = _ntwkDao.createSearchBuilder(); + ntwkSearch.and("vlan", ntwkSearch.entity().getBroadcastUri(), SearchCriteria.Op.EQ); + sb.join("networkSearch", ntwkSearch, sb.entity().getNetworkId(), ntwkSearch.entity().getId(), JoinBuilder.JoinType.INNER); + } + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (id != null) { + sc.addAnd("id", Op.EQ, id); + } + + if (ipAddress != null) { + sc.addAnd("ip4Address", Op.EQ, ipAddress); + } + + if (vpcId != null) { + sc.addAnd("vpcId", Op.EQ, vpcId); + } + + if (vlan != null) { + sc.setJoinParameters("networkSearch", "vlan", BroadcastDomainType.Vlan.toUri(vlan)); + } + + List vos = _vpcGatewayDao.search(sc, searchFilter); + List privateGtws = new ArrayList(vos.size()); + for (VpcGateway vo : vos) { + privateGtws.add(getPrivateGatewayProfile(vo)); + } + + return privateGtws; + } + + @Override + public StaticRoute getStaticRoute(long routeId) { + return _staticRouteDao.findById(routeId); + } + + @Override + public boolean applyStaticRoutes(long vpcId) throws ResourceUnavailableException { + Account caller = UserContext.current().getCaller(); + List routes = _staticRouteDao.listByVpcId(vpcId); + return applyStaticRoutes(routes, caller, true); + } + + protected boolean applyStaticRoutes(List routes, Account caller, boolean updateRoutesInDB) throws ResourceUnavailableException { + boolean success = true; + List staticRouteProfiles = new ArrayList(routes.size()); + Map gatewayMap = new HashMap(); + for (StaticRoute route : routes) { + VpcGateway gateway = gatewayMap.get(route.getVpcGatewayId()); + if (gateway == null) { + gateway = _vpcGatewayDao.findById(route.getVpcGatewayId()); + gatewayMap.put(gateway.getId(), gateway); + } + staticRouteProfiles.add(new StaticRouteProfile(route, gateway)); + } + if (!applyStaticRoutes(staticRouteProfiles)) { + s_logger.warn("Routes are not completely applied"); + return false; + } else { + if (updateRoutesInDB) { + for (StaticRoute route : routes) { + if (route.getState() == StaticRoute.State.Revoke) { + _staticRouteDao.remove(route.getId()); + s_logger.debug("Removed route " + route + " from the DB"); + } else if (route.getState() == StaticRoute.State.Add) { + StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId()); + ruleVO.setState(StaticRoute.State.Active); + _staticRouteDao.update(ruleVO.getId(), ruleVO); + s_logger.debug("Marked route " + route + " with state " + StaticRoute.State.Active); + } + } + } + } + + return success; + } + + protected boolean applyStaticRoutes(List routes) throws ResourceUnavailableException{ + if (routes.isEmpty()) { + s_logger.debug("No static routes to apply"); + return true; + } + Vpc vpc = getVpc(routes.get(0).getVpcId()); + + s_logger.debug("Applying static routes for vpc " + vpc); + if (getVpcElement().applyStaticRoutes(vpc, routes)) { + s_logger.debug("Applied static routes for vpc " + vpc); + } else { + s_logger.warn("Failed to apply static routes for vpc " + vpc); + return false; + } + + return true; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_DELETE, eventDescription = "deleting static route") + public boolean revokeStaticRoute(long routeId) throws ResourceUnavailableException { + Account caller = UserContext.current().getCaller(); + + StaticRouteVO route = _staticRouteDao.findById(routeId); + if (route == null) { + throw new InvalidParameterValueException("Unable to find static route by id"); + } + + _accountMgr.checkAccess(caller, null, false, route); + + markStaticRouteForRevoke(route, caller); + + return applyStaticRoutes(route.getVpcId()); + } + + @DB + protected boolean revokeStaticRoutesForVpc(long vpcId, Account caller) throws ResourceUnavailableException { + //get all static routes for the vpc + List routes = _staticRouteDao.listByVpcId(vpcId); + s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId); + if (!routes.isEmpty()) { + //mark all of them as revoke + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (StaticRouteVO route : routes) { + markStaticRouteForRevoke(route, caller); + } + txn.commit(); + return applyStaticRoutes(vpcId); + } + + return true; + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_STATIC_ROUTE_CREATE, eventDescription = "creating static route", create=true) + public StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException { + Account caller = UserContext.current().getCaller(); + + //parameters validation + VpcGateway gateway = _vpcGatewayDao.findById(gatewayId); + if (gateway == null) { + throw new InvalidParameterValueException("Invalid gateway id is given"); + } + + Vpc vpc = getActiveVpc(gateway.getVpcId()); + if (vpc == null) { + throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted"); + } + _accountMgr.checkAccess(caller, null, false, vpc); + + if (!NetUtils.isValidCIDR(cidr)){ + throw new InvalidParameterValueException("Invalid format for cidr " + cidr); + } + + //TODO - check cidr for the conflicts + Transaction txn = Transaction.currentTxn(); + txn.start(); + + StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId()); + s_logger.debug("Adding static route " + newRoute); + newRoute = _staticRouteDao.persist(newRoute); + + detectRoutesConflict(newRoute); + + if (!_staticRouteDao.setStateToAdd(newRoute)) { + throw new CloudRuntimeException("Unable to update the state to add for " + newRoute); + } + UserContext.current().setEventDetails("Static route Id: " + newRoute.getId()); + + txn.commit(); + + return newRoute; + } + + @Override + public List listStaticRoutes(ListStaticRoutesCmd cmd) { + Long id = cmd.getId(); + Long gatewayId = cmd.getGatewayId(); + Long vpcId = cmd.getVpcId(); + Long domainId = cmd.getDomainId(); + Boolean isRecursive = cmd.isRecursive(); + Boolean listAll = cmd.listAll(); + String accountName = cmd.getAccountName(); + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(StaticRouteVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + + SearchBuilder sb = _staticRouteDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); + sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ); + + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (id != null) { + sc.addAnd("id", Op.EQ, id); + } + + if (vpcId != null) { + sc.addAnd("vpcId", Op.EQ, vpcId); + } + + if (gatewayId != null) { + sc.addAnd("vpcGatewayId", Op.EQ, vpcId); + } + + return _staticRouteDao.search(sc, searchFilter); + } + + protected void detectRoutesConflict(StaticRoute newRoute) throws NetworkRuleConflictException { + List routes = _staticRouteDao.listByGatewayIdAndNotRevoked(newRoute.getVpcGatewayId()); + assert (routes.size() >= 1) : "For static routes, we now always first persist the route and then check for " + + "network conflicts so we should at least have one rule at this point."; + + for (StaticRoute route : routes) { + if (route.getId() == newRoute.getId()) { + continue; // Skips my own route. + } + + if (NetUtils.isNetworksOverlap(route.getCidr(), newRoute.getCidr())) { + throw new NetworkRuleConflictException("New static route cidr conflicts with existing route " + route); + } + } + } + + protected void markStaticRouteForRevoke(StaticRouteVO route, Account caller) { + s_logger.debug("Revoking static route " + route); + if (caller != null) { + _accountMgr.checkAccess(caller, null, false, route); + } + + if (route.getState() == StaticRoute.State.Staged) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a static route that is still in stage state so just removing it: " + route); + } + _staticRouteDao.remove(route.getId()); + } else if (route.getState() == StaticRoute.State.Add || route.getState() == StaticRoute.State.Active) { + route.setState(StaticRoute.State.Revoke); + _staticRouteDao.update(route.getId(), route); + s_logger.debug("Marked static route " + route + " with state " + StaticRoute.State.Revoke); + } + } + + protected class VpcCleanupTask implements Runnable { + @Override + public void run() { + try { + GlobalLock lock = GlobalLock.getInternLock("VpcCleanup"); + if (lock == null) { + s_logger.debug("Couldn't get the global lock"); + return; + } + + if (!lock.lock(30)) { + s_logger.debug("Couldn't lock the db"); + return; + } + + Transaction txn = null; + try { + txn = Transaction.open(Transaction.CLOUD_DB); + + // Cleanup inactive VPCs + List inactiveVpcs = _vpcDao.listInactiveVpcs(); + s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup"); + for (VpcVO vpc : inactiveVpcs) { + s_logger.debug("Cleaning up " + vpc); + destroyVpc(vpc); + } + } catch (Exception e) { + s_logger.error("Exception ", e); + } finally { + if (txn != null) { + txn.close(); + } + lock.unlock(); + } + } catch (Exception e) { + s_logger.error("Exception ", e); + } + } + } +} diff --git a/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java b/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java new file mode 100644 index 00000000000..ffe8533cdf9 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java @@ -0,0 +1,87 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc_offering_service_map") +public class VpcOfferingServiceMapVO { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="vpc_offering_id") + long vpcOfferingId; + + @Column(name="service") + String service; + + @Column(name="provider") + String provider; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + public long getId() { + return id; + } + + public long getVpcOfferingId() { + return vpcOfferingId; + } + + public String getService() { + return service; + } + + public String getProvider() { + return provider; + } + + public Date getCreated() { + return created; + } + + public VpcOfferingServiceMapVO() { + } + + public VpcOfferingServiceMapVO(long vpcOfferingId, Service service, Provider provider) { + this.vpcOfferingId = vpcOfferingId; + this.service = service.getName(); + if (provider != null) { + this.provider = provider.getName(); + } + } + + public String toString() { + StringBuilder buf = new StringBuilder("[VPC Offering Service["); + return buf.append(vpcOfferingId).append("-").append(service).append("-").append(provider).append("]").toString(); + } +} diff --git a/server/src/com/cloud/network/vpc/VpcOfferingVO.java b/server/src/com/cloud/network/vpc/VpcOfferingVO.java new file mode 100644 index 00000000000..2109e1c0cd7 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcOfferingVO.java @@ -0,0 +1,150 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +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 com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc_offerings") +public class VpcOfferingVO implements VpcOffering{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name="uuid") + private String uuid; + + @Column(name = "name") + String name; + + @Column(name = "unique_name") + String uniqueName; + + @Column(name = "display_text") + String displayText; + + @Column(name = "state") + @Enumerated(value = EnumType.STRING) + State state = State.Disabled; + + @Column(name = "default") + boolean isDefault = false; + + @Column(name = GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + Date created; + + @Column(name = "service_offering_id") + Long serviceOfferingId; + + public VpcOfferingVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public VpcOfferingVO(String name, String displayText, Long serviceOfferingId) { + this.name = name; + this.displayText = displayText; + this.uniqueName = name; + this.serviceOfferingId = serviceOfferingId; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId) { + this(name, displayText, serviceOfferingId); + this.isDefault = isDefault; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getUniqueName() { + return uniqueName; + } + + @Override + public String getDisplayText() { + return displayText; + } + + @Override + public State getState() { + return state; + } + + @Override + public boolean isDefault() { + return isDefault; + } + + public void setUniqueName(String uniqueName) { + this.uniqueName = uniqueName; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("[VPC Offering ["); + return buf.append(id).append("-").append(name).append("]").toString(); + } + + public void setName(String name) { + this.name = name; + } + + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public Long getServiceOfferingId() { + return serviceOfferingId; + } +} diff --git a/server/src/com/cloud/network/vpc/VpcVO.java b/server/src/com/cloud/network/vpc/VpcVO.java new file mode 100644 index 00000000000..212a124f9b7 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcVO.java @@ -0,0 +1,187 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc") +public class VpcVO implements Vpc, Identity { + @Id + @Column(name="id") + long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="name") + private String name; + + @Column(name = "display_text") + String displayText; + + @Column(name="zone_id") + long zoneId; + + @Column(name="cidr") + private String cidr = null; + + @Column(name="domain_id") + Long domainId = null; + + @Column(name="account_id") + Long accountId = null; + + @Column(name="state") + @Enumerated(value=EnumType.STRING) + State state; + + @Column(name="vpc_offering_id") + long vpcOfferingId; + + @Column(name=GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + @Column(name="network_domain") + String networkDomain; + + @Column(name="restart_required") + boolean restartRequired = false; + + public VpcVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr, + String networkDomain) { + this.zoneId = zoneId; + this.name = name; + this.displayText = displayText; + this.accountId = accountId; + this.domainId = domainId; + this.cidr = cidr; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Enabled; + this.networkDomain = networkDomain; + this.vpcOfferingId = vpcOffId; + } + + @Override + public boolean readyToUse() { + return state == State.Enabled; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getName() { + return name; + } + + @Override + public long getZoneId() { + return zoneId; + } + + @Override + public String getCidr() { + return cidr; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public long getVpcOfferingId() { + return vpcOfferingId; + } + + public Date getRemoved() { + return removed; + } + + @Override + public String getDisplayText() { + return displayText; + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("[VPC ["); + return buf.append(id).append("-").append(name).append("]").toString(); + } + + @Override + public String getNetworkDomain() { + return networkDomain; + } + + public void setRestartRequired(boolean restartRequired) { + this.restartRequired = restartRequired; + } + + @Override + public boolean isRestartRequired() { + return restartRequired; + } +} diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 035629ceb85..9290044e324 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -102,7 +102,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag SearchBuilder VpnSearch; @Override - public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException { + public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall, long networkId) + throws NetworkRuleConflictException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); @@ -114,7 +115,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag _accountMgr.checkAccess(caller, null, true, ipAddr); - if (!ipAddr.readyToUse() || ipAddr.getAssociatedWithNetworkId() == null) { + if (!ipAddr.readyToUse()) { throw new InvalidParameterValueException("The Ip address is not ready to be used yet: " + ipAddr.getAddress()); } @@ -132,7 +133,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } // TODO: assumes one virtual network / domr per account per zone - vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), ipAddr.getAssociatedWithNetworkId()); + vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), networkId); if (vpnVO != null) { //if vpn is in Added state, return it to the api if (vpnVO.getState() == RemoteAccessVpn.State.Added) { @@ -142,7 +143,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } //Verify that vpn service is enabled for the network - Network network = _networkMgr.getNetwork(ipAddr.getAssociatedWithNetworkId()); + Network network = _networkMgr.getNetwork(networkId); if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Vpn)) { throw new InvalidParameterValueException("Vpn service is not supported in network id=" + ipAddr.getAssociatedWithNetworkId()); } diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java new file mode 100644 index 00000000000..6c41ec8cacf --- /dev/null +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -0,0 +1,336 @@ +package com.cloud.network.vpn; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.api.commands.CreateVpnConnectionCmd; +import com.cloud.api.commands.CreateVpnCustomerGatewayCmd; +import com.cloud.api.commands.CreateVpnGatewayCmd; +import com.cloud.api.commands.DeleteVpnConnectionCmd; +import com.cloud.api.commands.DeleteVpnCustomerGatewayCmd; +import com.cloud.api.commands.DeleteVpnGatewayCmd; +import com.cloud.api.commands.ListVpnConnectionsCmd; +import com.cloud.api.commands.ListVpnCustomerGatewaysCmd; +import com.cloud.api.commands.ListVpnGatewaysCmd; +import com.cloud.api.commands.ResetVpnConnectionCmd; +import com.cloud.api.commands.UpdateVpnCustomerGatewayCmd; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; +import com.cloud.network.NetworkManager; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteCustomerGatewayVO; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnConnection.State; +import com.cloud.network.Site2SiteVpnConnectionVO; +import com.cloud.network.Site2SiteVpnGateway; +import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.dao.Site2SiteVpnConnectionDao; +import com.cloud.network.dao.Site2SiteVpnGatewayDao; +import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.net.NetUtils; + +@Local(value = Site2SiteVpnService.class) +public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { + private static final Logger s_logger = Logger.getLogger(Site2SiteVpnManagerImpl.class); + + @Inject Site2SiteCustomerGatewayDao _customerGatewayDao; + @Inject Site2SiteVpnGatewayDao _vpnGatewayDao; + @Inject Site2SiteVpnConnectionDao _vpnConnectionDao; + @Inject NetworkManager _networkMgr; + @Inject VpcDao _vpcDao; + @Inject IPAddressDao _ipAddressDao; + + String _name; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { + Long ipId = cmd.getPublicIpId(); + IpAddress ip = _networkMgr.getIp(ipId); + if (ip.getVpcId() == null) { + throw new InvalidParameterValueException("The VPN gateway cannot create with ip not belong to VPC"); + } + if (_vpnGatewayDao.findByIpAddrId(ipId) != null) { + throw new InvalidParameterValueException("The VPN gateway with ip ID " + ipId + " already existed!"); + } + Site2SiteVpnGatewayVO gw = new Site2SiteVpnGatewayVO(ipId); + _vpnGatewayDao.persist(gw); + return gw; + } + + @Override + public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCmd cmd) { + String gatewayIp = cmd.getGatewayIp(); + if (!NetUtils.isValidIp(gatewayIp)) { + throw new InvalidParameterValueException("The customer gateway ip " + gatewayIp + " is invalid!"); + } + String guestCidrList = cmd.getGuestCidrList(); + if (!NetUtils.validateGuestCidrList(guestCidrList)) { + throw new InvalidParameterValueException("The customer gateway guest cidr list " + guestCidrList + " is invalid guest cidr!"); + } + String ipsecPsk = cmd.getIpsecPsk(); + String ikePolicy = cmd.getIkePolicy(); + String espPolicy = cmd.getEspPolicy(); + if (!NetUtils.isValidS2SVpnPolicy(ikePolicy)) { + throw new InvalidParameterValueException("The customer gateway IKE policy" + ikePolicy + " is invalid!"); + } + if (!NetUtils.isValidS2SVpnPolicy(espPolicy)) { + throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!"); + } + Long lifetime = cmd.getLifetime(); + if (lifetime == null) { + // Default value of lifetime is 1 day + lifetime = (long) 86400; + } + if (lifetime > 86400) { + throw new InvalidParameterValueException("The lifetime " + lifetime + " of vpn connection is invalid!"); + } + if (_customerGatewayDao.findByGatewayIp(gatewayIp) != null) { + throw new InvalidParameterValueException("The customer gateway with ip " + gatewayIp + " already existed!"); + } + Site2SiteCustomerGatewayVO gw = new Site2SiteCustomerGatewayVO(gatewayIp, guestCidrList, ipsecPsk, + ikePolicy, espPolicy, lifetime); + _customerGatewayDao.persist(gw); + return gw; + } + + @Override + public Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException { + Long customerGatewayId = cmd.getCustomerGatewayId(); + Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(customerGatewayId); + if (customerGateway == null) { + throw new InvalidParameterValueException("Unable to found specified Site to Site VPN customer gateway " + customerGatewayId + " !"); + } + Long vpnGatewayId = cmd.getVpnGatewayId(); + Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(vpnGatewayId); + if (vpnGateway == null) { + throw new InvalidParameterValueException("Unable to found specified Site to Site VPN gateway " + vpnGatewayId + " !"); + } + if (_vpnConnectionDao.findByCustomerGatewayId(customerGatewayId) != null || + _vpnConnectionDao.findByVpnGatewayId(vpnGatewayId) != null) { + throw new InvalidParameterValueException("The vpn connection with customer gateway id " + customerGatewayId + " or vpn gateway id " + + vpnGatewayId + " already existed!"); + } + Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(vpnGatewayId, customerGatewayId); + return conn; + } + + @Override + public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { + Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); + if (conn.getState() != State.Pending && conn.getState() != State.Disconnected) { + throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(pending or disconnected) to process!"); + } + + conn.setState(State.Pending); + _vpnConnectionDao.persist(conn); + List elements = _networkMgr.getSite2SiteVpnElements(); + boolean result = true; + for (Site2SiteVpnServiceProvider element : elements) { + result = result & element.startSite2SiteVpn(conn); + } + + if (result) { + conn.setState(State.Connected); + _vpnConnectionDao.persist(conn); + return conn; + } + conn.setState(State.Error); + _vpnConnectionDao.persist(conn); + throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id); + } + + @Override + public IpAddress getVpnGatewayIp(Long vpnGatewayId) { + Site2SiteVpnGatewayVO gateway = _vpnGatewayDao.findById(vpnGatewayId); + IpAddress ip = _networkMgr.getIp(gateway.getAddrId()); + return ip; + } + + @Override + public Site2SiteCustomerGateway deleteCustomerGateway(DeleteVpnCustomerGatewayCmd cmd) { + Long id = cmd.getId(); + Site2SiteCustomerGateway customerGateway = _customerGatewayDao.findById(id); + if (customerGateway == null) { + throw new InvalidParameterValueException("Fail to find customer gateway with " + id + " !"); + } + _customerGatewayDao.remove(id); + return customerGateway; + } + + @Override + public Site2SiteVpnGateway deleteVpnGateway(DeleteVpnGatewayCmd cmd) { + Long id = cmd.getId(); + Site2SiteVpnGateway vpnGateway = _vpnGatewayDao.findById(id); + if (vpnGateway == null) { + throw new InvalidParameterValueException("Fail to find vpn gateway with " + id + " !"); + } + _vpnGatewayDao.remove(id); + return vpnGateway; + } + + @Override + public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCmd cmd) { + Long id = cmd.getId(); + Site2SiteCustomerGatewayVO gw = _customerGatewayDao.findById(id); + if (gw == null) { + throw new InvalidParameterValueException("Find to find customer gateway with id " + id); + } + Site2SiteVpnConnection conn = _vpnConnectionDao.findByCustomerGatewayId(id); + if (conn != null && (conn.getState() != State.Disconnected || conn.getState() != State.Error)) { + throw new InvalidParameterValueException("Unable to update customer gateway because there is the correlate VPN connection " + conn.getId() + + " still active!"); + } + String gatewayIp = cmd.getGatewayIp(); + if (!NetUtils.isValidIp(gatewayIp)) { + throw new InvalidParameterValueException("The customer gateway ip " + gatewayIp + " is invalid!"); + } + String guestCidrList = cmd.getGuestCidrList(); + if (!NetUtils.validateGuestCidrList(guestCidrList)) { + throw new InvalidParameterValueException("The customer gateway guest cidr list " + guestCidrList + " contains invalid guest cidr!"); + } + String ipsecPsk = cmd.getIpsecPsk(); + String ikePolicy = cmd.getIkePolicy(); + String espPolicy = cmd.getEspPolicy(); + if (!NetUtils.isValidS2SVpnPolicy(ikePolicy)) { + throw new InvalidParameterValueException("The customer gateway IKE policy" + ikePolicy + " is invalid!"); + } + if (!NetUtils.isValidS2SVpnPolicy(espPolicy)) { + throw new InvalidParameterValueException("The customer gateway ESP policy" + espPolicy + " is invalid!"); + } + Long lifetime = cmd.getLifetime(); + if (lifetime == null) { + // Default value of lifetime is 1 day + lifetime = (long) 86400; + } + if (lifetime > 86400) { + throw new InvalidParameterValueException("The lifetime " + lifetime + " of vpn connection is invalid!"); + } + gw.setGatewayIp(gatewayIp); + gw.setGuestCidrList(guestCidrList); + gw.setIkePolicy(ikePolicy); + gw.setEspPolicy(espPolicy); + gw.setIpsecPsk(ipsecPsk); + gw.setLifetime(lifetime); + _customerGatewayDao.persist(gw); + return gw; + } + + @Override + public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUnavailableException { + Long id = cmd.getId(); + Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); + if (conn == null) { + throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to delete!"); + } + if (conn.getState() == State.Connected) { + stopVpnConnection(id); + } + _vpnConnectionDao.remove(id); + return conn; + } + + private void stopVpnConnection(Long id) throws ResourceUnavailableException { + Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); + if (conn.getState() != State.Connected && conn.getState() != State.Error) { + throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(connected) to process disconnect!"); + } + + List elements = _networkMgr.getSite2SiteVpnElements(); + boolean result = true; + conn.setState(State.Disconnected); + _vpnConnectionDao.persist(conn); + for (Site2SiteVpnServiceProvider element : elements) { + result = result & element.stopSite2SiteVpn(conn); + } + + if (!result) { + conn.setState(State.Error); + _vpnConnectionDao.persist(conn); + throw new ResourceUnavailableException("Failed to apply site-to-site VPN", Site2SiteVpnConnection.class, id); + } + } + + @Override + public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) throws ResourceUnavailableException { + Long id = cmd.getId(); + Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id); + if (conn == null) { + throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to reset!"); + } + if (conn.getState() == State.Connected || conn.getState() == State.Error) { + stopVpnConnection(id); + } + startVpnConnection(id); + return conn; + } + + @Override + public List searchForCustomerGateways(ListVpnCustomerGatewaysCmd cmd) { + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_customerGatewayDao.findById(cmd.getId())); + } else { + results.addAll(_customerGatewayDao.listAll()); + } + return results; + } + + @Override + public List searchForVpnGateways(ListVpnGatewaysCmd cmd) { + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_vpnGatewayDao.findById(cmd.getId())); + } else { + results.addAll(_vpnGatewayDao.listAll()); + } + return results; + } + + @Override + public List searchForVpnConnections(ListVpnConnectionsCmd cmd) { + Long id = cmd.getId(); + List results = new ArrayList(); + if (id != null) { + results.add(_vpnConnectionDao.findById(cmd.getId())); + } else { + results.addAll(_vpnConnectionDao.listAll()); + } + return results; + } +} diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index cf0e6702437..d1adeac96a8 100755 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -307,6 +307,12 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { this(name, "System Offering for " + name, trafficType, true, false, 0, 0, true, Availability.Required, null, null, true, specifyIpRanges); this.state = State.Enabled; } + + public NetworkOfferingVO(String name, Network.GuestType guestType) { + this(name, "System Offering for " + name, TrafficType.Guest, true, true, 0, 0, true, Availability.Optional, + null, Network.GuestType.Isolated, true, false); + this.state = State.Enabled; + } @Override public String toString() { diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java index 2ab4507d765..430c94de91b 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java @@ -26,11 +26,18 @@ import com.cloud.utils.db.GenericDao; */ public interface NetworkOfferingServiceMapDao extends GenericDao { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); + List listByNetworkOfferingId(long networkOfferingId); + void deleteByOfferingId(long networkOfferingId); + List listProvidersForServiceForNetworkOffering(long networkOfferingId, Service service); + boolean isProviderForNetworkOffering(long networkOfferingId, Provider provider); + List listServicesForNetworkOffering(long networkOfferingId); + + List getDistinctProviders(long offId); } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java index 28eed904e43..c43220dd38b 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java @@ -17,12 +17,9 @@ import java.util.List; import javax.ejb.Local; -import com.cloud.exception.UnsupportedServiceException; -import com.cloud.network.NetworkServiceMapVO; -import com.cloud.network.Network.Service; import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; import com.cloud.offerings.NetworkOfferingServiceMapVO; -import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -37,6 +34,8 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase MultipleServicesSearch; final GenericSearchBuilder ProvidersSearch; final GenericSearchBuilder ServicesSearch; + final GenericSearchBuilder DistinctProvidersSearch; + protected NetworkOfferingServiceMapDaoImpl() { super(); @@ -62,6 +61,12 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase getDistinctProviders(long offId) { + SearchCriteria sc = DistinctProvidersSearch.create(); + sc.setParameters("offId", offId); + List results = customSearch(sc, null); + return results; + } } diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index f611441712a..9b06e49a58f 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -585,12 +585,16 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ Project project = getProject(projectId); if (project == null) { - throw new InvalidParameterValueException("Unable to find the project id=" + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } //User can be added to Active project only if (project.getState() != Project.State.Active) { - throw new InvalidParameterValueException("Can't add account to the project id=" + projectId + " in state=" + project.getState() + " as it's no longer active"); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } //check that account-to-add exists @@ -598,7 +602,10 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ if (accountName != null) { account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId()); if (account == null) { - throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id"); + // We don't have a DomainVO object with us, so just pass the tablename "domain" manually. + ex.addProxyObject("domain", project.getDomainId(), "domainId"); + throw ex; } //verify permissions - only project owner can assign @@ -660,13 +667,17 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ Project project = getProject(projectId); if (project == null) { - throw new InvalidParameterValueException("Unable to find the project id=" + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } //check that account-to-remove exists Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId()); if (account == null) { - throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); + // Since we don't have a domainVO object, pass the table name manually. + ex.addProxyObject("domain", project.getDomainId(), "domainId"); } //verify permissions @@ -675,12 +686,17 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ //Check if the account exists in the project ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId()); if (projectAccount == null) { - throw new InvalidParameterValueException("Account " + accountName + " is not assigned to the project id=" + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id"); + // Use the projectVO object and not the projectAccount object to inject the projectId. + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } //can't remove the owner of the project if (projectAccount.getAccountRole() == Role.Admin) { - throw new InvalidParameterValueException("Unable to delete account " + accountName + " from the project id=" + projectId + " as the account is the owner of the project"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to delete account " + accountName + " from the project with specified id as the account is the owner of the project"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } return deleteAccountFromProject(projectId, account.getId()); @@ -935,7 +951,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ ProjectVO project = getProject(projectId); if (project == null) { - throw new InvalidParameterValueException("Unable to find the project id=" + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } //verify permissions @@ -975,7 +993,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ ProjectVO project= getProject(projectId); //verify input parameters if (project == null) { - throw new InvalidParameterValueException("Unable to find project by id " + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); @@ -984,7 +1004,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ s_logger.debug("Successfully suspended project id=" + projectId); return _projectDao.findById(projectId); } else { - throw new CloudRuntimeException("Failed to suspend project id=" + projectId); + CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } } diff --git a/server/src/com/cloud/projects/ProjectVO.java b/server/src/com/cloud/projects/ProjectVO.java index 631d4c923e4..ad61dac1bec 100644 --- a/server/src/com/cloud/projects/ProjectVO.java +++ b/server/src/com/cloud/projects/ProjectVO.java @@ -92,7 +92,6 @@ public class ProjectVO implements Project, Identity { return domainId; } - @Override public long getId() { return id; diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index a147ddc2f94..dcd9ce7367f 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -144,6 +144,7 @@ import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHCmdHelper; import com.cloud.utils.ssh.sshException; +import com.cloud.utils.AnnotationHelper; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineManager; @@ -342,22 +343,29 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma // Check if the zone exists in the system DataCenterVO zone = _dcDao.findById(dcId); if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " + dcId); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } Account account = UserContext.current().getCaller(); if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } - // Check if the pod exists in the system - if (_podDao.findById(podId) == null) { - throw new InvalidParameterValueException("Can't find pod by id " + podId); - } - // check if pod belongs to the zone HostPodVO pod = _podDao.findById(podId); + if (pod == null) { + throw new InvalidParameterValueException("Can't find pod with specified podId " + podId); + } + + // check if pod belongs to the zone if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); + InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId); + ex.addProxyObject(pod, podId, "podId"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } // Verify cluster information and create a new cluster if needed @@ -413,7 +421,11 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma cluster = _clusterDao.persist(cluster); } catch (Exception e) { // no longer tolerate exception during the cluster creation phase - throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); + CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod and data center with specified ids", e); + // Get the pod VO object's table name. + ex.addProxyObject(pod, podId, "podId"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } clusterId = cluster.getId(); result.add(cluster); @@ -564,6 +576,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma if (!success) { _clusterDetailsDao.deleteDetails(clusterId); _clusterDao.remove(clusterId); + _clusterVSMDao.removeByClusterId(clusterId); } } } @@ -601,12 +614,16 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma if (clusterId != null) { ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null) { - throw new InvalidParameterValueException("can not fine cluster for clusterId " + clusterId); + InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster for specified clusterId"); + ex.addProxyObject(cluster, clusterId, "clusterId"); + throw ex; } else { if (cluster.getGuid() == null) { List hosts = listAllHostsInCluster(clusterId); if (!hosts.isEmpty()) { - throw new CloudRuntimeException("Guid is not updated for cluster " + clusterId + " need to wait hosts in this cluster up"); + CloudRuntimeException ex = new CloudRuntimeException("Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up"); + ex.addProxyObject(cluster, clusterId, "clusterId"); + throw ex; } } } @@ -644,17 +661,23 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma Account account = UserContext.current().getCaller(); if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + dcId); + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } - + // Check if the pod exists in the system if (podId != null) { HostPodVO pod = _podDao.findById(podId); if (pod == null) { throw new InvalidParameterValueException("Can't find pod by id " + podId); } + // check if pod belongs to the zone if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - throw new InvalidParameterValueException("Pod " + podId + " doesn't belong to the zone " + dcId); + InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified podId" + podId + " doesn't belong to the zone with specified zoneId" + dcId); + ex.addProxyObject(pod, podId, "podId"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } } @@ -708,7 +731,10 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma } catch (Exception e) { cluster = _clusterDao.findBy(clusterName, podId); if (cluster == null) { - throw new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod " + podId + " and data center " + dcId, e); + CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod with specified podId and data center with specified dcID", e); + ex.addProxyObject(pod, podId, "podId"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; } } clusterId = cluster.getId(); @@ -809,7 +835,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma // Verify that host exists HostVO host = _hostDao.findById(hostId); if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); } _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId()); diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 797d9f03706..aa4b7223c81 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -206,12 +206,12 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager { public long findCorrectResourceLimitForAccount(Account account, ResourceType type) { long max = Resource.RESOURCE_UNLIMITED; // if resource limit is not found, then we treat it as unlimited - - //no limits for Admin accounts - if (_accountMgr.isAdmin(account.getType())) { + + // No limits for Root Admin accounts + if (_accountMgr.isRootAdmin(account.getType())) { return max; } - + ResourceLimitVO limit = _resourceLimitDao.findByOwnerIdAndType(account.getId(), ResourceOwnerType.Account, type); // Check if limit is configured for account @@ -273,8 +273,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager { long numResources = ((count.length == 0) ? 1 : count[0]); Project project = null; - // Don't place any limits on system or admin accounts - if (_accountMgr.isAdmin(account.getType())) { + // Don't place any limits on system or root admin accounts + if (_accountMgr.isRootAdmin(account.getType())) { return; } @@ -337,7 +337,7 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager { List limits = new ArrayList(); boolean isAccount = true; - if (!_accountMgr.isAdmin(caller.getType())) { + if (!_accountMgr.isRootAdmin(caller.getType())) { accountId = caller.getId(); domainId = null; } else { @@ -506,10 +506,17 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager { if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new InvalidParameterValueException("Can't update system account"); } - - //only Unlimited value is accepted if account is Admin - if (_accountMgr.isAdmin(account.getType()) && max.shortValue() != ResourceLimit.RESOURCE_UNLIMITED) { - throw new InvalidParameterValueException("Only " + ResourceLimit.RESOURCE_UNLIMITED + " limit is supported for Admin accounts"); + + //only Unlimited value is accepted if account is Root Admin + if (_accountMgr.isRootAdmin(account.getType()) && max.shortValue() != ResourceLimit.RESOURCE_UNLIMITED) { + throw new InvalidParameterValueException("Only " + ResourceLimit.RESOURCE_UNLIMITED + " limit is supported for Root Admin accounts"); + } + + if ((caller.getAccountId() == accountId.longValue()) && + (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || + caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + // If the admin is trying to update his own account, disallow. + throw new PermissionDeniedException("Unable to update resource limit for his own account " + accountId + ", permission denied"); } if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 81ca96e931c..1560fd1e26e 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -61,6 +61,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InternalErrorException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Network.State; @@ -94,7 +95,6 @@ import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -421,10 +421,11 @@ public class ConfigurationServerImpl implements ConfigurationServer { protected void updateCloudIdentifier() { // Creates and saves a UUID as the cloud identifier - String currentCloudIdentifier = _configDao.getValue("cloud.identifier"); + ConfigurationVO cloudIdentifier = _configDao.findByName("cloud.identifier"); + String currentCloudIdentifier = cloudIdentifier.getValue(); if (currentCloudIdentifier == null || currentCloudIdentifier.isEmpty()) { String uuid = UUID.randomUUID().toString(); - _configDao.update(Config.CloudIdentifier.key(), Config.CloudIdentifier.getCategory(), uuid); + _configDao.update(Config.CloudIdentifier.key(), cloudIdentifier.getCategory(), uuid); } } @@ -874,16 +875,22 @@ public class ConfigurationServerImpl implements ConfigurationServer { @DB protected void createDefaultNetworkOfferings() { - NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, true); + NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, + TrafficType.Public, true); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); - NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, TrafficType.Management, false); + NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, + TrafficType.Management, false); managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering); - NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, TrafficType.Control, false); + NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, + TrafficType.Control, false); controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering); - NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, true); + NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, + TrafficType.Storage, true); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); + NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, GuestType.Isolated); + privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); - // populate providers + //populate providers Map defaultSharedNetworkOfferingProviders = new HashMap(); defaultSharedNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter); defaultSharedNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter); @@ -968,7 +975,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } @@ -1007,6 +1015,36 @@ public class ConfigurationServerImpl implements ConfigurationServer { s_logger.trace("Added service for the network offering: " + offService); } + // Offering #6 + NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated Vpc networks with Source Nat service enabled", + TrafficType.Guest, + false, false, null, null, true, Availability.Required, + null, Network.GuestType.Isolated, false, false); + + defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); + defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); + + Map defaultVpcNetworkOfferingProviders = new HashMap(); + defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Firewall, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); + + for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + txn.commit(); } @@ -1061,8 +1099,9 @@ public class ConfigurationServerImpl implements ConfigurationServer { } if (broadcastDomainType != null) { - NetworkVO network = new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain, Network.GuestType.Shared, zoneId, null, - null, specifyIpRanges); + NetworkVO network = new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, + domainId, accountId, related, null, null, networkDomain, Network.GuestType.Shared, zoneId, null, + null, specifyIpRanges, null); network.setGuruName(guruNames.get(network.getTrafficType())); network.setDns1(zone.getDns1()); network.setDns2(zone.getDns2()); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index b865f9c184e..28323b2cbf1 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -244,6 +244,8 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.utils.exception.CSExceptionErrorCode; +import com.cloud.utils.AnnotationHelper; import edu.emory.mathcs.backport.java.util.Arrays; import edu.emory.mathcs.backport.java.util.Collections; @@ -676,7 +678,9 @@ public class ManagementServerImpl implements ManagementServer { } else if (vmId != null) { UserVmVO vmInstance = _userVmDao.findById(vmId); if ((vmInstance == null) || (vmInstance.getRemoved() != null)) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id"); + ex.addProxyObject(vmInstance, vmId, "vmId"); + throw ex; } _accountMgr.checkAccess(caller, null, true, vmInstance); @@ -746,7 +750,9 @@ public class ManagementServerImpl implements ManagementServer { } else if (vmId != null) { UserVmVO vmInstance = _userVmDao.findById(vmId); if ((vmInstance == null) || (vmInstance.getRemoved() != null)) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with id " + vmId); + ex.addProxyObject(vmInstance, vmId, "vmId"); + throw ex; } _accountMgr.checkAccess(caller, null, false, vmInstance); @@ -889,14 +895,18 @@ public class ManagementServerImpl implements ManagementServer { VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to find the VM by id=" + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the VM with specified id"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } // business logic if (vm.getState() != State.Running) { if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is not Running, unable to migrate the vm " + vm); + s_logger.debug("VM is not Running, unable to migrate the vm" + vm); } - throw new InvalidParameterValueException("VM is not Running, unable to migrate the vm " + vm); + InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM) @@ -914,12 +924,16 @@ public class ManagementServerImpl implements ManagementServer { throw new InvalidParameterValueException("Unsupported operation, VM uses Local storage, cannot migrate"); } long srcHostId = vm.getHostId(); + // why is this not HostVO? Host srcHost = _hostDao.findById(srcHostId); if (srcHost == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find the host with id: " + srcHostId + " of this VM:" + vm); } - throw new InvalidParameterValueException("Unable to find the host with id: " + srcHostId + " of this VM:" + vm); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find the host (with specified id) of VM with specified id"); + ex.addProxyObject(srcHost, srcHostId, "hostId"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } Long cluster = srcHost.getClusterId(); Type hostType = srcHost.getType(); @@ -1098,7 +1112,11 @@ public class ManagementServerImpl implements ManagementServer { } Account account = _accountDao.findActiveAccount(accountName, domainId); if (account == null) { - throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain"); + // Since we don't have a DomainVO object here, we directly set tablename to "domain". + String tablename = "domain"; + ex.addProxyObject(tablename, domainId, "domainId"); + throw ex; } else { accountId = account.getId(); } @@ -1116,7 +1134,9 @@ public class ManagementServerImpl implements ManagementServer { if (projectId != null) { Project project = _projectMgr.getProject(projectId); if (project == null) { - throw new InvalidParameterValueException("Unable to find project by id " + projectId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project by id " + projectId); + ex.addProxyObject(project, projectId, "projectId"); + throw ex; } accountId = project.getProjectAccountId(); } @@ -1283,11 +1303,15 @@ public class ManagementServerImpl implements ManagementServer { }// If ISO requested then it should be ISO. if (isIso && template.getFormat() != ImageFormat.ISO) { s_logger.error("Template Id " + templateId + " is not an ISO"); - throw new InvalidParameterValueException("Template Id " + templateId + " is not an ISO"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO"); + ex.addProxyObject(template, templateId, "templateId"); + throw ex; }// If ISO not requested then it shouldn't be an ISO. if (!isIso && template.getFormat() == ImageFormat.ISO) { s_logger.error("Incorrect format of the template id " + templateId); - throw new InvalidParameterValueException("Incorrect format " + template.getFormat() + " of the template id " + templateId); + InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() + " of the specified template id"); + ex.addProxyObject(template, templateId, "templateId"); + throw ex; } } @@ -1365,12 +1389,16 @@ public class ManagementServerImpl implements ManagementServer { // verify that template exists VMTemplateVO template = _templateDao.findById(id); if (template == null || template.getRemoved() != null) { - throw new InvalidParameterValueException("unable to find template/iso with id " + id); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id"); + ex.addProxyObject(template, id, "templateId"); + throw ex; } // Don't allow to modify system template if (id == Long.valueOf(1)) { - throw new InvalidParameterValueException("Unable to update template/iso with id " + id); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); + ex.addProxyObject(template, id, "templateId"); + throw ex; } // do a permission check @@ -1565,6 +1593,7 @@ public class ManagementServerImpl implements ManagementServer { Long hostId = cmd.getHostId(); String keyword = cmd.getKeyword(); Long networkId = cmd.getNetworkId(); + Long vpcId = cmd.getVpcId(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1585,6 +1614,7 @@ public class ManagementServerImpl implements ManagementServer { sb.and("dataCenterId", sb.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); if (networkId != null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); @@ -1611,25 +1641,35 @@ public class ManagementServerImpl implements ManagementServer { if (name != null) { sc.setParameters("name", "%" + name + "%"); } + if (id != null) { sc.setParameters("id", id); } + if (state != null) { sc.setParameters("state", state); } + if (zone != null) { sc.setParameters("dataCenterId", zone); } + if (pod != null) { sc.setParameters("podId", pod); } + if (hostId != null) { sc.setParameters("hostId", hostId); } + if (networkId != null) { sc.setJoinParameters("nicSearch", "networkId", networkId); } + if (vpcId != null) { + sc.setParameters("vpcId", vpcId); + } + return _routerDao.search(sc, searchFilter); } @@ -1646,6 +1686,7 @@ public class ManagementServerImpl implements ManagementServer { Long ipId = cmd.getId(); Boolean sourceNat = cmd.getIsSourceNat(); Boolean staticNat = cmd.getIsStaticNat(); + Long vpcId = cmd.getVpcId(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1673,6 +1714,7 @@ public class ManagementServerImpl implements ManagementServer { sb.and("associatedNetworkIdEq", sb.entity().getAssociatedWithNetworkId(), SearchCriteria.Op.EQ); sb.and("isSourceNat", sb.entity().isSourceNat(), SearchCriteria.Op.EQ); sb.and("isStaticNat", sb.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); if (forLoadBalancing != null && (Boolean) forLoadBalancing) { SearchBuilder lbSearch = _loadbalancerDao.createSearchBuilder(); @@ -1702,7 +1744,7 @@ public class ManagementServerImpl implements ManagementServer { } // don't show SSVM/CPVM ips - if (vlanType == VlanType.VirtualNetwork && (allocatedOnly)) { + if (vlanType == VlanType.VirtualNetwork && (allocatedOnly) && vpcId == null) { sb.and("associatedNetworkId", sb.entity().getAssociatedWithNetworkId(), SearchCriteria.Op.NNULL); } @@ -1715,6 +1757,10 @@ public class ManagementServerImpl implements ManagementServer { sc.setParameters("dataCenterId", zone); } + if (vpcId != null) { + sc.setParameters("vpcId", vpcId); + } + if (ipId != null) { sc.setParameters("id", ipId); } @@ -1882,7 +1928,9 @@ public class ManagementServerImpl implements ManagementServer { // check if domain exists in the system DomainVO domain = _domainDao.findById(domainId); if (domain == null) { - throw new InvalidParameterValueException("Unable to find domain " + domainId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find domain with specified domain id"); + ex.addProxyObject(domain, domainId, "domainId"); + throw ex; } else if (domain.getParent() == null && domainName != null) { // check if domain is ROOT domain - and deny to edit it with the new name throw new InvalidParameterValueException("ROOT domain can not be edited with a new name"); @@ -1902,7 +1950,7 @@ public class ManagementServerImpl implements ManagementServer { if (!domains.isEmpty() && !sameDomain) { InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system"); - ex.addProxyObject("domain", domainId, "domainId"); + ex.addProxyObject(domain, domainId, "domainId"); throw ex; } } @@ -2607,7 +2655,9 @@ public class ManagementServerImpl implements ManagementServer { public VirtualMachine.Type findSystemVMTypeById(long instanceId) { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(instanceId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { - throw new InvalidParameterValueException("Unable to find a system vm: " + instanceId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm of specified instanceId"); + ex.addProxyObject(systemVm, instanceId, "instanceId"); + throw ex; } return systemVm.getType(); } @@ -2617,7 +2667,9 @@ public class ManagementServerImpl implements ManagementServer { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { - throw new InvalidParameterValueException("unable to find a system vm with id " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId"); + ex.addProxyObject(systemVm, vmId, "vmId"); + throw ex; } if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) { @@ -2625,7 +2677,9 @@ public class ManagementServerImpl implements ManagementServer { } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) { return startSecondaryStorageVm(vmId); } else { - throw new InvalidParameterValueException("Unable to find a system vm: " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a system vm with specified vmId"); + ex.addProxyObject(systemVm, vmId, "vmId"); + throw ex; } } @@ -2636,7 +2690,9 @@ public class ManagementServerImpl implements ManagementServer { // verify parameters VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { - throw new InvalidParameterValueException("unable to find a system vm with id " + id); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId"); + ex.addProxyObject(systemVm, id, "vmId"); + throw ex; } try { @@ -2656,7 +2712,9 @@ public class ManagementServerImpl implements ManagementServer { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { - throw new InvalidParameterValueException("unable to find a system vm with id " + cmd.getId()); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId"); + ex.addProxyObject(systemVm, cmd.getId(), "vmId"); + throw ex; } if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) { @@ -2671,7 +2729,9 @@ public class ManagementServerImpl implements ManagementServer { VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(cmd.getId(), VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { - throw new InvalidParameterValueException("unable to find a system vm with id " + cmd.getId()); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a system vm with specified vmId"); + ex.addProxyObject(systemVm, cmd.getId(), "vmId"); + throw ex; } if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)) { @@ -2707,7 +2767,9 @@ public class ManagementServerImpl implements ManagementServer { // verify that user exists User user = _accountMgr.getUserIncludingRemoved(userId); if ((user == null) || (user.getRemoved() != null)) { - throw new InvalidParameterValueException("Unable to find active user by id " + userId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find active user of specified id"); + ex.addProxyObject(user, userId, "userId"); + throw ex; } // check permissions @@ -2791,7 +2853,9 @@ public class ManagementServerImpl implements ManagementServer { VolumeVO volume = _volumeDao.findById(volumeId); if (volume == null) { - throw new InvalidParameterValueException("Unable to find volume with id " + volumeId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId"); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; } // perform permission check @@ -2806,18 +2870,21 @@ public class ManagementServerImpl implements ManagementServer { // Extract activity only for detached volumes or for volumes whose instance is stopped if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) { s_logger.debug("Invalid state of the volume with ID: " + volumeId + ". It should be either detached or the VM should be in stopped state."); - throw new PermissionDeniedException("Invalid state of the volume with ID: " + volumeId + ". It should be either detached or the VM should be in stopped state."); + PermissionDeniedException ex = new PermissionDeniedException("Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state."); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; } if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont have any template dependence. VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); - if (template != null) { // For ISO based volumes template = null and we allow extraction of all ISO based -// volumes + if (template != null) { // For ISO based volumes template = null and we allow extraction of all ISO based volumes boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) { // Global // admins are always allowed to extract - throw new PermissionDeniedException("The volume:" + volumeId + " is not allowed to be extracted"); + PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted"); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; } } } @@ -2952,7 +3019,9 @@ public class ManagementServerImpl implements ManagementServer { // Verify input parameters InstanceGroupVO group = _vmGroupDao.findById(groupId.longValue()); if (group == null) { - throw new InvalidParameterValueException("unable to find a vm group with id " + groupId); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a vm group with specified groupId"); + ex.addProxyObject(group, groupId, "groupId"); + throw ex; } _accountMgr.checkAccess(caller, null, true, group); @@ -3174,7 +3243,9 @@ public class ManagementServerImpl implements ManagementServer { SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName()); if (s == null) { - throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName() + " in domain id=" + owner.getDomainId()); + InvalidParameterValueException ex = new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName() + " in specified domain id"); + ex.addProxyObject(owner, owner.getDomainId(), "domainId"); + throw ex; } return _sshKeyPairDao.deleteByName(caller.getAccountId(), caller.getDomainId(), cmd.getName()); @@ -3255,7 +3326,9 @@ public class ManagementServerImpl implements ManagementServer { UserVmVO vm = _userVmDao.findById(cmd.getId()); if (vm == null) { - throw new InvalidParameterValueException("No VM with id '" + cmd.getId() + "' found."); + InvalidParameterValueException ex = new InvalidParameterValueException("No VM with specified id found."); + ex.addProxyObject(vm, cmd.getId(), "vmId"); + throw ex; } // make permission check @@ -3264,7 +3337,9 @@ public class ManagementServerImpl implements ManagementServer { _userVmDao.loadDetails(vm); String password = vm.getDetail("Encrypted.Password"); if (password == null || password.equals("")) { - throw new InvalidParameterValueException("No password for VM with id '" + cmd.getId() + "' found."); + InvalidParameterValueException ex = new InvalidParameterValueException("No password for VM with specified id found."); + ex.addProxyObject(vm, cmd.getId(), "vmId"); + throw ex; } return password; @@ -3368,7 +3443,9 @@ public class ManagementServerImpl implements ManagementServer { HypervisorCapabilitiesVO hpvCapabilities = _hypervisorCapabilitiesDao.findById(id, true); if (hpvCapabilities == null) { - throw new InvalidParameterValueException("unable to find the hypervisor capabilities " + id); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find the hypervisor capabilities for specified id"); + ex.addProxyObject(hpvCapabilities, id, "Id"); + throw ex; } boolean updateNeeded = (maxGuestsLimit != null || securityGroupEnabled != null); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 29a978244ee..e93be77d8ef 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -42,6 +42,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.capacity.dao.CapacityDao; import com.cloud.cluster.ClusterManager; @@ -69,6 +71,7 @@ import com.cloud.info.RunningHostInfoAgregator; import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; @@ -1087,7 +1090,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); } - buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); if (nic.isDefaultNic()) { buf.append(" gateway=").append(nic.getGateway()); } @@ -1444,4 +1446,25 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } return null; } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + + } } diff --git a/server/src/com/cloud/tags/ResourceTagVO.java b/server/src/com/cloud/tags/ResourceTagVO.java new file mode 100644 index 00000000000..7aef1e4eaf2 --- /dev/null +++ b/server/src/com/cloud/tags/ResourceTagVO.java @@ -0,0 +1,148 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.tags; + +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 com.cloud.api.Identity; +import com.cloud.server.ResourceTag; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="resource_tags") +public class ResourceTagVO implements Identity, ResourceTag{ + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="key") + private String key; + + @Column(name="value") + String value; + + @Column(name="domain_id") + long domainId; + + @Column(name="account_id") + long accountId; + + @Column(name="resource_id") + long resourceId; + + @Column(name="resource_type") + @Enumerated(value=EnumType.STRING) + private TaggedResourceType resourceType; + + @Column(name="customer") + String customer; + + + protected ResourceTagVO(){ + this.uuid = UUID.randomUUID().toString(); + } + + /** + * @param key + * @param value + * @param accountId + * @param domainId + * @param resourceId + * @param resourceType + * @param customer TODO + */ + public ResourceTagVO(String key, String value, long accountId, long domainId, long resourceId, + TaggedResourceType resourceType, String customer) { + super(); + this.key = key; + this.value = value; + this.domainId = domainId; + this.accountId = accountId; + this.resourceId = resourceId; + this.resourceType = resourceType; + this.uuid = UUID.randomUUID().toString(); + this.customer = customer; + } + + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("Tag["); + buf.append(id).append("|key=").append(key).append("|value=").append(domainId).append("|value="). + append("|resourceType=").append(resourceType).append("|resourceId=").append(resourceId) + .append("|accountId=").append(accountId).append("]"); + return buf.toString(); + } + + @Override + public long getId() { + return id; + } + + @Override + public String getKey() { + return key; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public TaggedResourceType getResourceType() { + return resourceType; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getCustomer() { + return customer; + } +} diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java new file mode 100644 index 00000000000..3d3cf27d405 --- /dev/null +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -0,0 +1,410 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.tags; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.api.commands.ListTagsCmd; +import com.cloud.domain.Domain; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.LoadBalancerDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.RemoteAccessVpnDao; +import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.server.TaggedResourceService; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.tags.dao.ResourceTagDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.DomainManager; +import com.cloud.user.UserContext; +import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.DbUtil; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.uuididentity.dao.IdentityDao; +import com.cloud.vm.dao.UserVmDao; + +/** + * @author Alena Prokharchyk + */ +@Local(value = { TaggedResourceService.class}) +public class TaggedResourceManagerImpl implements TaggedResourceService, Manager{ + public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class); + private String _name; + + private static Map> _daoMap= + new HashMap>(); + + @Inject + AccountManager _accountMgr; + @Inject + ResourceTagDao _resourceTagDao; + @Inject + IdentityDao _identityDao; + @Inject + DomainManager _domainMgr; + @Inject + UserVmDao _userVmDao; + @Inject + VolumeDao _volumeDao; + @Inject + VMTemplateDao _templateDao; + @Inject + SnapshotDao _snapshotDao; + @Inject + NetworkDao _networkDao; + @Inject + LoadBalancerDao _lbDao; + @Inject + PortForwardingRulesDao _pfDao; + @Inject + FirewallRulesDao _firewallDao; + @Inject + SecurityGroupDao _securityGroupDao; + @Inject + RemoteAccessVpnDao _vpnDao; + @Inject + IPAddressDao _publicIpDao; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + _daoMap.put(TaggedResourceType.UserVm, _userVmDao); + _daoMap.put(TaggedResourceType.Volume, _volumeDao); + _daoMap.put(TaggedResourceType.Template, _templateDao); + _daoMap.put(TaggedResourceType.ISO, _templateDao); + _daoMap.put(TaggedResourceType.Snapshot, _snapshotDao); + _daoMap.put(TaggedResourceType.Network, _networkDao); + _daoMap.put(TaggedResourceType.LoadBalancer, _lbDao); + _daoMap.put(TaggedResourceType.PortForwardingRule, _pfDao); + _daoMap.put(TaggedResourceType.FirewallRule, _firewallDao); + _daoMap.put(TaggedResourceType.SecurityGroup, _securityGroupDao); + _daoMap.put(TaggedResourceType.PublicIpAddress, _publicIpDao); + + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + + private Long getResourceId(String resourceId, TaggedResourceType resourceType) { + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + + Long identityId = null; + + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + identityId = _identityDao.getIdentityId(tableName, resourceId); + if (identityId != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); + } + + if (identityId == null) { + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + } + return identityId; + } + + protected String getTableName(TaggedResourceType resourceType) { + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + return DbUtil.getTableName(claz); + } + + private Pair getAccountDomain(long resourceId, TaggedResourceType resourceType) { + + Pair pair = null; + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + pair = _identityDao.getAccountDomainInfo(tableName, resourceId); + if (pair.first() != null || pair.second() != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); + } + + Long accountId = pair.first(); + Long domainId = pair.second(); + + if (accountId == null) { + accountId = Account.ACCOUNT_ID_SYSTEM; + } + + if (domainId == null) { + domainId = Domain.ROOT_DOMAIN; + } + + return new Pair(accountId, domainId); + } + + @Override + public TaggedResourceType getResourceType(String resourceTypeStr) { + + for (TaggedResourceType type : ResourceTag.TaggedResourceType.values()) { + if (type.toString().equalsIgnoreCase(resourceTypeStr)) { + return type; + } + } + throw new InvalidParameterValueException("Invalid resource type " + resourceTypeStr); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = "creating resource tags") + public List createTags(List resourceIds, TaggedResourceType resourceType, + Map tags, String customer) { + Account caller = UserContext.current().getCaller(); + + List resourceTags = new ArrayList(tags.size()); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + + for (String tag : tags.keySet()) { + for (String resourceId : resourceIds) { + Long id = getResourceId(resourceId, resourceType); + + //check if object exists + if (_daoMap.get(resourceType).findById(id) == null) { + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); + } + + Pair accountDomainPair = getAccountDomain(id, resourceType); + Long domainId = accountDomainPair.second(); + Long accountId = accountDomainPair.first(); + if (accountId != null) { + _accountMgr.checkAccess(caller, null, false, _accountMgr.getAccount(accountId)); + } else if (domainId != null && caller.getType() != Account.ACCOUNT_TYPE_NORMAL) { + //check permissions; + _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId)); + } else { + throw new PermissionDeniedException("Account " + caller + " doesn't have permissions to create tags" + + " for resource " + tag); + } + + ResourceTagVO resourceTag = new ResourceTagVO(tag, tags.get(tag), accountDomainPair.first(), + accountDomainPair.second(), + id, resourceType, customer); + resourceTag = _resourceTagDao.persist(resourceTag); + resourceTags.add(resourceTag); + + } + } + + txn.commit(); + + return resourceTags; + } + + @Override + public String getUuid(String resourceId, TaggedResourceType resourceType) { + GenericDao dao = _daoMap.get(resourceType); + Class claz = DbUtil.getEntityBeanType(dao); + + String identiyUUId = null; + + while (claz != null && claz != Object.class) { + try { + String tableName = DbUtil.getTableName(claz); + if (tableName == null) { + throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); + } + identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); + if (identiyUUId != null) { + break; + } + } catch (Exception ex) { + //do nothing here, it might mean uuid field is missing and we have to search further + } + claz = claz.getSuperclass(); + } + + if (identiyUUId == null) { + return resourceId; + } + + return identiyUUId; + } + + @Override + public List listTags(ListTagsCmd cmd) { + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + String key = cmd.getKey(); + String value = cmd.getValue(); + String resourceId = cmd.getResourceId(); + String resourceType = cmd.getResourceType(); + String customerName = cmd.getCustomer(); + boolean listAll = cmd.listAll(); + + Ternary domainIdRecursiveListProject = + new Ternary(cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), + cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false); + Long domainId = domainIdRecursiveListProject.first(); + Boolean isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + + SearchBuilder sb = _resourceTagDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ); + sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ); + sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ); + sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ); + + // now set the SC criteria... + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (key != null) { + sc.setParameters("key", key); + } + + if (value != null) { + sc.setParameters("value", value); + } + + if (resourceId != null) { + sc.setParameters("resourceId", resourceId); + } + + if (resourceType != null) { + sc.setParameters("resourceType", resourceType); + } + + if (customerName != null) { + sc.setParameters("customer", customerName); + } + + return _resourceTagDao.search(sc, searchFilter); + } + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_TAGS_DELETE, eventDescription = "deleting resource tags") + public boolean deleteTags(List resourceIds, TaggedResourceType resourceType, Map tags) { + Account caller = UserContext.current().getCaller(); + + SearchBuilder sb = _resourceTagDao.createSearchBuilder(); + sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN); + sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ); + SearchCriteria sc = sb.create(); + sc.setParameters("resourceId", resourceIds.toArray()); + sc.setParameters("resourceType", resourceType); + + List resourceTags = _resourceTagDao.search(sc, null);; + List tagsToRemove = new ArrayList(); + + // Finalize which tags should be removed + for (ResourceTag resourceTag : resourceTags) { + //1) validate the permissions + Account owner = _accountMgr.getAccount(resourceTag.getAccountId()); + _accountMgr.checkAccess(caller, null, false, owner); + //2) Only remove tag if it matches key value pairs + if (tags != null && !tags.isEmpty()) { + for (String key : tags.keySet()) { + boolean canBeRemoved = false; + if (resourceTag.getKey().equalsIgnoreCase(key)) { + String value = tags.get(key); + if (value != null) { + if (resourceTag.getValue().equalsIgnoreCase(value)) { + canBeRemoved = true; + } + } else { + canBeRemoved = true; + } + if (canBeRemoved) { + tagsToRemove.add(resourceTag); + break; + } + } + } + } else { + tagsToRemove.add(resourceTag); + } + } + + //Remove the tags + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (ResourceTag tagToRemove : tagsToRemove) { + _resourceTagDao.remove(tagToRemove.getId()); + s_logger.debug("Removed the tag " + tagToRemove); + } + txn.commit(); + + return true; + } +} diff --git a/server/src/com/cloud/tags/dao/ResourceTagDao.java b/server/src/com/cloud/tags/dao/ResourceTagDao.java new file mode 100644 index 00000000000..a2d38514188 --- /dev/null +++ b/server/src/com/cloud/tags/dao/ResourceTagDao.java @@ -0,0 +1,23 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.tags.dao; + +import com.cloud.tags.ResourceTagVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface ResourceTagDao extends GenericDao{ + +} diff --git a/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java new file mode 100644 index 00000000000..0285dad8cda --- /dev/null +++ b/server/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java @@ -0,0 +1,29 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.tags.dao; + +import javax.ejb.Local; + +import com.cloud.tags.ResourceTagVO; +import com.cloud.utils.db.GenericDaoBase; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = { ResourceTagDao.class }) +public class ResourceTagsDaoImpl extends GenericDaoBase implements ResourceTagDao{ + + protected ResourceTagsDaoImpl() { + } +} diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java index 2669e66d774..0daa9167493 100644 --- a/server/src/com/cloud/test/PodZoneConfig.java +++ b/server/src/com/cloud/test/PodZoneConfig.java @@ -381,7 +381,8 @@ public class PodZoneConfig { String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage); String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest); - String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` (physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)"; + String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` " + + "(physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)"; try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade302to303.java b/server/src/com/cloud/upgrade/dao/Upgrade302to303.java index ce7c46a5953..51effefef00 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade302to303.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade302to303.java @@ -16,6 +16,7 @@ package com.cloud.upgrade.dao; * @author Alena Prokharchyk */ import java.io.File; +import java.io.UnsupportedEncodingException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -25,6 +26,7 @@ import java.util.UUID; import org.apache.log4j.Logger; // import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @@ -59,6 +61,7 @@ public class Upgrade302to303 implements DbUpgrade { @Override public void performDataMigration(Connection conn) { setupExternalNetworkDevices(conn); + encryptConfig(conn); } private void setupExternalNetworkDevices(Connection conn) { @@ -249,6 +252,45 @@ public class Upgrade302to303 implements DbUpgrade { } } + private void encryptConfig(Connection conn){ + //Encrypt config params and change category to Hidden + s_logger.debug("Encrypting Config values"); + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + pstmt = conn.prepareStatement("select name, value from `cloud`.`configuration` where name in ('router.ram.size', 'secondary.storage.vm', 'security.hash.key') and category <> 'Hidden'"); + rs = pstmt.executeQuery(); + while (rs.next()) { + String name = rs.getString(1); + String value = rs.getString(2); + if (value == null) { + continue; + } + String encryptedValue = DBEncryptionUtil.encrypt(value); + pstmt = conn.prepareStatement("update `cloud`.`configuration` set value=?, category = 'Hidden' where name=?"); + pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); + pstmt.setString(2, name); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable encrypt configuration values ", e); + } catch (UnsupportedEncodingException e) { + throw new CloudRuntimeException("Unable encrypt configuration values ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + s_logger.debug("Done encrypting Config values"); + } + @Override public File[] getCleanupScripts() { return null; diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index a7f5a68c83f..4c18f63e927 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -71,7 +71,7 @@ public interface AccountManager extends AccountService { * made, and the signature itself in the single sign-on case * @return a user object, null if the user failed to authenticate */ - UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters); + UserAccount authenticateUser(String username, String password, Long domainId, String loginIpAddress, Map requestParameters); /** * Locate a user by their apiKey diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 35fbfe01077..9e091164797 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -77,6 +77,8 @@ import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -199,6 +201,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private ProjectAccountDao _projectAccountDao; @Inject private IPAddressDao _ipAddressDao; + @Inject + private VpcManager _vpcMgr; private Adapters _userAuthenticators; @@ -229,7 +233,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Map configs = configDao.getConfiguration(params); String value = configs.get(Config.AccountCleanupInterval.key()); - _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 hour. + _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day. _userAuthenticators = locator.getAdapters(UserAuthenticator.class); if (_userAuthenticators == null || !_userAuthenticators.isSet()) { @@ -574,19 +578,35 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } - // release ip addresses belonging to the account - List ipsToRelease = _ipAddressDao.listByAccount(accountId); - for (IpAddress ip : ipsToRelease) { - s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup"); - if (!_networkMgr.releasePublicIpAddress(ip.getId(), callerUserId, caller)) { - s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup"); + //Delete all VPCs + boolean vpcsDeleted = true; + s_logger.debug("Deleting vpcs for account " + account.getId()); + List vpcs = _vpcMgr.getVpcsForAccount(account.getId()); + for (Vpc vpc : vpcs) { + + if (!_vpcMgr.destroyVpc(vpc)) { + s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup."); accountCleanupNeeded = true; + vpcsDeleted = false; + } else { + s_logger.debug("VPC " + vpc.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup."); + } + } + + if (vpcsDeleted) { + // release ip addresses belonging to the account + List ipsToRelease = _ipAddressDao.listByAccount(accountId); + for (IpAddress ip : ipsToRelease) { + s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup"); + if (!_networkMgr.disassociatePublicIpAddress(ip.getId(), callerUserId, caller)) { + s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup"); + accountCleanupNeeded = true; + } } } // delete account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned - // up - // successfully + // up successfully if (networksDeleted) { if (!_configMgr.deleteAccountSpecificVirtualRanges(accountId)) { accountCleanupNeeded = true; @@ -1618,7 +1638,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters) { + public UserAccount authenticateUser(String username, String password, Long domainId, String loginIpAddress, Map requestParameters) { UserAccount user = null; if (password != null) { user = getUserAccount(username, password, domainId, requestParameters); @@ -1720,7 +1740,13 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (s_logger.isDebugEnabled()) { s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); } - EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in"); + if (NetUtils.isValidIp(loginIpAddress)) { + EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, + "user has logged in from IP Address " + loginIpAddress); + } else { + EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, + "user has logged in. The IP Address cannot be determined"); + } return user; } else { if (s_logger.isDebugEnabled()) { diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index 3223d8c1c28..b0398bd8bc7 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -228,22 +228,24 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager long ownerId = domain.getAccountId(); if ((cleanup != null) && cleanup.booleanValue()) { if (!cleanupDomain(domain.getId(), ownerId)) { - s_logger.error("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domain.getId() + ")."); - return false; + CloudRuntimeException e = new CloudRuntimeException("Failed to clean up domain resources and sub domains, delete failed on domain " + domain.getName() + " (id: " + domain.getId() + ")."); + e.addProxyObject(domain, domain.getId(), "domainId"); + throw e; } } else { List accountsForCleanup = _accountDao.findCleanupsForRemovedAccounts(domain.getId()); if (accountsForCleanup.isEmpty()) { if (!_domainDao.remove(domain.getId())) { - s_logger.error("Delete failed on domain " + domain.getName() + " (id: " + domain.getId() - + "); please make sure all users and sub domains have been removed from the domain before deleting"); rollBackState = true; - return false; + CloudRuntimeException e = new CloudRuntimeException("Delete failed on domain " + domain.getName() + " (id: " + domain.getId() + "); Please make sure all users and sub domains have been removed from the domain before deleting"); + e.addProxyObject(domain, domain.getId(), "domainId"); + throw e; } } else { - s_logger.warn("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); rollBackState = true; - return false; + CloudRuntimeException e = new CloudRuntimeException("Can't delete the domain yet because it has " + accountsForCleanup.size() + "accounts that need a cleanup"); + e.addProxyObject(domain, domain.getId(), "domainId"); + throw e; } } @@ -251,7 +253,10 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager return true; } catch (Exception ex) { s_logger.error("Exception deleting domain with id " + domain.getId(), ex); - return false; + if (ex instanceof CloudRuntimeException) + throw (CloudRuntimeException)ex; + else + return false; } finally { //when success is false if (rollBackState) { diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/server/src/com/cloud/uuididentity/dao/IdentityDao.java index 3d1b7da341f..f963fcbc476 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDao.java @@ -13,11 +13,18 @@ package com.cloud.uuididentity.dao; import com.cloud.api.IdentityMapper; +import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; public interface IdentityDao extends GenericDao { Long getIdentityId(IdentityMapper mapper, String identityString); Long getIdentityId(String tableName, String identityString); String getIdentityUuid(String tableName, String identityString); - void initializeDefaultUuid(String tableName); + void initializeDefaultUuid(String tableName); + /** + * @param tableName + * @param identityId + * @return + */ + Pair getAccountDomainInfo(String tableName, Long identityId); } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java index e0c0ccc4da5..a86dbcb0447 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java @@ -12,22 +12,23 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.uuididentity.dao; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - -import com.cloud.api.IdentityMapper; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.Transaction; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.api.IdentityMapper; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.utils.Pair; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.Transaction; @Local(value={IdentityDao.class}) public class IdentityDaoImpl extends GenericDaoBase implements IdentityDao { @@ -50,7 +51,14 @@ public class IdentityDaoImpl extends GenericDaoBase implements PreparedStatement pstmt = null; Transaction txn = Transaction.open(Transaction.CLOUD_DB); try { - try { + try { + try { + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s`", tableName)); + pstmt.executeQuery(); + } catch (SQLException e) { + throw new InvalidParameterValueException("uuid field doesn't exist in table " + tableName); + } + pstmt = txn.prepareAutoCloseStatement( String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName) @@ -85,9 +93,47 @@ public class IdentityDaoImpl extends GenericDaoBase implements txn.close(); } return null; + } + + @DB + @Override + public Pair getAccountDomainInfo(String tableName, Long identityId) { + assert(tableName != null); + + PreparedStatement pstmt = null; + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + Long domainId = null; + Long accountId = null; + //get domainId + try { + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT domain_id FROM `%s` WHERE id=?", tableName)); + pstmt.setLong(1, identityId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + domainId = rs.getLong(1); + } + } catch (SQLException e) { + } + + //get accountId + try { + pstmt = txn.prepareAutoCloseStatement(String.format("SELECT account_id FROM `%s` WHERE id=?", tableName)); + pstmt.setLong(1, identityId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + accountId = rs.getLong(1); + } + } catch (SQLException e) { + } + return new Pair(accountId, domainId); + } finally { + txn.close(); + } } - @DB + @DB + @Override public String getIdentityUuid(String tableName, String identityString) { assert(tableName != null); assert(identityString != null); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 63b85a573bc..a21f9fdf604 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -152,7 +152,6 @@ import com.cloud.storage.GuestOSVO; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; -import com.cloud.storage.VolumeHostVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; @@ -166,6 +165,7 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; @@ -213,6 +213,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.net.NetUtils; +import com.cloud.utils.AnnotationHelper; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.InstanceGroupDao; import com.cloud.vm.dao.InstanceGroupVMMapDao; @@ -425,7 +426,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId()); - NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork), _networkMgr.getNetworkTag(template.getHypervisorType(), defaultNetwork)); + NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, + _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork), + _networkMgr.getNetworkTag(template.getHypervisorType(), defaultNetwork)); VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance); vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password); @@ -2167,9 +2170,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List virtualNetworks = _networkMgr.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks.isEmpty()) { - s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process"); - Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, - null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); + s_logger.debug("Creating network for account " + owner + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), + owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, + null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds"); @@ -2346,11 +2351,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (defaultNetworkNumber == 0) { defaultNetworkNumber++; - profile.setDefaultNic(true); // if user requested specific ip for default network, add it if (defaultNetworkIp != null) { profile = new NicProfile(defaultNetworkIp); } + + profile.setDefaultNic(true); } networks.add(new Pair(network, profile)); @@ -2829,7 +2835,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // Verify input parameters UserVmVO vm = _vmDao.findById(vmId); if (vm == null || vm.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a virtual machine with specified vmId"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } if (vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { @@ -2846,7 +2854,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager try { status = _itMgr.destroy(vm, userCaller, caller); } catch (OperationTimedoutException e) { - throw new CloudRuntimeException("Unable to destroy " + vm, e); + CloudRuntimeException ex = new CloudRuntimeException("Unable to destroy with specified vmId", e); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } if (status) { @@ -2865,7 +2875,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return _vmDao.findById(vmId); } else { - throw new CloudRuntimeException("Failed to destroy vm with id " + vmId); + CloudRuntimeException ex = new CloudRuntimeException("Failed to destroy vm with specified vmId"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } } @@ -3070,10 +3082,12 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } @Override - public HypervisorType getHypervisorTypeOfUserVM(long vmid) { - UserVmVO userVm = _vmDao.findById(vmid); + public HypervisorType getHypervisorTypeOfUserVM(long vmId) { + UserVmVO userVm = _vmDao.findById(vmId); if (userVm == null) { - throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmid); + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find a virtual machine with specified id"); + ex.addProxyObject(userVm, vmId, "vmId"); + throw ex; } return userVm.getHypervisorType(); @@ -3108,7 +3122,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } if (vm.getState() != State.Stopped) { - throw new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm " + vm); + InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Stopped, unable to migrate the vm having the specified id"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } if (vm.getType() != VirtualMachine.Type.User) { @@ -3150,7 +3166,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (s_logger.isDebugEnabled()) { s_logger.debug("VM is not Running, unable to migrate the vm " + vm); } - throw new InvalidParameterValueException("VM is not Running, unable to migrate the vm " + vm); + InvalidParameterValueException ex = new InvalidParameterValueException("VM is not Running, unable to migrate the vm with specified id"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM) && !vm.getHypervisorType().equals(HypervisorType.Ovm)) { if (s_logger.isDebugEnabled()) { @@ -3220,7 +3238,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (s_logger.isDebugEnabled()) { s_logger.debug("VM is Running, unable to move the vm " + vm); } - throw new InvalidParameterValueException("VM is Running, unable to move the vm " + vm); + InvalidParameterValueException ex = new InvalidParameterValueException("VM is Running, unable to move the vm with specified vmId"); + ex.addProxyObject(vm, cmd.getVmId(), "vmId"); + throw ex; } Account oldAccount = _accountService.getActiveAccountById(vm.getAccountId()); @@ -3229,7 +3249,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } //don't allow to move the vm from the project if (oldAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { - throw new InvalidParameterValueException("Vm id=" + cmd.getVmId() + " belongs to the project and can't be moved"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified Vm id belongs to the project and can't be moved"); + ex.addProxyObject(vm, cmd.getVmId(), "vmId"); + throw ex; } Account newAccount = _accountService.getActiveAccountByName(cmd.getAccountName(), cmd.getDomainId()); if (newAccount == null || newAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { @@ -3416,7 +3438,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager for (Long networkId : networkIdList) { NetworkVO network = _networkDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkId); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find specified network id"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } _networkMgr.checkNetworkPermissions(newAccount, network); @@ -3424,7 +3448,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //don't allow to use system networks NetworkOffering networkOffering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); if (networkOffering.isSystemOnly()) { - throw new InvalidParameterValueException("Network id=" + networkId + " is system only and can't be used for vm deployment"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified Network id is system only and can't be used for vm deployment"); + ex.addProxyObject(network, networkId, "networkId"); + throw ex; } applicableNetworks.add(network); } @@ -3433,7 +3459,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager NetworkVO defaultNetwork = null; List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (requiredOfferings.size() < 1) { - throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as a part of vm creation"); + throw new InvalidParameterValueException("Unable to find network offering with availability=" + + Availability.Required + " to automatically create the network as a part of vm creation"); } PhysicalNetwork physicalNetwork = _networkMgr.translateZoneIdToPhysicalNetwork(zone.getId()); @@ -3442,17 +3469,21 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List virtualNetworks = _networkMgr.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks.isEmpty()) { - s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process"); - Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, - null, null, newAccount, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); + s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), + newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, + null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { - throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + newAccount + "; please specify networkIds"); + throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + + "for account " + newAccount + "; please specify networkIds"); } else { defaultNetwork = virtualNetworks.get(0); } } else { - throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + throw new InvalidParameterValueException("Required network offering id=" + + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); } applicableNetworks.add(defaultNetwork); @@ -3491,7 +3522,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager long vmId = cmd.getVmId(); UserVmVO vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Cann not find VM with ID " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Cann not find VM with ID " + vmId); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } Account owner = _accountDao.findById(vm.getAccountId()); @@ -3513,14 +3546,19 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List rootVols = _volsDao.findByInstance(vmId); if (rootVols.isEmpty()) { - throw new InvalidParameterValueException("Can not find root volume for VM " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vmId); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } VolumeVO root = rootVols.get(0); long templateId = root.getTemplateId(); VMTemplateVO template = _templateDao.findById(templateId); if (template == null) { - throw new InvalidParameterValueException("Cannot find template for volume " + root.getId() + " vm " + vmId); + InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template for specified volumeid and vmId"); + ex.addProxyObject(vm, vmId, "vmId"); + ex.addProxyObject(root, root.getId(), "volumeId"); + throw ex; } if (needRestart) { @@ -3528,7 +3566,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _itMgr.stop(vm, user, caller); } catch (ResourceUnavailableException e) { s_logger.debug("Stop vm " + vmId + " failed", e); - throw new CloudRuntimeException("Stop vm " + vmId + " failed"); + CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId"); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } } @@ -3549,7 +3589,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _itMgr.start(vm, null, user, caller); } catch (Exception e) { s_logger.debug("Unable to start VM " + vmId, e); - throw new CloudRuntimeException("Unable to start VM " + vmId + " " + e.getMessage()); + CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage()); + ex.addProxyObject(vm, vmId, "vmId"); + throw ex; } } @@ -3557,5 +3599,24 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return vm; } + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index f736310ebb8..82e42dd2af7 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -13,9 +13,15 @@ package com.cloud.vm; import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; /** * A VirtualMachineGuru knows how to process a certain type of virtual machine. @@ -68,4 +74,41 @@ public interface VirtualMachineGuru { * @return id if the handler works for this vm and can parse id. null if not. */ Long convertToId(String vmName); + + /** + * Prepare for a nic to be plugged into the network. + * @param network + * @param nic + * @param vm + * @param context + * @param dest TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientNetworkCapacityException + */ + boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; + + /** + * A nic is unplugged from this network. + * @param network + * @param nic + * @param vm + * @param context + * @param dest TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * Prepare Vm for Stop + * @param profile + * @return + */ + void prepareStop(VirtualMachineProfile profile); } diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 3387a8e22e7..1f2b4b50ba5 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -12,9 +12,12 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.List; import java.util.Map; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.AgentUnavailableException; @@ -26,6 +29,7 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; @@ -132,4 +136,40 @@ public interface VirtualMachineManager extends Manager { */ boolean upgradeVmDb(long vmId, long serviceOfferingId); + /** + * @param vm + * @param network + * @param requested TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientCapacityException + */ + NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vm + * @param network + * @param broadcastUri TODO + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param nic + * @param hypervisorType + * @return + */ + NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType); + + /** + * @param profile + * @param hvGuru + * @return + */ + VirtualMachineTO toVmTO(VirtualMachineProfile profile); + } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index b73d0fd8e48..54d72d95e11 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,6 +58,7 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupRoutingCommand.VmState; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; @@ -103,6 +105,7 @@ import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.dao.NetworkDao; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; @@ -217,6 +220,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene protected StoragePoolDao _storagePoolDao; @Inject protected HypervisorGuruManager _hvGuruMgr; + @Inject + protected NetworkDao _networkDao; @Inject(adapter = DeploymentPlanner.class) protected Adapters _planners; @@ -748,11 +753,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene reuseVolume = true; } - VirtualMachineTO vmTO = null; Commands cmds = null; vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); - vmTO = hvGuru.implement(vmProfile); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); cmds.addCommand(new StartCommand(vmTO)); @@ -1059,11 +1063,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if (vm.getState() != State.Stopping) { throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState()); } - String routerPrivateIp = null; - if (vm.getType() == VirtualMachine.Type.DomainRouter) { - routerPrivateIp = vm.getPrivateIpAddress(); - } - StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null, routerPrivateIp); + + vmGuru.prepareStop(profile); + + StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); boolean stopped = false; StopAnswer answer = null; try { @@ -1300,9 +1303,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); _networkMgr.prepareNicForMigration(profile, dest); _storageMgr.prepareForMigration(profile, dest); - HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); - VirtualMachineTO to = hvGuru.implement(profile); + VirtualMachineTO to = toVmTO(profile); PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId()); @@ -1407,6 +1409,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene } } + @Override + public VirtualMachineTO toVmTO(VirtualMachineProfile profile) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO to = hvGuru.implement(profile); + return to; + } + protected void cancelWorkItems(long nodeId) { GlobalLock scanLock = GlobalLock.getInternLock("vmmgr.cancel.workitem"); @@ -2128,7 +2137,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene List nics = _nicsDao.listByVmId(profile.getId()); for (NicVO nic : nics) { Network network = _networkMgr.getNetwork(nic.getNetworkId()); - NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); profile.addNic(nicProfile); } @@ -2426,4 +2436,124 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene vmForUpdate.setServiceOfferingId(newSvcOff.getId()); return _vmDao.update(vmId, vmForUpdate); } + + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + s_logger.debug("Adding vm " + vm + " to network " + network); + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + NetworkVO networkVO = _networkDao.findById(network.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + + NicProfile nic = null; + String broadcastUri = null; + if (requested != null && requested.getBroadCastUri() != null) { + broadcastUri = requested.getBroadCastUri().toString(); + NicVO nicVO = _nicsDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri); + if (nicVO != null) { + nic = _networkMgr.getNicProfile(vm, network.getId()); + } + } else { + NicVO nicVO = _nicsDao.findByInstanceIdAndNetworkId(network.getId(), vm.getId()); + if (nicVO != null) { + nic = _networkMgr.getNicProfile(vm, network.getId()); + } + } + + if (nic == null) { + s_logger.debug("Allocating nic for the " + vm + " in network " + network); + //1) allocate nic and prepare nic if needed + int deviceId = _nicsDao.countNics(vm.getId()); + + nic = _networkMgr.allocateNic(requested, network, false, + deviceId, vmProfile).first(); + + if (nic == null) { + throw new CloudRuntimeException("Failed to allocate nic for vm " + vm + " in network " + network); + } + + s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network); + + nic = _networkMgr.prepareNic(vmProfile, dest, context, nic.getId(), networkVO); + + s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network); + + } + + //2) Convert vmProfile to vmTO + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + //3) Convert nicProfile to NicTO + NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); + + //4) plug the nic to the vm + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + + s_logger.debug("Plugging nic for vm " + vm + " in network " + network); + if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) { + s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm is a part of network now"); + return nic; + } else { + s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); + return null; + } + } + + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType); + + NicTO nicTO = hvGuru.toNicTO(nic); + return nicTO; + } + + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + NetworkVO networkVO = _networkDao.findById(network.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + + //1) Release the nic + NicProfile nic = _networkMgr.releaseNic(vmProfile, networkVO, broadcastUri); + + //2) Convert vmProfile to vmTO + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); + + s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network); + boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest); + //4) Unplug the nic + if (result) { + s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network ); + } else { + s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); + return false; + } + + //6) Remove the nic + _networkMgr.removeNic(vmProfile, network); + return result; + } + } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index af5cd32fc99..ed861841d59 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -64,16 +64,7 @@ public interface DomainRouterDao extends GenericDao { * @param hostId id of the host. null if to get all. * @return list of DomainRouterVO */ - public List listVirtualByHostId(Long hostId); - - /** - * list virtual machine routers by host id. exclude destroyed, stopped, expunging VM, - * pass in null to get all - * virtual machine routers. - * @param hostId id of the host. null if to get all. - * @return list of DomainRouterVO - */ - public List listVirtualUpByHostId(Long hostId); + public List listIsolatedByHostId(Long hostId); /** * Find the list of domain routers for a domain @@ -101,4 +92,43 @@ public interface DomainRouterDao extends GenericDao { List listByNetworkAndRole(long networkId, Role role); List listByElementId(long elementId); + + /** + * Persists the domain router instance + creates the reference to the guest network (if not null) + * @param guestNetworks TODO + * @return + */ + DomainRouterVO persist(DomainRouterVO router, List guestNetworks); + + /** + * @param routerId + * @return + */ + List getRouterNetworks(long routerId); + + /** + * @param vpcId + * @return + */ + List listByVpcId(long vpcId); + + /** + * @param routerId + * @param guestNetwork + */ + void addRouterToGuestNetwork(DomainRouterVO router, Network guestNetwork); + + /** + * @param routerId + * @param guestNetworkId + */ + void removeRouterFromNetwork(long routerId, long guestNetworkId); + + /** + * @param routerId + * @param guestNetworkId + * @return + */ + boolean isRouterPartOfGuestNetwork(long routerId, long guestNetworkId); + } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 1f28c3ad547..176f03a253b 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -16,15 +16,16 @@ import java.util.List; import javax.ejb.Local; -import org.apache.log4j.Logger; - import com.cloud.host.HostVO; import com.cloud.host.dao.HostDaoImpl; import com.cloud.network.Network; -import com.cloud.network.NetworkVO; -import com.cloud.network.dao.NetworkDaoImpl; +import com.cloud.network.RouterNetworkDaoImpl; +import com.cloud.network.RouterNetworkVO; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; @@ -37,15 +38,16 @@ import com.cloud.vm.VirtualMachine.State; @Local(value = { DomainRouterDao.class }) public class DomainRouterDaoImpl extends GenericDaoBase implements DomainRouterDao { - private static final Logger s_logger = Logger.getLogger(DomainRouterDaoImpl.class); protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder IdNetworkIdStatesSearch; protected final SearchBuilder HostUpSearch; protected final SearchBuilder StateNetworkTypeSearch; protected final SearchBuilder OutsidePodSearch; - NetworkDaoImpl _networksDao = ComponentLocator.inject(NetworkDaoImpl.class); HostDaoImpl _hostsDao = ComponentLocator.inject(HostDaoImpl.class); + RouterNetworkDaoImpl _routerNetworkDao = ComponentLocator.inject(RouterNetworkDaoImpl.class); + UserStatisticsDaoImpl _userStatsDao = ComponentLocator.inject(UserStatisticsDaoImpl.class); + protected final SearchBuilder VpcSearch; protected DomainRouterDaoImpl() { AllFieldsSearch = createSearchBuilder(); @@ -56,37 +58,55 @@ public class DomainRouterDaoImpl extends GenericDaoBase im AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ); AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ); AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork.and("networkId", joinRouterNetwork.entity().getNetworkId(), Op.EQ); + AllFieldsSearch.join("networkRouter", joinRouterNetwork, joinRouterNetwork.entity().getRouterId(), AllFieldsSearch.entity().getId(), JoinType.INNER); AllFieldsSearch.and("podId", AllFieldsSearch.entity().getPodIdToDeployIn(), Op.EQ); AllFieldsSearch.and("elementId", AllFieldsSearch.entity().getElementId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); + + VpcSearch = createSearchBuilder(); + VpcSearch.and("role", VpcSearch.entity().getRole(), Op.EQ); + VpcSearch.and("vpcId", VpcSearch.entity().getVpcId(), Op.EQ); + VpcSearch.done(); IdNetworkIdStatesSearch = createSearchBuilder(); IdNetworkIdStatesSearch.and("id", IdNetworkIdStatesSearch.entity().getId(), Op.EQ); - IdNetworkIdStatesSearch.and("network", IdNetworkIdStatesSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork1 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork1.and("networkId", joinRouterNetwork1.entity().getNetworkId(), Op.EQ); + IdNetworkIdStatesSearch.join("networkRouter", joinRouterNetwork1, joinRouterNetwork1.entity().getRouterId(), IdNetworkIdStatesSearch.entity().getId(), JoinType.INNER); IdNetworkIdStatesSearch.and("states", IdNetworkIdStatesSearch.entity().getState(), Op.IN); IdNetworkIdStatesSearch.done(); HostUpSearch = createSearchBuilder(); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN); - SearchBuilder joinNetwork = _networksDao.createSearchBuilder(); - joinNetwork.and("type", joinNetwork.entity().getGuestType(), Op.EQ); - HostUpSearch.join("network", joinNetwork, joinNetwork.entity().getId(), HostUpSearch.entity().getNetworkId(), JoinType.INNER); + SearchBuilder joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork3.and("networkId", joinRouterNetwork3.entity().getNetworkId(), Op.EQ); + joinRouterNetwork3.and("type", joinRouterNetwork3.entity().getGuestType(), Op.EQ); + HostUpSearch.join("networkRouter", joinRouterNetwork3, joinRouterNetwork3.entity().getRouterId(), HostUpSearch.entity().getId(), JoinType.INNER); HostUpSearch.done(); - + StateNetworkTypeSearch = createSearchBuilder(); StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ); - SearchBuilder joinStateNetwork = _networksDao.createSearchBuilder(); - joinStateNetwork.and("type", joinStateNetwork.entity().getGuestType(), Op.EQ); - StateNetworkTypeSearch.join("network", joinStateNetwork, joinStateNetwork.entity().getId(), StateNetworkTypeSearch.entity().getNetworkId(), JoinType.INNER); + SearchBuilder joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ); + joinRouterNetwork4.and("type", joinRouterNetwork4.entity().getGuestType(), Op.EQ); + StateNetworkTypeSearch.join("networkRouter", joinRouterNetwork4, joinRouterNetwork4.entity().getRouterId(), StateNetworkTypeSearch.entity().getId(), JoinType.INNER); + SearchBuilder joinHost = _hostsDao.createSearchBuilder(); joinHost.and("mgmtServerId", joinHost.entity().getManagementServerId(), Op.EQ); - StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER); + StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), + StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER); StateNetworkTypeSearch.done(); - + + OutsidePodSearch = createSearchBuilder(); - OutsidePodSearch.and("network", OutsidePodSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork2 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork2.and("networkId", joinRouterNetwork2.entity().getNetworkId(), Op.EQ); + OutsidePodSearch.join("networkRouter", joinRouterNetwork2, joinRouterNetwork2.entity().getRouterId(), + OutsidePodSearch.entity().getId(), JoinType.INNER); OutsidePodSearch.and("podId", OutsidePodSearch.entity().getPodIdToDeployIn(), Op.NEQ); OutsidePodSearch.and("state", OutsidePodSearch.entity().getState(), Op.EQ); OutsidePodSearch.and("role", OutsidePodSearch.entity().getRole(), Op.EQ); @@ -150,23 +170,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im } @Override - public List listVirtualByHostId(Long hostId) { + public List listIsolatedByHostId(Long hostId) { SearchCriteria sc = HostUpSearch.create(); if (hostId != null) { sc.setParameters("host", hostId); } - sc.setJoinParameters("network", "type", Network.GuestType.Isolated); - return listBy(sc); - } - - @Override - public List listVirtualUpByHostId(Long hostId) { - SearchCriteria sc = HostUpSearch.create(); - if (hostId != null) { - sc.setParameters("host", hostId); - } - sc.setParameters("states", State.Destroyed, State.Stopped, State.Expunging); - sc.setJoinParameters("network", "type", Network.GuestType.Isolated); + sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated); return listBy(sc); } @@ -180,7 +189,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List findByNetwork(long networkId) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); return listBy(sc); } @@ -195,7 +204,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listActive(long networkId) { SearchCriteria sc = IdNetworkIdStatesSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("states", State.Running, State.Migrating, State.Stopping, State.Starting); return listBy(sc); } @@ -204,7 +213,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im public List listByStateAndNetworkType(State state, Network.GuestType type, long mgmtSrvrId) { SearchCriteria sc = StateNetworkTypeSearch.create(); sc.setParameters("state", state); - sc.setJoinParameters("network", "type", type); + sc.setJoinParameters("networkRouter", "type", type); sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); return listBy(sc); } @@ -212,7 +221,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List findByNetworkOutsideThePod(long networkId, long podId, State state, Role role) { SearchCriteria sc = OutsidePodSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("podId", podId); sc.setParameters("state", state); sc.setParameters("role", role); @@ -222,7 +231,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listByNetworkAndPodAndRole(long networkId, long podId, Role role) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("podId", podId); sc.setParameters("role", role); return listBy(sc); @@ -231,7 +240,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listByNetworkAndRole(long networkId, Role role) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("role", role); return listBy(sc); } @@ -242,4 +251,71 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("elementId", elementId); return listBy(sc); } + + @Override + @DB + public DomainRouterVO persist(DomainRouterVO router, List guestNetworks) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + // 1) create network + DomainRouterVO newRouter = super.persist(router); + + if (guestNetworks != null && !guestNetworks.isEmpty()) { + // 2) add router to the network + for (Network guestNetwork : guestNetworks) { + if (!isRouterPartOfGuestNetwork(router.getId(), guestNetwork.getId())) { + addRouterToGuestNetwork(router, guestNetwork); + } + } + } + + txn.commit(); + return newRouter; + } + + @Override + @DB + public void addRouterToGuestNetwork(DomainRouterVO router, Network guestNetwork) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + //1) add router to network + RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType()); + _routerNetworkDao.persist(routerNtwkMap); + //2) create user stats entry for the network + UserStatisticsVO stats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(), + guestNetwork.getId(), null, router.getId(), router.getType().toString()); + if (stats == null) { + stats = new UserStatisticsVO(router.getAccountId(), router.getDataCenterIdToDeployIn(), null, router.getId(), + router.getType().toString(), guestNetwork.getId()); + _userStatsDao.persist(stats); + } + txn.commit(); + } + + @Override + public void removeRouterFromNetwork(long routerId, long guestNetworkId) { + RouterNetworkVO routerNtwkMap = _routerNetworkDao.findByRouterAndNetwork(routerId, guestNetworkId); + _routerNetworkDao.remove(routerNtwkMap.getId()); + } + + @Override + public List getRouterNetworks(long routerId) { + return _routerNetworkDao.getRouterNetworks(routerId); + } + + @Override + public List listByVpcId(long vpcId) { + SearchCriteria sc = VpcSearch.create(); + sc.setParameters("vpcId", vpcId); + sc.setParameters("role", Role.VIRTUAL_ROUTER); + return listBy(sc); + } + + @Override + public boolean isRouterPartOfGuestNetwork(long routerId, long guestNetworkId) { + RouterNetworkVO routerNtwkMap = _routerNetworkDao.findByRouterAndNetwork(routerId, guestNetworkId); + return routerNtwkMap != null; + } + } diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 2748ba22231..3dca809e3e9 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -37,4 +37,17 @@ public interface NicDao extends GenericDao { NicVO findByIp4AddressAndNetworkId(String ip4Address, long networkId); NicVO findDefaultNicForVM(long instanceId); + + /** + * @param networkId + * @param instanceId + * @return + */ + NicVO findNonReleasedByInstanceIdAndNetworkId(long networkId, long instanceId); + + String getIpAddress(long networkId, long instanceId); + + int countNics(long instanceId); + + NicVO findByInstanceIdNetworkIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 1e3d6e06363..77f54ce81cd 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -22,6 +22,8 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.vm.Nic; +import com.cloud.vm.Nic.State; import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachine; @@ -29,6 +31,9 @@ import com.cloud.vm.VirtualMachine; public class NicDaoImpl extends GenericDaoBase implements NicDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; + private final SearchBuilder NonReleasedSearch; + final GenericSearchBuilder CountBy; + protected NicDaoImpl() { super(); @@ -39,6 +44,7 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { AllFieldsSearch.and("vmType", AllFieldsSearch.entity().getVmType(), Op.EQ); AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ); AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().isDefaultNic(), Op.EQ); + AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); AllFieldsSearch.done(); IpSearch = createSearchBuilder(String.class); @@ -46,6 +52,18 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ); IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL); IpSearch.done(); + + NonReleasedSearch = createSearchBuilder(); + NonReleasedSearch.and("instance", NonReleasedSearch.entity().getInstanceId(), Op.EQ); + NonReleasedSearch.and("network", NonReleasedSearch.entity().getNetworkId(), Op.EQ); + NonReleasedSearch.and("state", NonReleasedSearch.entity().getState(), Op.NOTIN); + NonReleasedSearch.done(); + + CountBy = createSearchBuilder(Integer.class); + CountBy.select(null, Func.COUNT, CountBy.entity().getId()); + CountBy.and("vmId", CountBy.entity().getInstanceId(), Op.EQ); + CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); + CountBy.done(); } @Override @@ -123,4 +141,40 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { sc.setParameters("isDefault", 1); return findOneBy(sc); } + + @Override + public NicVO findNonReleasedByInstanceIdAndNetworkId(long networkId, long instanceId) { + SearchCriteria sc = NonReleasedSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + sc.setParameters("state", State.Releasing, Nic.State.Deallocating); + return findOneBy(sc); + } + + @Override + public String getIpAddress(long networkId, long instanceId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + return findOneBy(sc).getIp4Address(); + } + + @Override + public int countNics(long instanceId) { + SearchCriteria sc = CountBy.create(); + sc.setParameters("vmId", instanceId); + List results = customSearch(sc, null); + return results.get(0); + } + + + @Override + public NicVO findByInstanceIdNetworkIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + sc.setParameters("broadcastUri", broadcastUri); + return findOneBy(sc); + } + } diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 594986c226c..0c7e62219c0 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -43,7 +43,6 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; -import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Event; diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index b2b4ce04ccc..4801251e1b6 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -44,11 +45,14 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; +import com.cloud.network.element.Site2SiteVpnServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; @@ -72,19 +76,19 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public IpAddress associateIP(long ipId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException { + public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub return null; } @Override - public boolean disassociateIpAddress(long ipAddressId) { + public boolean releaseIpAddress(long ipAddressId) { // TODO Auto-generated method stub return false; } @Override - public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { + public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { // TODO Auto-generated method stub return null; } @@ -178,21 +182,14 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } - @Override - public PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean releasePublicIpAddress(long id, long userId, Account caller) { + public boolean disassociatePublicIpAddress(long id, long userId, Account caller) { // TODO Auto-generated method stub return false; } @Override - public List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId) { + public List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) { // TODO Auto-generated method stub return null; } @@ -206,7 +203,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS @Override public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException { // TODO Auto-generated method stub return null; } @@ -310,8 +307,8 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, - Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { // TODO Auto-generated method stub return null; } @@ -645,12 +642,6 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS return false; } - @Override - public PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { - // TODO Auto-generated method stub - return null; - } - @Override public Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) { // TODO Auto-generated method stub @@ -707,13 +698,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS // TODO Auto-generated method stub return false; } - - @Override - public PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { - // TODO Auto-generated method stub - return null; - } - + @Override public List getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) { // TODO Auto-generated method stub @@ -874,10 +859,220 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#allocateIP(long, com.cloud.user.Account) + * @see com.cloud.network.NetworkService#isVmPartOfNetwork(long, long) */ @Override - public IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public boolean isVmPartOfNetwork(long vmId, long ntwkId) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#associateIP(long, java.lang.Long, java.lang.Long) + */ + @Override + public IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#createPrivateNetwork(java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long) + */ + @Override + public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIP, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getAccountNetworkDomain(long, long) + */ + @Override + public String getAccountNetworkDomain(long accountId, long zoneId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getDefaultNetworkDomain() + */ + @Override + public String getDefaultNetworkDomain() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getNtwkOffDistinctProviders(long) + */ + @Override + public List getNtwkOffDistinctProviders(long networkId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#allocateNic(com.cloud.vm.NicProfile, com.cloud.network.Network, java.lang.Boolean, int, com.cloud.vm.VirtualMachineProfile) + */ + @Override + public Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#prepareNic(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext, long, com.cloud.network.NetworkVO) + */ + @Override + public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context, long nicId, NetworkVO network) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.NetworkVO) + */ + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#removeNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.Network) + */ + @Override + public void removeNic(VirtualMachineProfile vm, Network network) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean) + */ + @Override + public List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#unassignIPFromVpcNetwork(long) + */ + @Override + public void unassignIPFromVpcNetwork(long ipId) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getNicProfile(com.cloud.vm.VirtualMachine, long) + */ + @Override + public NicProfile getNicProfile(VirtualMachine vm, long networkId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @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 + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.NetworkVO, java.net.URI) + */ + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#allocateIP(com.cloud.user.Account, boolean, long) + */ + @Override + public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#listNetworksByVpc(long) + */ + @Override + public List listNetworksByVpc(long vpcId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getElementImplementingProvider(java.lang.String) + */ + @Override + public NetworkElement getElementImplementingProvider(String providerName) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#assignSourceNatIpAddressToGuestNetwork(com.cloud.user.Account, com.cloud.network.Network) + */ + @Override + public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#assignSourceNatIpAddressToVpc(com.cloud.user.Account, com.cloud.network.vpc.Vpc) + */ + @Override + public PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#canUseForDeploy(com.cloud.network.Network) + */ + @Override + public boolean canUseForDeploy(Network network) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getPhysicalNtwksSupportingTrafficType(long, com.cloud.network.Networks.TrafficType) + */ + @Override + public List getPhysicalNtwksSupportingTrafficType(long zoneId, TrafficType trafficType) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#isPrivateGateway(com.cloud.vm.Nic) + */ + @Override + public boolean isPrivateGateway(Nic guestNic) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getSite2SiteVpnElements() + */ + @Override + public List getSite2SiteVpnElements() { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index e6ab4fec2ee..e7ee1edd1ee 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -254,7 +254,7 @@ public class MockAccountManagerImpl implements Manager, AccountManager { } @Override - public UserAccount authenticateUser(String username, String password, Long domainId, Map requestParameters) { + public UserAccount authenticateUser(String username, String password, Long domainId, String loginIpAddress, Map requestParameters) { return null; } diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java index 1ba56480256..dd16dc75e4f 100644 --- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java +++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java @@ -21,6 +21,8 @@ import javax.naming.ConfigurationException; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.api.commands.AssignVMCmd; import com.cloud.api.commands.AttachVolumeCmd; @@ -49,6 +51,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; import com.cloud.offering.ServiceOffering; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.Criteria; @@ -407,4 +410,23 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana return null; } + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineGuru#plugNic(com.cloud.network.Network, com.cloud.agent.api.to.NicTO, com.cloud.agent.api.to.VirtualMachineTO, com.cloud.vm.ReservationContext, com.cloud.deploy.DeployDestination) + */ + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineGuru#unplugNic(com.cloud.network.Network, com.cloud.agent.api.to.NicTO, com.cloud.agent.api.to.VirtualMachineTO, com.cloud.vm.ReservationContext, com.cloud.deploy.DeployDestination) + */ + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + } diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 5a65a6d13f9..721925c03be 100755 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -12,12 +12,15 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.List; import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.AgentUnavailableException; @@ -29,6 +32,7 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; @@ -235,4 +239,40 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager { return false; } + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#addVmToNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, com.cloud.vm.NicProfile) + */ + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI) + */ + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#toNicTO(com.cloud.vm.NicProfile, com.cloud.hypervisor.Hypervisor.HypervisorType) + */ + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#toVmTO(com.cloud.vm.VirtualMachineProfile) + */ + @Override + public VirtualMachineTO toVmTO(VirtualMachineProfile profile) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/setup/apidoc/gen_toc.py b/setup/apidoc/gen_toc.py index 1c2f48c4c09..f2cd0d57fbc 100644 --- a/setup/apidoc/gen_toc.py +++ b/setup/apidoc/gen_toc.py @@ -81,6 +81,7 @@ known_categories = { 'Pod': 'Pod', 'Zone': 'Zone', 'NetworkOffering': 'Network Offering', + 'NetworkACL': 'Network ACL', 'Network': 'Network', 'CiscoNexus': 'Network', 'Vpn': 'VPN', @@ -115,6 +116,10 @@ known_categories = { 'Project': 'Project', 'Lun': 'Storage', 'Pool': 'Pool', + 'Tags': 'Resource Tags', + 'VPC': 'VPC', + 'PrivateGateway': 'VPC', + 'StaticRoute': 'VPC', } diff --git a/setup/db/create-schema-premium.sql b/setup/db/create-schema-premium.sql index f0e68aaf7bc..9a446355650 100644 --- a/setup/db/create-schema-premium.sql +++ b/setup/db/create-schema-premium.sql @@ -131,6 +131,7 @@ CREATE TABLE `cloud_usage`.`account` ( `removed` datetime COMMENT 'date removed', `cleanup_needed` tinyint(1) NOT NULL default '0', `network_domain` varchar(100) COMMENT 'Network domain name of the Vms of the account', + `default_zone_id` bigint unsigned, CONSTRAINT `uc_account__uuid` UNIQUE (`uuid`), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index d7cd2d64549..c2eafd661f7 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -137,6 +137,9 @@ DROP TABLE IF EXISTS `cloud`.`op_dc_storage_network_ip_address`; DROP TABLE IF EXISTS `cloud`.`cluster_vsm_map`; DROP TABLE IF EXISTS `cloud`.`virtual_supervisor_module`; DROP TABLE IF EXISTS `cloud`.`port_profile`; +DROP TABLE IF EXISTS `cloud`.`s2s_customer_gateway`; +DROP TABLE IF EXISTS `cloud`.`s2s_vpn_gateway`; +DROP TABLE IF EXISTS `cloud`.`s2s_vpn_connection`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -208,12 +211,14 @@ CREATE TABLE `cloud`.`networks` ( `created` datetime NOT NULL COMMENT 'date created', `removed` datetime COMMENT 'date removed if not null', `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network provides an ability to define ip ranges', + `vpc_id` bigint unsigned COMMENT 'vpc this network belongs to', PRIMARY KEY (`id`), CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + CONSTRAINT `fk_networks__vpc_id` FOREIGN KEY(`vpc_id`) REFERENCES `vpc`(`id`), CONSTRAINT `uc_networks__uuid` UNIQUE (`uuid`), INDEX `i_networks__removed`(`removed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -645,7 +650,7 @@ CREATE TABLE `cloud`.`op_dc_vnet_alloc` ( CREATE TABLE `cloud`.`firewall_rules` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', `uuid` varchar(40), - `ip_address_id` bigint unsigned NOT NULL COMMENT 'id of the corresponding ip address', + `ip_address_id` bigint unsigned COMMENT 'id of the corresponding ip address', `start_port` int(10) COMMENT 'starting port of a port range', `end_port` int(10) COMMENT 'end port of a port range', `state` char(32) NOT NULL COMMENT 'current state of this rule', @@ -660,12 +665,15 @@ CREATE TABLE `cloud`.`firewall_rules` ( `icmp_type` int(10) COMMENT 'The ICMP type (if protocol=ICMP). A value of -1 means all types.', `related` bigint unsigned COMMENT 'related to what other firewall rule', `type` varchar(10) NOT NULL DEFAULT 'USER', + `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', + `traffic_type` char(32) COMMENT 'the traffic type of the rule, can be Ingress or Egress', PRIMARY KEY (`id`), CONSTRAINT `fk_firewall_rules__ip_address_id` FOREIGN KEY(`ip_address_id`) REFERENCES `user_ip_address`(`id`), CONSTRAINT `fk_firewall_rules__network_id` FOREIGN KEY(`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_firewall_rules__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_firewall_rules__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_firewall_rules__related` FOREIGN KEY(`related`) REFERENCES `firewall_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_firewall_rules__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, INDEX `i_firewall_rules__purpose`(`purpose`), CONSTRAINT `uc_firewall_rules__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -918,6 +926,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( `network_id` bigint unsigned COMMENT 'network this public ip address is associated with', `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', `is_system` int(1) unsigned NOT NULL default '0', + `vpc_id` bigint unsigned COMMENT 'vpc the ip address is associated with', PRIMARY KEY (`id`), UNIQUE (`public_ip_address`, `source_network_id`), CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`), @@ -928,6 +937,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( CONSTRAINT `fk_user_ip_address__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `uc_user_ip_address__uuid` UNIQUE (`uuid`), CONSTRAINT `fk_user_ip_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user_ip_address__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, INDEX `i_user_ip_address__allocated`(`allocated`), INDEX `i_user_ip_address__source_nat`(`source_nat`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1069,7 +1079,6 @@ CREATE TABLE `cloud`.`domain_router` ( `public_netmask` varchar(15) COMMENT 'netmask used for the domR', `guest_netmask` varchar(15) COMMENT 'netmask used for the guest network', `guest_ip_address` char(40) COMMENT ' ip address in the guest network', - `network_id` bigint unsigned NOT NULL COMMENT 'network configuration that this domain router belongs to', `is_redundant_router` int(1) unsigned NOT NULL COMMENT 'if in redundant router mode', `priority` int(4) unsigned COMMENT 'priority of router in the redundant router mode', `is_priority_bumpup` int(1) unsigned NOT NULL COMMENT 'if the priority has been bumped up', @@ -1078,9 +1087,11 @@ CREATE TABLE `cloud`.`domain_router` ( `role` varchar(64) NOT NULL COMMENT 'type of role played by this router', `template_version` varchar(100) COMMENT 'template version', `scripts_version` varchar(100) COMMENT 'scripts version', + `vpc_id` bigint unsigned COMMENT 'correlated virtual router vpc ID', PRIMARY KEY (`id`), CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`) + CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`), + CONSTRAINT `fk_domain_router__vpc_id` FOREIGN KEY `fk_domain_router__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance'; CREATE TABLE `cloud`.`upload` ( @@ -2122,5 +2133,179 @@ CREATE TABLE `cloud`.`port_profile` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`s2s_vpn_gateway` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `addr_id` bigint unsigned UNIQUE NOT NULL, + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_s2s_vpn_gateway__addr_id` FOREIGN KEY (`addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, + CONSTRAINT `uc_s2s_vpn_gateway__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`s2s_customer_gateway` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `gateway_ip` char(40) UNIQUE NOT NULL, + `guest_cidr_list` varchar(200) NOT NULL, + `ipsec_psk` varchar(256), + `ike_policy` varchar(30) NOT NULL, + `esp_policy` varchar(30) NOT NULL, + `lifetime` int, + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `uc_s2s_customer_gateway__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`s2s_vpn_connection` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `vpn_gateway_id` bigint unsigned NULL, + `customer_gateway_id` bigint unsigned NULL, + `state` varchar(32) NOT NULL, + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_s2s_vpn_connection__vpn_gateway_id` FOREIGN KEY (`vpn_gateway_id`) REFERENCES `s2s_vpn_gateway` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_s2s_vpn_connection__customer_gateway_id` FOREIGN KEY (`customer_gateway_id`) REFERENCES `s2s_customer_gateway` (`id`) ON DELETE CASCADE, + CONSTRAINT `uc_s2s_vpn_connection__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`resource_tags` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `key` varchar(255), + `value` varchar(255), + `resource_id` bigint unsigned NOT NULL, + `resource_type` varchar(255), + `customer` varchar(255), + `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpc` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'vpc display text', + `cidr` varchar(18) COMMENT 'vpc cidr', + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc offering id that this vpc is created from', + `zone_id` bigint unsigned NOT NULL COMMENT 'the id of the zone this Vpc belongs to', + `state` varchar(32) NOT NULL COMMENT 'state of the VP (can be Enabled and Disabled)', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain the vpc belongs to', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this vpc', + `network_domain` varchar(255) COMMENT 'network domain', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the VPC', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc__zone_id` FOREIGN KEY `fk_vpc__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), + CONSTRAINT `fk_vpc__account_id` FOREIGN KEY `fk_vpc__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__domain_id` FOREIGN KEY `fk_vpc__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_offerings` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the vpc offering', + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'display text', + `state` char(32) COMMENT 'state of the vpc offering that has Disabled value by default', + `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if vpc offering is default', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc_offerings__service_offering_id` FOREIGN KEY `fk_vpc_offerings__service_offering_id` (`service_offering_id`) REFERENCES `service_offering`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpc_offering_service_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc_offering_id', + `service` varchar(255) NOT NULL COMMENT 'service', + `provider` varchar(255) COMMENT 'service provider', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_offering_service_map__vpc_offering_id` FOREIGN KEY(`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`) ON DELETE CASCADE, + UNIQUE (`vpc_offering_id`, `service`, `provider`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`router_network_ref` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `router_id` bigint unsigned NOT NULL COMMENT 'router id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', + PRIMARY KEY (`id`), + CONSTRAINT `fk_router_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + UNIQUE `i_router_network_ref__router_id__network_id`(`router_id`, `network_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_gateways` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `ip4_address` char(40) COMMENT 'ip4 address of the gateway', + `netmask` varchar(15) COMMENT 'netmask of the gateway', + `gateway` varchar(15) COMMENT 'gateway', + `vlan_tag` varchar(255), + `type` varchar(32) COMMENT 'type of gateway; can be Public/Private/Vpn', + `network_id` bigint unsigned NOT NULL COMMENT 'network id vpc gateway belongs to', + `vpc_id` bigint unsigned NOT NULL COMMENT 'id of the vpc the gateway belongs to', + `zone_id` bigint unsigned NOT NULL COMMENT 'id of the zone the gateway belongs to', + `created` datetime COMMENT 'date created', + `account_id` bigint unsigned NOT NULL COMMENT 'owner id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_gateways__network_id` FOREIGN KEY `fk_vpc_gateways__network_id`(`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_vpc_gateways__vpc_id` FOREIGN KEY `fk_vpc_gateways__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), + CONSTRAINT `fk_vpc_gateways__zone_id` FOREIGN KEY `fk_vpc_gateways__zone_id`(`zone_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `fk_vpc_gateways__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc_gateways__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_vpc_gateways__uuid` UNIQUE (`uuid`), + INDEX `i_vpc_gateways__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`private_ip_address` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `network_id` bigint unsigned NOT NULL COMMENT 'id of the network ip belongs to', + `reservation_id` char(40) COMMENT 'reservation id', + `mac_address` varchar(17) COMMENT 'mac address', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + CONSTRAINT `fk_private_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`static_routes` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `vpc_gateway_id` bigint unsigned COMMENT 'id of the corresponding ip address', + `cidr` varchar(18) COMMENT 'cidr for the static route', + `state` char(32) NOT NULL COMMENT 'current state of this rule', + `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', + `account_id` bigint unsigned NOT NULL COMMENT 'owner id', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain id', + `created` datetime COMMENT 'Date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_static_routes__vpc_gateway_id` FOREIGN KEY(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_static_routes__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1; + diff --git a/setup/db/db/schema-2214to30.sql b/setup/db/db/schema-2214to30.sql index 57b1fd674d0..cfaa36a071e 100755 --- a/setup/db/db/schema-2214to30.sql +++ b/setup/db/db/schema-2214to30.sql @@ -719,7 +719,7 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag UPDATE `cloud`.`network_offerings` SET display_text='Offering for Shared Security group enabled networks' where display_text='System-Guest-Network'; UPDATE `cloud`.`configuration` SET category = 'Secure' where name in ('alert.smtp.password', 'network.loadbalancer.haproxy.stats.auth', 'security.singlesignon.key', 'project.smtp.password'); - +UPDATE `cloud`.`configuration` SET category = 'Hidden' where name in ('secondary.storage.vm', 'xen.create.pools.in.pod', 'cloud.identifier', 'security.hash.key', 'router.ram.size'); INSERT IGNORE INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (143, 1, 'CentOS 6.0 (32-bit)'); INSERT IGNORE INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (144, 1, 'CentOS 6.0 (64-bit)'); diff --git a/setup/db/db/schema-302to303.sql b/setup/db/db/schema-302to303.sql index 30f53b2fb1e..b3ab8dcfb1a 100755 --- a/setup/db/db/schema-302to303.sql +++ b/setup/db/db/schema-302to303.sql @@ -103,11 +103,8 @@ UPDATE `cloud`.`configuration` set component='NetworkManager' where name='router UPDATE `cloud`.`configuration` set component='NetworkManager' where name='router.ram.size'; UPDATE `cloud`.`configuration` set component='NetworkManager' where name='router.stats.interval'; UPDATE `cloud`.`configuration` set component='NetworkManager' where name='router.template.id'; -UPDATE `cloud`.`configuration` set category='Advanced ' where name='capacity.skipcounting.hours'; -UPDATE `cloud`.`configuration` set category='Advanced ' where name='use.local.storage'; -UPDATE `cloud`.`configuration` set category='Hidden ' where name='router.ram.size'; -UPDATE `cloud`.`configuration` set category='Hidden ' where name='secondary.storage.vm'; -UPDATE `cloud`.`configuration` set category='Hidden ' where name='security.hash.key'; +UPDATE `cloud`.`configuration` set category='Advanced' where name='capacity.skipcounting.hours'; +UPDATE `cloud`.`configuration` set category='Advanced' where name='use.local.storage'; UPDATE `cloud`.`configuration` set description = 'Percentage (as a value between 0 and 1) of local storage utilization above which alerts will be sent about low local storage available.' where name = 'cluster.localStorage.capacity.notificationthreshold'; DELETE FROM `cloud`.`configuration` WHERE name='direct.agent.pool.size'; @@ -123,6 +120,7 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'vmware.use.nexus.vswitch', 'false', 'Enable/Disable Cisco Nexus 1000v vSwitch in VMware environment'); ALTER TABLE `cloud`.`account` ADD COLUMN `default_zone_id` bigint unsigned; ALTER TABLE `cloud`.`account` ADD CONSTRAINT `fk_account__default_zone_id` FOREIGN KEY `fk_account__default_zone_id`(`default_zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE; +ALTER TABLE `cloud_usage`.`account` ADD COLUMN `default_zone_id` bigint unsigned; DROP TABLE IF EXISTS `cloud`.`cluster_vsm_map`; DROP TABLE IF EXISTS `cloud`.`virtual_supervisor_module`; diff --git a/test/integration/component/test_high_availability.py b/test/integration/component/test_high_availability.py index 10281615cc3..02463f0e0b8 100644 --- a/test/integration/component/test_high_availability.py +++ b/test/integration/component/test_high_availability.py @@ -21,7 +21,7 @@ from marvin.cloudstackAPI import * from integration.lib.utils import * from integration.lib.base import * from integration.lib.common import * -from marvin.remoteSSHClient import remoteSSHClient +from marvin import remoteSSHClient import datetime @@ -80,7 +80,7 @@ class Services: "templates": { "displaytext": "Public Template", "name": "Public template", - "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f', + "ostypeid": '1d4a6dce-8db1-4c08-8752-e88b360d8287', "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", "hypervisor": 'XenServer', "format" : 'VHD', @@ -89,7 +89,7 @@ class Services: "isextractable": True, "templatefilter": 'self', }, - "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f', + "ostypeid": '1d4a6dce-8db1-4c08-8752-e88b360d8287', # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 100, @@ -198,7 +198,7 @@ class TestHighAvailability(cloudstackTestCase): True, "List hosts should return valid host response" ) - self.assertEqual( + self.assertGreaterEqual( len(hosts), 2, "There must be two hosts present in a cluster" @@ -277,15 +277,6 @@ class TestHighAvailability(cloudstackTestCase): self.debug("Creating LB rule on IP with NAT: %s" % public_ip.ipaddress.ipaddress) - # Open up firewall port for SSH - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol=self.services["natrule"]["protocol"], - cidrlist=['0.0.0.0/0'], - startport=self.services["natrule"]["publicport"], - endport=self.services["natrule"]["publicport"] - ) # Create Load Balancer rule on IP already having NAT rule lb_rule = LoadBalancerRule.create( self.apiclient, @@ -600,7 +591,7 @@ class TestHighAvailability(cloudstackTestCase): True, "List hosts should return valid host response" ) - self.assertEqual( + self.assertGreaterEqual( len(hosts), 2, "There must be two hosts present in a cluster" @@ -676,16 +667,6 @@ class TestHighAvailability(cloudstackTestCase): ipaddressid=public_ip.ipaddress.id ) - # Open up firewall port for SSH - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol=self.services["natrule"]["protocol"], - cidrlist=['0.0.0.0/0'], - startport=self.services["natrule"]["publicport"], - endport=self.services["natrule"]["publicport"] - ) - self.debug("Creating LB rule on IP with NAT: %s" % public_ip.ipaddress.ipaddress) diff --git a/test/integration/component/test_netscaler_configs.py b/test/integration/component/test_netscaler_configs.py index a76a19b8b2e..99f356a8ee9 100644 --- a/test/integration/component/test_netscaler_configs.py +++ b/test/integration/component/test_netscaler_configs.py @@ -63,12 +63,23 @@ class Services: "password": 'nsroot', "networkdevicetype": 'NetscalerVPXLoadBalancer', "publicinterface": '1/1', - "privateinterface": '0/1', + "privateinterface": '1/1', "numretries": 2, "lbdevicededicated": False, "lbdevicecapacity": 50, "port": 22, }, + "netscaler_dedicated": { + "ipaddress": '192.168.100.213', + "username": 'nsroot', + "password": 'nsroot', + "networkdevicetype": 'NetscalerVPXLoadBalancer', + "publicinterface": '1/1', + "privateinterface": '1/1', + "numretries": 2, + "lbdevicededicated": True, + "port": 22, + }, "network_offering_dedicated": { "name": 'Netscaler', "displaytext": 'Netscaler', @@ -262,6 +273,7 @@ class TestAddNetScaler(cloudstackTestCase): return + class TestInvalidParametersNetscaler(cloudstackTestCase): @classmethod @@ -502,7 +514,7 @@ class TestInvalidParametersNetscaler(cloudstackTestCase): ) return -@unittest.skip("Issue- Unable to validate user credentials while creating nw offering") + class TestNetScalerDedicated(cloudstackTestCase): @classmethod @@ -528,10 +540,9 @@ class TestNetScalerDedicated(cloudstackTestCase): if isinstance(physical_networks, list): physical_network = physical_networks[0] - cls.services["netscaler"]["lbdevicededicated"] = True cls.netscaler = NetScaler.add( cls.api_client, - cls.services["netscaler"], + cls.services["netscaler_dedicated"], physicalnetworkid=physical_network.id ) @@ -702,8 +713,8 @@ class TestNetScalerDedicated(cloudstackTestCase): # Creating network using the network offering created self.debug("Trying to create network with network offering: %s" % self.network_offering.id) - with self.assertRaises(Exception): - Network.create( + + Network.create( self.apiclient, self.services["network"], accountid=self.account_2.account.name, @@ -711,9 +722,21 @@ class TestNetScalerDedicated(cloudstackTestCase): networkofferingid=self.network_offering.id, zoneid=self.zone.id ) + self.debug("Deploying an instance in account: %s" % self.account_2.account.name) + with self.assertRaises(Exception): + VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deply instacne in dedicated Network offering mode failed") return + class TestNetScalerShared(cloudstackTestCase): @classmethod @@ -827,12 +850,12 @@ class TestNetScalerShared(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return - def test_netscaler_dedicated_mode(self): - """Test netscaler device in dedicated mode + def test_netscaler_shared_mode(self): + """Test netscaler device in shared mode """ # Validate the following - # 1. Add Netscaler device in dedicated mode. + # 1. Add Netscaler device in shared mode. # 2. Netscaler should be configured successfully.It should be able to # service only 1 account. @@ -955,6 +978,7 @@ class TestNetScalerShared(cloudstackTestCase): return + class TestNetScalerCustomCapacity(cloudstackTestCase): @classmethod @@ -1074,14 +1098,14 @@ class TestNetScalerCustomCapacity(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return - def test_netscaler_dedicated_mode(self): - """Test netscaler device in dedicated mode + def test_netscaler_custom_capacity(self): + """Test netscaler device with custom capacity """ # Validate the following - # 1. Add Netscaler device in dedicated mode. + # 1. Add Netscaler device in shared mode with capacity 3 # 2. Netscaler should be configured successfully.It should be able to - # service only 1 account. + # service only 3 accounts. ns_list = NetScaler.list( self.apiclient, @@ -1226,6 +1250,7 @@ class TestNetScalerCustomCapacity(cloudstackTestCase): return + class TestNetScalerNoCapacity(cloudstackTestCase): @classmethod @@ -1250,7 +1275,7 @@ class TestNetScalerNoCapacity(cloudstackTestCase): ) if isinstance(physical_networks, list): physical_network = physical_networks[0] - + cls.services["netscaler"]["lbdevicecapacity"] = 2 cls.netscaler = NetScaler.add( cls.api_client, cls.services["netscaler"], @@ -1345,14 +1370,15 @@ class TestNetScalerNoCapacity(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return - def test_netscaler_dedicated_mode(self): - """Test netscaler device in dedicated mode + def test_netscaler_no_capacity(self): + """Test netscaler device with no capacity remaining """ # Validate the following - # 1. Add Netscaler device in dedicated mode. + # 1. Add Netscaler device in shared mode with capacity 2 # 2. Netscaler should be configured successfully.It should be able to - # service only 1 account. + # service only 2 accounts. + # 3. Deploy instance for account 3 should fail ns_list = NetScaler.list( self.apiclient, @@ -1497,6 +1523,7 @@ class TestNetScalerNoCapacity(cloudstackTestCase): return + class TestGuestNetworkWithNetScaler(cloudstackTestCase): @classmethod @@ -2049,6 +2076,7 @@ class TestGuestNetworkWithNetScaler(cloudstackTestCase): return + class TestGuestNetworkShutDown(cloudstackTestCase): @classmethod @@ -2209,7 +2237,7 @@ class TestGuestNetworkShutDown(cloudstackTestCase): name='network.gc.wait' ) # Sleep to ensure that all resources are deleted - time.sleep((int(interval[0].value) + int(wait[0].value))*2) + time.sleep((int(interval[0].value) + int(wait[0].value)) * 2) self.debug("SSH into netscaler: %s" % self.services["netscaler"]["ipaddress"]) @@ -2459,6 +2487,7 @@ class TestGuestNetworkShutDown(cloudstackTestCase): return + class TestServiceProvider(cloudstackTestCase): @classmethod @@ -2750,8 +2779,15 @@ class TestServiceProvider(cloudstackTestCase): id=self.netscaler_provider.id, state='Disabled' ) - self.debug("Deploying VM in the network: %s" % self.network.id) with self.assertRaises(Exception): + self.debug("Deploying VM in the network: %s" % self.network.id) + LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip.ipaddress.id, + accountid=self.account.account.name, + networkid=self.network.id + ) VirtualMachine.create( self.apiclient, self.services["virtual_machine"], @@ -2763,6 +2799,7 @@ class TestServiceProvider(cloudstackTestCase): return + class TestDeleteNetscaler(cloudstackTestCase): @classmethod diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py index 6b1e517df98..59ac84f3f69 100644 --- a/test/integration/component/test_netscaler_lb.py +++ b/test/integration/component/test_netscaler_lb.py @@ -1571,7 +1571,6 @@ class TestMultipleLbRules(cloudstackTestCase): return - class TestMultipleLbRulesSameIp(cloudstackTestCase): @classmethod diff --git a/test/integration/component/test_netscaler_lb_algo.py b/test/integration/component/test_netscaler_lb_algo.py index 7248405001b..bcff75fb4a9 100644 --- a/test/integration/component/test_netscaler_lb_algo.py +++ b/test/integration/component/test_netscaler_lb_algo.py @@ -58,7 +58,7 @@ class Services: "protocol": 'TCP', }, "netscaler": { - "ipaddress": '10.147.40.100', + "ipaddress": '192.168.100.213', "username": 'nsroot', "password": 'nsroot', "networkdevicetype": 'NetscalerVPXLoadBalancer', @@ -67,35 +67,7 @@ class Services: "numretries": 2, "lbdevicededicated": False, "lbdevicecapacity": 50, - }, - "network_offering_dedicated": { - "name": 'Netscaler', - "displaytext": 'Netscaler', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "specifyVlan": False, - "specifyIpRanges": False, - "serviceProviderList" : { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'Netscaler', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - "servicecapabilitylist": { - "SourceNat": { - "SupportedSourceNatTypes": "peraccount" - }, - "lb": { - "SupportedLbIsolation": "dedicated" - }, - }, + "port": 22, }, "network_offering": { "name": 'Netscaler', @@ -128,12 +100,7 @@ class Services: "publicport": 22, "openfirewall": False, }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "ostypeid": '2b58909b-7d9e-45d9-80d8-e58d0bbcbf07', + "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f', # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, @@ -166,6 +133,7 @@ class TestLbWithRoundRobin(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id @@ -174,8 +142,8 @@ class TestLbWithRoundRobin(cloudstackTestCase): cls.services["service_offering"] ) cls._cleanup = [ - cls.service_offering, cls.network_offering, + cls.service_offering ] return @@ -248,7 +216,7 @@ class TestLbWithRoundRobin(cloudstackTestCase): self.debug("Deploying VM in account: %s" % self.account.account.name) # Spawn an instance in that network - virtual_machine_1 = VirtualMachine.create( + self.virtual_machine = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account.account.name, @@ -259,12 +227,12 @@ class TestLbWithRoundRobin(cloudstackTestCase): self.debug("Deployed VM in network: %s" % self.network.id) list_vm_response = VirtualMachine.list( self.apiclient, - id=virtual_machine_1.id + id=self.virtual_machine.id ) self.debug( "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_1.id + % self.virtual_machine.id ) self.assertEqual( @@ -280,41 +248,6 @@ class TestLbWithRoundRobin(cloudstackTestCase): "VM state should be running after deployment" ) - self.debug("Deploying another VM in account: %s" % - self.account.account.name) - - # Spawn an instance in that network - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_2.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) self.debug("Associating public IP for network: %s" % self.network.id) ip_with_lb_rule = PublicIPAddress.create( @@ -341,9 +274,6 @@ class TestLbWithRoundRobin(cloudstackTestCase): networkid=self.network.id ) - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - lb_rules = LoadBalancerRule.list( self.apiclient, id=lb_rule.id, @@ -354,60 +284,39 @@ class TestLbWithRoundRobin(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) - self.debug("Adding %s, %s to the LB rule %s" % ( - virtual_machine_1.name, - virtual_machine_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine_1, virtual_machine_2]) - - try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress) - self.debug("Command: hostname") - result = ssh.execute("hostname") + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) + try: + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( + ip_with_lb_rule.ipaddress.ipaddress, + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) self.debug("Output: %s" % result) - hostnames.append(result) - - ssh = virtual_machine_2.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.assertNotEqual( - hostnames[0], - hostnames[1], - "Hostnames must not be same if round robin algo is used" - ) - - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) self.assertEqual( - hostnames[0], - hostnames[2], - "Alternate Hostnames must be same if roundrobin algo is used" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( - ip_with_lb_rule.ipaddress.ipaddress, - e)) - return + result.count("Configured Method: ROUNDROBIN"), + 1, + "'ROUNDROBIN' algorithm should be configured on NS" + ) + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + return class TestLbWithLeastConn(cloudstackTestCase): @@ -435,6 +344,7 @@ class TestLbWithLeastConn(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id @@ -442,9 +352,10 @@ class TestLbWithLeastConn(cloudstackTestCase): cls.api_client, cls.services["service_offering"] ) + cls._cleanup = [ - cls.service_offering, cls.network_offering, + cls.service_offering ] return @@ -517,7 +428,7 @@ class TestLbWithLeastConn(cloudstackTestCase): self.debug("Deploying VM in account: %s" % self.account.account.name) # Spawn an instance in that network - virtual_machine_1 = VirtualMachine.create( + self.virtual_machine = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account.account.name, @@ -528,12 +439,12 @@ class TestLbWithLeastConn(cloudstackTestCase): self.debug("Deployed VM in network: %s" % self.network.id) list_vm_response = VirtualMachine.list( self.apiclient, - id=virtual_machine_1.id + id=self.virtual_machine.id ) self.debug( "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_1.id + % self.virtual_machine.id ) self.assertEqual( @@ -549,43 +460,15 @@ class TestLbWithLeastConn(cloudstackTestCase): "VM state should be running after deployment" ) - self.debug("Deploying another VM in account: %s" % - self.account.account.name) - - # Spawn an instance in that network - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_2.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) self.debug("Associating public IP for network: %s" % self.network.id) + PublicIPAddress.create( + self.apiclient, + accountid=self.account.account.name, + zoneid=self.zone.id, + domainid=self.account.account.domainid, + networkid=self.network.id + ) ip_with_lb_rule = PublicIPAddress.create( self.apiclient, accountid=self.account.account.name, @@ -610,9 +493,6 @@ class TestLbWithLeastConn(cloudstackTestCase): networkid=self.network.id ) - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - lb_rules = LoadBalancerRule.list( self.apiclient, id=lb_rule.id, @@ -624,60 +504,42 @@ class TestLbWithLeastConn(cloudstackTestCase): "List LB rules should return a newly created LB rule" ) self.debug("Adding %s to the LB rule %s" % ( - virtual_machine_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine_1]) - self.debug("Creating a firewall rule to open up SSH ports..") + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine_2]) - - ssh = virtual_machine_2.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - self.assertNotEqual( - res.count(virtual_machine_2.name), - 1, - "SSH request should go to second VM(having least connections)" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( ip_with_lb_rule.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: LEASTCONNECTION"), + 1, + "'LEASTCONNECTION' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbWithSourceIp(cloudstackTestCase): @classmethod @@ -711,8 +573,8 @@ class TestLbWithSourceIp(cloudstackTestCase): cls.services["service_offering"] ) cls._cleanup = [ - cls.service_offering, cls.network_offering, + cls.service_offering ] return @@ -785,7 +647,7 @@ class TestLbWithSourceIp(cloudstackTestCase): self.debug("Deploying VM in account: %s" % self.account.account.name) # Spawn an instance in that network - virtual_machine_1 = VirtualMachine.create( + self.virtual_machine = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account.account.name, @@ -796,12 +658,12 @@ class TestLbWithSourceIp(cloudstackTestCase): self.debug("Deployed VM in network: %s" % self.network.id) list_vm_response = VirtualMachine.list( self.apiclient, - id=virtual_machine_1.id + id=self.virtual_machine.id ) self.debug( "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_1.id + % self.virtual_machine.id ) self.assertEqual( @@ -817,41 +679,6 @@ class TestLbWithSourceIp(cloudstackTestCase): "VM state should be running after deployment" ) - self.debug("Deploying another VM in account: %s" % - self.account.account.name) - - # Spawn an instance in that network - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % virtual_machine_2.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) self.debug("Associating public IP for network: %s" % self.network.id) ip_with_lb_rule = PublicIPAddress.create( @@ -878,9 +705,6 @@ class TestLbWithSourceIp(cloudstackTestCase): networkid=self.network.id ) - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - lb_rules = LoadBalancerRule.list( self.apiclient, id=lb_rule.id, @@ -891,76 +715,43 @@ class TestLbWithSourceIp(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) + self.debug("Adding %s to the LB rule %s" % ( - virtual_machine_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine_1]) - + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - res = str(result) - - self.assertEqual( - res.count(virtual_machine_1.name), - 1, - "Request should be sent only to the first VM" - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine_2]) - - ssh = virtual_machine_1.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - res = str(result) - - self.assertEqual( - res.count(virtual_machine_1.name), - 1, - "Request should be sent only to the first VM" - ) - - ssh = virtual_machine_2.get_ssh_client( - ipaddress=ip_with_lb_rule.ipaddress.ipaddress - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - - self.assertEqual( - res.count(virtual_machine_1.name), - 1, - "Request should be sent only to the first VM" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( ip_with_lb_rule.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: SOURCEIPHASH"), + 1, + "'SOURCEIPHASH' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoRrLc(cloudstackTestCase): @classmethod @@ -985,13 +776,6 @@ class TestLbAlgoRrLc(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -1006,17 +790,16 @@ class TestLbAlgoRrLc(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -1032,8 +815,8 @@ class TestLbAlgoRrLc(cloudstackTestCase): networkid=cls.network.id ) cls._cleanup = [ - cls.service_offering, - cls.account + cls.account, + cls.service_offering ] return @@ -1100,8 +883,6 @@ class TestLbAlgoRrLc(cloudstackTestCase): networkid=self.network.id ) self.cleanup.append(lb_rule) - self.debug("Trying to create PF rule on IP with LB rule: %s" % - self.public_ip.ipaddress.ipaddress) lb_rules = LoadBalancerRule.list( self.apiclient, @@ -1113,119 +894,76 @@ class TestLbAlgoRrLc(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) - self.debug("Adding %s, %s to the LB rule %s" % ( - self.vm_1.name, - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2]) + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the roundrobin algo used by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( + self.public_ip.ipaddress.ipaddress, + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_2 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.assertNotEqual( - hostnames[0], - hostnames[1], - "Hostnames must not be same if round robin algo is used" - ) - - ssh_3 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) self.assertEqual( - hostnames[0], - hostnames[2], - "Alternate Hostnames must be same if roundrobin algo is used" - ) + result.count("Configured Method: ROUNDROBIN"), + 1, + "'ROUNDROBIN' algorithm should be configured on NS" + ) except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( - self.public_ip.ipaddress.ipaddress, - e)) + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'leastconn')) lb_rule.update(self.apiclient, algorithm='leastconn') - self.debug( - "Removing virtual machine: %s to test least connection algo" % - self.vm_2.name) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_4 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_5 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - self.assertNotEqual( - res.count(self.vm_2.name), - 1, - "SSH request should go to second VM(having least connections)" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: LEASTCONNECTION"), + 1, + "'LEASTCONNECTION' algorithm should be configured on NS" + ) + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoLcRr(cloudstackTestCase): @classmethod @@ -1250,13 +988,6 @@ class TestLbAlgoLcRr(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -1271,17 +1002,16 @@ class TestLbAlgoLcRr(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -1297,8 +1027,8 @@ class TestLbAlgoLcRr(cloudstackTestCase): networkid=cls.network.id ) cls._cleanup = [ - cls.service_offering, - cls.account + cls.account, + cls.service_offering ] return @@ -1377,113 +1107,72 @@ class TestLbAlgoLcRr(cloudstackTestCase): "List LB rules should return a newly created LB rule" ) self.debug("Adding %s to the LB rule %s" % ( - self.vm_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1]) - + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the leastconn algo used by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_2 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_3 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - self.assertNotEqual( - res.count(self.vm_2.name), - 1, - "SSH request should go to second VM(having least connections)" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: LEASTCONNECTION"), + 1, + "'LEASTCONNECTION' algorithm should be configured on NS" + ) + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'roundrobin')) lb_rule.update(self.apiclient, algorithm='roundrobin') + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the roundrobin algo used by SSHing into instances") - hostnames = [] - ssh_4 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( + self.public_ip.ipaddress.ipaddress, + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_5 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.assertNotEqual( - hostnames[0], - hostnames[1], - "Hostnames must not be same if round robin algo is used" - ) - - ssh_6 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_6.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) self.assertEqual( - hostnames[0], - hostnames[2], - "Alternate Hostnames must be same if roundrobin algo is used" - ) + result.count("Configured Method: ROUNDROBIN"), + 1, + "'ROUNDROBIN' algorithm should be configured on NS" + ) except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( - self.public_ip.ipaddress.ipaddress, - e)) + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoRrSb(cloudstackTestCase): @classmethod @@ -1508,13 +1197,6 @@ class TestLbAlgoRrSb(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -1529,17 +1211,16 @@ class TestLbAlgoRrSb(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -1547,6 +1228,7 @@ class TestLbAlgoRrSb(cloudstackTestCase): serviceofferingid=cls.service_offering.id, networkids=[str(cls.network.id)] ) + cls.public_ip = PublicIPAddress.create( cls.api_client, accountid=cls.account.account.name, @@ -1555,8 +1237,8 @@ class TestLbAlgoRrSb(cloudstackTestCase): networkid=cls.network.id ) cls._cleanup = [ - cls.service_offering, - cls.account + cls.account, + cls.service_offering ] return @@ -1623,8 +1305,6 @@ class TestLbAlgoRrSb(cloudstackTestCase): networkid=self.network.id ) self.cleanup.append(lb_rule) - self.debug("Trying to create PF rule on IP with LB rule: %s" % - self.public_ip.ipaddress.ipaddress) lb_rules = LoadBalancerRule.list( self.apiclient, @@ -1636,135 +1316,75 @@ class TestLbAlgoRrSb(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) - self.debug("Adding %s, %s to the LB rule %s" % ( - self.vm_1.name, - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2]) - + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the roundrobin algo used by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( + self.public_ip.ipaddress.ipaddress, + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_2 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.assertNotEqual( - hostnames[0], - hostnames[1], - "Hostnames must not be same if round robin algo is used" - ) - - ssh_3 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) self.assertEqual( - hostnames[0], - hostnames[2], - "Alternate Hostnames must be same if roundrobin algo is used" - ) + result.count("Configured Method: ROUNDROBIN"), + 1, + "'ROUNDROBIN' algorithm should be configured on NS" + ) except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( - self.public_ip.ipaddress.ipaddress, - e)) + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'source')) lb_rule.update(self.apiclient, algorithm='source') - self.debug( - "Removing virtual machine: %s to test source algo" % - self.vm_2.name) - lb_rule.remove(self.apiclient, [self.vm_2]) - + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_4 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_5 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - ssh_6 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_6.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: SOURCEIPHASH"), + 1, + "'SOURCEIPHASH' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoSbRr(cloudstackTestCase): @classmethod @@ -1789,13 +1409,7 @@ class TestLbAlgoSbRr(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -1810,17 +1424,16 @@ class TestLbAlgoSbRr(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -1828,6 +1441,7 @@ class TestLbAlgoSbRr(cloudstackTestCase): serviceofferingid=cls.service_offering.id, networkids=[str(cls.network.id)] ) + cls.public_ip = PublicIPAddress.create( cls.api_client, accountid=cls.account.account.name, @@ -1836,7 +1450,6 @@ class TestLbAlgoSbRr(cloudstackTestCase): networkid=cls.network.id ) cls._cleanup = [ - cls.service_offering, cls.account ] return @@ -1915,132 +1528,77 @@ class TestLbAlgoSbRr(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) + self.debug("Adding %s to the LB rule %s" % ( - self.vm_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1]) + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_2 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - ssh_3 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: SOURCEIPHASH"), + 1, + "'SOURCEIPHASH' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'roundrobin')) lb_rule.update(self.apiclient, algorithm='roundrobin') + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the roundrobin algo used by SSHing into instances") - hostnames = [] - ssh = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh.execute("hostname") + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( + self.public_ip.ipaddress.ipaddress, + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_4 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.assertNotEqual( - hostnames[0], - hostnames[1], - "Hostnames must not be same if round robin algo is used" - ) - - ssh_5 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) self.assertEqual( - hostnames[0], - hostnames[2], - "Alternate Hostnames must be same if roundrobin algo is used" - ) + result.count("Configured Method: ROUNDROBIN"), + 1, + "'ROUNDROBIN' algorithm should be configured on NS" + ) except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( - self.public_ip.ipaddress.ipaddress, - e)) + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoSbLc(cloudstackTestCase): @classmethod @@ -2065,13 +1623,7 @@ class TestLbAlgoSbLc(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -2086,17 +1638,16 @@ class TestLbAlgoSbLc(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -2104,6 +1655,7 @@ class TestLbAlgoSbLc(cloudstackTestCase): serviceofferingid=cls.service_offering.id, networkids=[str(cls.network.id)] ) + cls.public_ip = PublicIPAddress.create( cls.api_client, accountid=cls.account.account.name, @@ -2191,136 +1743,76 @@ class TestLbAlgoSbLc(cloudstackTestCase): True, "List LB rules should return a newly created LB rule" ) + self.debug("Adding %s to the LB rule %s" % ( - self.vm_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1]) + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_2 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - ssh_3 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: SOURCEIPHASH"), + 1, + "'SOURCEIPHASH' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'leastconn')) lb_rule.update(self.apiclient, algorithm='leastconn') - self.debug( - "Removing virtual machine: %s to test least connection algo" % - self.vm_2.name) - lb_rule.remove(self.apiclient, [self.vm_2]) + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_4 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_5 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_6 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_6.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - self.assertNotEqual( - res.count(self.vm_2.name), - 1, - "SSH request should go to second VM(having least connections)" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: LEASTCONNECTION"), + 1, + "'LEASTCONNECTION' algorithm should be configured on NS" + ) + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return + class TestLbAlgoLcSb(cloudstackTestCase): @classmethod @@ -2345,13 +1837,7 @@ class TestLbAlgoLcSb(cloudstackTestCase): ) # Enable Network offering cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) cls.account = Account.create( cls.api_client, cls.services["account"], @@ -2366,17 +1852,16 @@ class TestLbAlgoLcSb(cloudstackTestCase): networkofferingid=cls.network_offering.id, zoneid=cls.zone.id ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - networkids=[str(cls.network.id)] - ) - cls.vm_2 = VirtualMachine.create( + cls.virtual_machine = VirtualMachine.create( cls.api_client, cls.services["virtual_machine"], accountid=cls.account.account.name, @@ -2392,8 +1877,8 @@ class TestLbAlgoLcSb(cloudstackTestCase): networkid=cls.network.id ) cls._cleanup = [ - cls.service_offering, - cls.account + cls.account, + cls.service_offering ] return @@ -2472,130 +1957,69 @@ class TestLbAlgoLcSb(cloudstackTestCase): "List LB rules should return a newly created LB rule" ) self.debug("Adding %s to the LB rule %s" % ( - self.vm_1.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_1]) - + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_1 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_1.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - ssh_2 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_2.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_3 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_3.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - self.assertNotEqual( - res.count(self.vm_2.name), - 1, - "SSH request should go to second VM(having least connections)" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: LEASTCONNECTION"), + 1, + "'LEASTCONNECTION' algorithm should be configured on NS" + ) + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) + self.debug( "Updating LB rule: %s with new algorithm: %s" % ( lb_rule.name, 'source')) lb_rule.update(self.apiclient, algorithm='source') - self.debug( - "Removing virtual machine: %s to test source algo" % - self.vm_2.name) - lb_rule.remove(self.apiclient, [self.vm_2]) - + self.debug("SSH into Netscaler to check whether algorithm is configured properly or not?") + self.debug("SSH into netscaler: %s" % + self.services["netscaler"]["ipaddress"]) try: - self.debug( - "Verifying the algorithm used for LB by SSHing into instances") - hostnames = [] - ssh_4 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress) - self.debug("Command: hostname") - result = ssh_4.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - self.debug("Adding %s to the LB rule %s" % ( - self.vm_2.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [self.vm_2]) - - ssh_5 = self.vm_1.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_5.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - self.debug("Hostnames: %s" % str(hostnames)) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - - ssh_6 = self.vm_2.get_ssh_client( - ipaddress=self.public_ip.ipaddress.ipaddress, - reconnect=True - ) - self.debug("Command: hostname") - result = ssh_6.execute("hostname") - self.debug("Output: %s" % result) - hostnames.append(result) - - res = str(result) - - self.assertEqual( - res.count(self.vm_1.name), - 1, - "Request should be sent only to the first VM" - ) - except Exception as e: - self.fail("Exception occured during SSH: %s - %s" % ( + ssh_client = remoteSSHClient( + self.services["netscaler"]["ipaddress"], + self.services["netscaler"]["port"], + self.services["netscaler"]["username"], + self.services["netscaler"]["password"], + ) + cmd = "show lb vserver Cloud-VirtualServer-%s-%s" % ( self.public_ip.ipaddress.ipaddress, - e)) + lb_rule.publicport) + self.debug("command: %s" % cmd) + res = ssh_client.execute(cmd) + result = str(res) + self.debug("Output: %s" % result) + + self.assertEqual( + result.count("Configured Method: SOURCEIPHASH"), + 1, + "'SOURCEIPHASH' algorithm should be configured on NS" + ) + + except Exception as e: + self.fail("SSH Access failed for %s: %s" % \ + (self.services["netscaler"]["ipaddress"], e)) return diff --git a/test/integration/component/test_netscaler_lb_sticky.py b/test/integration/component/test_netscaler_lb_sticky.py index 75647951c8c..47f5cd1743d 100644 --- a/test/integration/component/test_netscaler_lb_sticky.py +++ b/test/integration/component/test_netscaler_lb_sticky.py @@ -58,7 +58,7 @@ class Services: "protocol": 'TCP', }, "netscaler": { - "ipaddress": '10.147.40.100', + "ipaddress": '192.168.100.213', "username": 'nsroot', "password": 'nsroot', "networkdevicetype": 'NetscalerVPXLoadBalancer', @@ -100,7 +100,7 @@ class Services: "publicport": 22, "openfirewall": False, }, - "ostypeid": '2b58909b-7d9e-45d9-80d8-e58d0bbcbf07', + "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f', # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, diff --git a/test/integration/component/test_netscaler_nw_off.py b/test/integration/component/test_netscaler_nw_off.py new file mode 100644 index 00000000000..d130ed540fa --- /dev/null +++ b/test/integration/component/test_netscaler_nw_off.py @@ -0,0 +1,2346 @@ +# -*- encoding: utf-8 -*- +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +""" P1 tests for multiple netscaler instances +""" +#Import Local Modules +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * +from marvin.remoteSSHClient import remoteSSHClient +import datetime + + +class Services: + """Test netscaler Services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "fr3sca", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "virtual_machine": { + "displayname": "TestVM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "netscaler_1": { + "ipaddress": '192.168.100.213', + "username": 'nsroot', + "password": 'nsroot', + "networkdevicetype": 'NetscalerVPXLoadBalancer', + "publicinterface": '1/1', + "privateinterface": '1/1', + "numretries": 2, + "lbdevicededicated": False, + "lbdevicecapacity": 50, + "port": 22, + }, + "netscaler_2": { + "ipaddress": '192.168.100.100', + "username": 'nsroot', + "password": 'nsroot', + "networkdevicetype": 'NetscalerVPXLoadBalancer', + "publicinterface": '1/1', + "privateinterface": '1/1', + "numretries": 2, + "lbdevicededicated": False, + "lbdevicecapacity": 50, + "port": 22, + }, + "netscaler_3": { + "ipaddress": '192.168.100.101', + "username": 'nsroot', + "password": 'nsroot', + "networkdevicetype": 'NetscalerVPXLoadBalancer', + "publicinterface": '1/1', + "privateinterface": '1/1', + "numretries": 2, + "lbdevicededicated": False, + "lbdevicecapacity": 50, + "port": 22, + }, + "network_offering_dedicated": { + "name": 'Netscaler', + "displaytext": 'Netscaler', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "specifyVlan": False, + "specifyIpRanges": False, + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'Netscaler', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "servicecapabilitylist": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount" + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "network_offering": { + "name": 'Netscaler', + "displaytext": 'Netscaler', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList" : { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'Netscaler', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + }, + "network": { + "name": "Netscaler", + "displaytext": "Netscaler", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": False, + }, + "ostypeid": '946b031b-0e10-4f4a-a3fc-d212ae2ea07f', + # Cent OS 5.3 (64 bit) + "sleep": 60, + "timeout": 10, + "mode":'advanced' + } + + + +class TestAddMultipleNetScaler(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestAddMultipleNetScaler, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls._cleanup = [] + 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: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_add_netscaler_device(self): + """Test add netscaler device + """ + + # Validate the following + # 1. Add multiple instances of netscaler + # 2. Netscaler should be configured successfully. + + physical_networks = PhysicalNetwork.list( + self.apiclient, + zoneid=self.zone.id + ) + self.assertEqual( + isinstance(physical_networks, list), + True, + "There should be atleast one physical network for advanced zone" + ) + physical_network = physical_networks[0] + self.debug("Adding netscaler device: %s" % + self.services["netscaler_1"]["ipaddress"]) + netscaler_1 = NetScaler.add( + self.apiclient, + self.services["netscaler_1"], + physicalnetworkid=physical_network.id + ) + self.cleanup.append(netscaler_1) + self.debug("Checking if Netscaler network service provider is enabled?") + + nw_service_providers = NetworkServiceProvider.list( + self.apiclient, + name='Netscaler', + physicalnetworkid=physical_network.id + ) + self.assertEqual( + isinstance(nw_service_providers, list), + True, + "Network service providers list should not be empty" + ) + netscaler_provider = nw_service_providers[0] + if netscaler_provider.state != 'Enabled': + self.debug("Netscaler provider is not enabled. Enabling it..") + response = NetworkServiceProvider.update( + self.apiclient, + id=netscaler_provider.id, + state='Enabled' + ) + self.assertEqual( + response.state, + "Enabled", + "Network service provider should be in enabled state" + ) + else: + self.debug("Netscaler service provider is already enabled.") + + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=netscaler_1.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + self.assertEqual( + ns.physicalnetworkid, + physical_network.id, + "Physical network id should match with the network in which device is configured" + ) + + self.debug("Adding netscaler device: %s" % + self.services["netscaler_2"]["ipaddress"]) + netscaler_2 = NetScaler.add( + self.apiclient, + self.services["netscaler_2"], + physicalnetworkid=physical_network.id + ) + self.cleanup.append(netscaler_2) + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=netscaler_1.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + self.assertEqual( + ns.physicalnetworkid, + physical_network.id, + "Physical network id should match with the network in which device is configured" + ) + self.debug("Another Netscaler device is added!") + return + + +class TestAddMultipleNSDiffZone(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestAddMultipleNSDiffZone, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + cls._cleanup = [] + 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: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_add_mul_netscaler_diff_zone(self): + """Test add netscaler devices in different zones + """ + + # Validate the following + # 1. Add multiple instances of Netscaler in different zones + # 2. Netscaler should be configured successfully. + + # Check if there are multiple zones present in the given setup + zones = Zone.list(self.apiclient, listall=True) + self.assertEqual( + isinstance(zones, list), + True, + "List Zones API should return a valid list" + ) + + # Find the number of zones configured in advanced mode + zone_list = [] + for zone in zones: + if zone.networktype == 'Advanced': + zone_list.append(zone) + + self.assertGreater( + len(zone_list), + 1, + "Atleast 2 advanced mode zones should be present for this test" + ) + + physical_networks = PhysicalNetwork.list( + self.apiclient, + zoneid=zone_list[0].id + ) + self.assertEqual( + isinstance(physical_networks, list), + True, + "There should be atleast one physical network for advanced zone" + ) + physical_network = physical_networks[0] + self.debug("Adding netscaler device: %s" % + self.services["netscaler_1"]["ipaddress"]) + netscaler = NetScaler.add( + self.apiclient, + self.services["netscaler_1"], + physicalnetworkid=physical_network.id + ) + self.cleanup.append(netscaler_1) + self.debug("Checking if Netscaler network service provider is enabled?") + + nw_service_providers = NetworkServiceProvider.list( + self.apiclient, + name='Netscaler', + physicalnetworkid=physical_network.id + ) + self.assertEqual( + isinstance(nw_service_providers, list), + True, + "Network service providers list should not be empty" + ) + netscaler_provider = nw_service_providers[0] + if netscaler_provider.state != 'Enabled': + self.debug("Netscaler provider is not enabled. Enabling it..") + response = NetworkServiceProvider.update( + self.apiclient, + id=netscaler_provider.id, + state='Enabled' + ) + self.assertEqual( + response.state, + "Enabled", + "Network service provider should be in enabled state" + ) + else: + self.debug("Netscaler service provider is already enabled.") + + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=netscaler_1.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + self.assertEqual( + ns.physicalnetworkid, + physical_network.id, + "Physical network id should match with the network in which device is configured" + ) + + physical_networks = PhysicalNetwork.list( + self.apiclient, + zoneid=zone_list[1].id + ) + self.assertEqual( + isinstance(physical_networks, list), + True, + "There should be atleast one physical network for advanced zone" + ) + physical_network = physical_networks[0] + + self.debug("Adding netscaler device: %s" % + self.services["netscaler_2"]["ipaddress"]) + netscaler_2 = NetScaler.add( + self.apiclient, + self.services["netscaler_2"], + physicalnetworkid=physical_network.id + ) + self.cleanup.append(netscaler_2) + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=netscaler_2.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + self.assertEqual( + ns.physicalnetworkid, + physical_network.id, + "Physical network id should match with the network in which device is configured" + ) + self.debug("Another Netscaler device is added!") + return + + +class TestNetScalerSharedMode(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestNetScalerSharedMode, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + physical_networks = PhysicalNetwork.list( + cls.api_client, + zoneid=cls.zone.id + ) + if isinstance(physical_networks, list): + cls.physical_network = physical_networks[0] + cls.services["netscaler_1"]["lbdevicecapacity"] = 2 + cls.netscaler_1 = NetScaler.add( + cls.api_client, + cls.services["netscaler_1"], + physicalnetworkid=cls.physical_network.id + ) + + nw_service_providers = NetworkServiceProvider.list( + cls.api_client, + name='Netscaler', + physicalnetworkid=cls.physical_network.id + ) + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + + if netscaler_provider.state != 'Enabled': + response = NetworkServiceProvider.update( + cls.api_client, + id=netscaler_provider.id, + state='Enabled' + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.account_1 = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls.account_2 = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls.account_3 = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls.account_4 = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls.account_5 = Account.create( + cls.api_client, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + cls.account_1, + cls.account_2, + cls.account_3, + cls.account_5 + ] + cls.cleanup_devices = [cls.netscaler_1] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + interval = list_configurations( + cls.api_client, + name='network.gc.interval' + ) + wait = list_configurations( + cls.api_client, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + cleanup_resources(cls.api_client, cls.cleanup_devices) + 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: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_01_netscaler_shared_mode(self): + """Test netscaler device in shared mode + """ + + # Validate the following + # 1. Add Netscaler device in shared mode with capacity 3 + # 2. Netscaler should be configured successfully.It should be able to + # service only 3 account. + + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=self.netscaler_1.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + self.network_1 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_1.id) + + self.debug("Deploying VM in account: %s" % self.account_1.account.name) + + # Spawn an instance in that network + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_1.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_1.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + self.network_2 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_2.id) + + self.debug("Deploying VM in account: %s" % self.account_2.account.name) + + # Spawn an instance in that network + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_2.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_2.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + self.network_3 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_3.id) + self.debug("Deploying VM in account: %s" % self.account_3.account.name) + + with self.assertRaises(Exception): + # Spawn an instance in that network + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_3.id)] + ) + + self.debug("Deploy VM failed as Netscaler device capacity is full!") + return + + def test_02_multiple_netscaler_capacilty(self): + """Test multiple netscaler devices with limited capacity + """ + + # Validate the following + # 1. Add another netscaler device and spawn a new VM again + # 2. VM deployement should be successful + + self.debug("Adding another netscaler device: %s" % + self.services["netscaler_2"]["ipaddress"]) + self.services["netscaler_2"]["lbdevicecapacity"] = 2 + netscaler_2 = NetScaler.add( + self.apiclient, + self.services["netscaler_2"], + physicalnetworkid=self.physical_network.id + ) + self.cleanup_devices.append(netscaler_2) + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=netscaler_2.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + self.assertEqual( + ns.physicalnetworkid, + self.physical_network.id, + "Physical network id should match with the network in which device is configured" + ) + self.debug("Another Netscaler device is added!") + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + networks = Network.list( + self.apiclient, + account=self.account_3.account.name, + domainid=self.account_3.account.domainid, + zoneid=self.zone.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "Network should be present for the account: %s" % + self.account_3.account.name + ) + self.network_3 = networks[0] + self.debug("Created network with ID: %s" % self.network_3.id) + + self.debug("Deploying VM in account: %s" % self.account_3.account.name) + + # Spawn an instance in that network + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_3.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_3.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + return + + def test_03_multiple_netscaler_full_capacilty(self): + """Test netscaler device with full capacity + """ + + # Validate the following + # 1. Spawn multiple instances for utilizing full capacity of Netscaler + # 2. Deploy VM should fail after capacity full in netscaler device + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + self.network_4 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_4.account.name, + domainid=self.account_4.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_4.id) + + self.debug("Deploying VM in account: %s" % self.account_4.account.name) + + # Spawn an instance in that network + virtual_machine_4 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_4.account.name, + domainid=self.account_4.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_4.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_4.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_4.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_4.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + self.network_5 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_5.account.name, + domainid=self.account_5.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_5.id) + + self.debug("Deploying VM in account: %s" % self.account_5.account.name) + + with self.assertRaises(Exception): + # Spawn an instance in that network + virtual_machine_5 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_5.account.name, + domainid=self.account_5.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_5.id)] + ) + self.debug("Deploy VM failed as Netscaler device capacity is full!") + return + + def test_04_delete_account_after_capacity_full(self): + """Test delete and add resouces after netscaler device capacity is full + """ + + # Validate the following + # 1. Delete one of the account. Wait till Network.gc.wait & + # network.gc.interval time + # 2. Create an instance from another account + # 3. Deploy instance should succeed + + self.debug("Delete account: %s" % self.account_4.account.name) + self.account_4.delete(self.apiclient) + self.debug("Account: %s is deleted" % self.account_4.account.name) + + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + self.debug("Sleeping for: network.gc.interval + network.gc.wait") + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering.id) + self.network_5 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_5.account.name, + domainid=self.account_5.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_5.id) + + self.debug("Deploying VM in account: %s" % self.account_5.account.name) + + # Spawn an instance in that network + virtual_machine_5 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_5.account.name, + domainid=self.account_5.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_5.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_5.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_5.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_5.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + return + + +class TestNwOffDedicatedNetscaler(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestNwOffDedicatedNetscaler, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + physical_networks = PhysicalNetwork.list( + cls.api_client, + zoneid=cls.zone.id + ) + if isinstance(physical_networks, list): + physical_network = physical_networks[0] + cls.services["netscaler_1"]["lbdevicecapacity"] = 3 + cls.netscaler = NetScaler.add( + cls.api_client, + cls.services["netscaler_1"], + physicalnetworkid=physical_network.id + ) + + nw_service_providers = NetworkServiceProvider.list( + cls.api_client, + name='Netscaler', + physicalnetworkid=physical_network.id + ) + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + + if netscaler_provider.state != 'Enabled': + response = NetworkServiceProvider.update( + cls.api_client, + id=netscaler_provider.id, + state='Enabled' + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering_dedicated"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + cls.netscaler, + ] + 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.account_1 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account_1] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_nw_off_dedicated_mode(self): + """Test network offering in dedicated mode device + """ + + # Validate the following + # 1. Add Netscaler device in shared mode + # 2. Create a network offering in dedicated mode. + # 3. Try to implemenent network with that network offering. Network + # craetion should fail. + + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=self.netscaler.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + + self.network_1 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Deploy Instance with network: %s" % self.network_1.name) + with self.assertRaises(Exception): + # Spawn an instance in that network + VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_1.id)] + ) + self.debug("Created instance failed!") + return + + +class TestNwOffNetscaler(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestNwOffNetscaler, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + physical_networks = PhysicalNetwork.list( + cls.api_client, + zoneid=cls.zone.id + ) + if isinstance(physical_networks, list): + physical_network = physical_networks[0] + cls.services["netscaler_1"]["lbdevicecapacity"] = 3 + cls.netscaler_1 = NetScaler.add( + cls.api_client, + cls.services["netscaler_1"], + physicalnetworkid=physical_network.id + ) + + cls.services["netscaler_2"].pop("lbdevicecapacity") + cls.services["netscaler_2"]["lbdevicededicated"] = True + cls.netscaler_2 = NetScaler.add( + cls.api_client, + cls.services["netscaler_2"], + physicalnetworkid=physical_network.id + ) + nw_service_providers = NetworkServiceProvider.list( + cls.api_client, + name='Netscaler', + physicalnetworkid=physical_network.id + ) + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + + if netscaler_provider.state != 'Enabled': + response = NetworkServiceProvider.update( + cls.api_client, + id=netscaler_provider.id, + state='Enabled' + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering_dedicated"], + conservemode=True + ) + cls.network_offering_shared = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + cls.network_offering_shared.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + cls.network_offering_shared, + cls.netscaler_1, + cls.netscaler_2, + ] + 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.account_1 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_2 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_3 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account_2, self.account_3] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_ns_shared_nw_dedicated(self): + """Test netscaler device in shared mode with network offering in dedicated mode + """ + + # Validate the following + # 1. Add Netscaler device in shared mode + # 2. Create a network offering in dedicated mode. + # 3. Try to implemenent network with that network offering. Network + # craetion should fail. + + ns_list = NetScaler.list( + self.apiclient, + lbdeviceid=self.netscaler_1.lbdeviceid + ) + self.assertEqual( + isinstance(ns_list, list), + True, + "NetScaler list should not be empty" + ) + ns = ns_list[0] + + self.assertEqual( + ns.lbdevicededicated, + False, + "NetScaler device is configured in shared mode" + ) + self.assertEqual( + ns.lbdevicestate, + "Enabled", + "NetScaler device state should be enabled" + ) + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Deploying VM in account: %s" % self.account_1.account.name) + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + # Creating network using the network offering created + self.debug("Creating different network with network offering: %s" % + self.network_offering.id) + + self.network_2 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_2.id) + with self.assertRaises(Exception): + VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_2.id)] + ) + self.debug( + "Attempt to create second network with dedicated network offering failed!") + self.debug("Deleting account: %s" % self.account_1.account.name) + self.account_1.delete(self.apiclient) + self.debug("Account: %s deleted!" % self.account_1.account.name) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + self.debug("Sleeping for: network.gc.interval + network.gc.wait") + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + + self.debug("Deploying VM in account: %s" % self.account_2.account.name) + + # Spawn an instance in that network + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_2.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_2.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering_shared.id) + self.network_3 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + networkofferingid=self.network_offering_shared.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_3.id) + + self.debug("Deploying VM in account: %s" % self.account_3.account.name) + + # Spawn an instance in that network + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_3.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_3.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + return + + +class TestNwOffSToDUpgrade(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestNwOffSToDUpgrade, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + physical_networks = PhysicalNetwork.list( + cls.api_client, + zoneid=cls.zone.id + ) + if isinstance(physical_networks, list): + cls.physical_network = physical_networks[0] + cls.services["netscaler_1"]["lbdevicecapacity"] = 3 + cls.netscaler_1 = NetScaler.add( + cls.api_client, + cls.services["netscaler_1"], + physicalnetworkid=cls.physical_network.id + ) + + cls.services["netscaler_2"].pop("lbdevicecapacity") + cls.services["netscaler_2"]["lbdevicededicated"] = True + cls.netscaler_2 = NetScaler.add( + cls.api_client, + cls.services["netscaler_2"], + physicalnetworkid=cls.physical_network.id + ) + + nw_service_providers = NetworkServiceProvider.list( + cls.api_client, + name='Netscaler', + physicalnetworkid=cls.physical_network.id + ) + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + + if netscaler_provider.state != 'Enabled': + response = NetworkServiceProvider.update( + cls.api_client, + id=netscaler_provider.id, + state='Enabled' + ) + cls.network_offering_dedicated = NetworkOffering.create( + cls.api_client, + cls.services["network_offering_dedicated"], + conservemode=True + ) + cls.network_offering_shared = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering_dedicated.update(cls.api_client, state='Enabled') + cls.network_offering_shared.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_offering, + cls.network_offering_dedicated, + cls.network_offering_shared, + cls.netscaler_1, + cls.netscaler_2, + ] + 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.account_1 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_2 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_3 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account_1, self.account_2, self.account_3] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_shared_to_dedicated_upgrade(self): + """Test upgrade from shared LB isolation to dedicated LB isolation""" + + # Validate the following + # 1. Create a dedicated and shared network offering + # 2. Configure 2 instances of Netscaler one with dedicated and other + # shared mode + # 3. Deploy instance with shared network offering in account 1. create + # LB rules + # 4. Deploy instance with shared network offering in account 2. create + # LB rules + # 5. Deploy instance with dedicated network offering in account 3. + # Create Lb rules. + # 6. Configure another instace of netscaler in dedicated mode + # 7. upgrade networkj for user 1 to dedicated network offering. + # Create LB rules. LB rule creation should be successful + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering_shared.id) + self.network_1 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + networkofferingid=self.network_offering_shared.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_1.id) + + self.debug("Deploying VM in account: %s" % self.account_1.account.name) + + # Spawn an instance in that network + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_1.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_1.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering_shared.id) + self.network_2 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + networkofferingid=self.network_offering_shared.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_2.id) + + self.debug("Deploying VM in account: %s" % self.account_2.account.name) + + # Spawn an instance in that network + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_2.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_2.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering_dedicated.id) + self.network_3 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + networkofferingid=self.network_offering_dedicated.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_3.id) + self.debug("Deploying VM in account: %s" % self.account_3.account.name) + + # Spawn an instance in that network + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_3.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_3.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + self.debug("Configuring another Netscaler device in dedicated mode") + + self.services["netscaler_3"].pop("lbdevicecapacity") + self.services["netscaler_3"]["lbdevicededicated"] = True + self.netscaler_3 = NetScaler.add( + self.apiclient, + self.services["netscaler_3"], + physicalnetworkid=self.physical_network.id + ) + + self.debug("Stopping All VMs before upgrading network for account: %s" % + self.account_1.account.name) + virtual_machine_1.stop(self.apiclient) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM state should be running after deployment" + ) + self.debug("All Vms are in stopped state") + self.debug("Upgrading the network: %s" % self.network_1.id) + self.network_1.update( + self.apiclient, + networkofferingid=self.network_offering_dedicated.id, + changecidr=True + ) + networks = Network.list( + self.apiclient, + id=self.network_1.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List Networks should return a valid list for given network ID" + ) + self.assertNotEqual( + len(networks), + 0, + "Length of list networks should not be 0" + ) + network = networks[0] + self.assertEqual( + network.networkofferingid, + self.network_offering_dedicated.id, + "Network offering ID should match with new offering ID" + ) + + self.debug("Starting All VMs after upgrading network for account: %s" % + self.account_1.account.name) + virtual_machine_1.start(self.apiclient) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + self.debug("All Vms are in running state") + try: + self.debug( + "Associating public Ip to the network: %s" % + self.network_1.name) + + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account_1.account.name, + zoneid=self.zone.id, + domainid=self.account_1.account.domainid, + networkid=self.network_1.id + ) + self.debug( + "Creating LB rule for IP address: %s with round robin algo" % + public_ip.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip.ipaddress.id, + accountid=self.account_1.account.name, + networkid=self.network_1.id + ) + self.debug("Created the load balancing rule for public IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to create load balancing rule - %s" % e) + return + + +class TestNwOffDToSUpgrade(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestNwOffDToSUpgrade, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + physical_networks = PhysicalNetwork.list( + cls.api_client, + zoneid=cls.zone.id + ) + if isinstance(physical_networks, list): + cls.physical_network = physical_networks[0] + cls.services["netscaler_1"]["lbdevicecapacity"] = 3 + cls.netscaler_1 = NetScaler.add( + cls.api_client, + cls.services["netscaler_1"], + physicalnetworkid=cls.physical_network.id + ) + + cls.services["netscaler_2"].pop("lbdevicecapacity") + cls.services["netscaler_2"]["lbdevicededicated"] = True + cls.netscaler_2 = NetScaler.add( + cls.api_client, + cls.services["netscaler_2"], + physicalnetworkid=cls.physical_network.id + ) + + nw_service_providers = NetworkServiceProvider.list( + cls.api_client, + name='Netscaler', + physicalnetworkid=cls.physical_network.id + ) + if isinstance(nw_service_providers, list): + netscaler_provider = nw_service_providers[0] + + if netscaler_provider.state != 'Enabled': + response = NetworkServiceProvider.update( + cls.api_client, + id=netscaler_provider.id, + state='Enabled' + ) + cls.network_offering_dedicated = NetworkOffering.create( + cls.api_client, + cls.services["network_offering_dedicated"], + conservemode=True + ) + cls.network_offering_shared = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering_dedicated.update(cls.api_client, state='Enabled') + cls.network_offering_shared.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_offering, + cls.network_offering_dedicated, + cls.network_offering_shared, + cls.netscaler_1, + cls.netscaler_2, + ] + 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.account_1 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_2 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.account_3 = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account_1, self.account_2, self.account_3] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_shared_to_dedicated_upgrade(self): + """Test upgrade from shared LB isolation to dedicated LB isolation""" + + # Validate the following + # 1. Create a dedicated and shared network offering + # 2. Configure 2 instances of Netscaler one with dedicated and other + # shared mode + # 3. Deploy instance with shared network offering in account 1. create + # LB rules + # 4. Deploy instance with shared network offering in account 2. create + # LB rules + # 5. Deploy instance with dedicated network offering in account 3. + # Create Lb rules. + # 6. Configure another instace of netscaler in dedicated mode + # 7. upgrade networkj for user 1 to dedicated network offering. + # Create LB rules. LB rule creation should be successful + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering_shared.id) + self.network_1 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + networkofferingid=self.network_offering_shared.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_1.id) + + self.debug("Deploying VM in account: %s" % self.account_1.account.name) + + # Spawn an instance in that network + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_1.account.name, + domainid=self.account_1.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_1.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_1.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering_shared.id) + self.network_2 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + networkofferingid=self.network_offering_shared.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_2.id) + + self.debug("Deploying VM in account: %s" % self.account_2.account.name) + + # Spawn an instance in that network + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_2.account.name, + domainid=self.account_2.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_2.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_2.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + # Creating network using the network offering created + self.debug("Trying to create network with network offering: %s" % + self.network_offering_dedicated.id) + self.network_3 = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + networkofferingid=self.network_offering_dedicated.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network_3.id) + self.debug("Deploying VM in account: %s" % self.account_3.account.name) + + # Spawn an instance in that network + virtual_machine_3 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account_3.account.name, + domainid=self.account_3.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network_3.id)] + ) + self.debug("Deployed VM in network: %s" % self.network_3.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Stopping all VMs in account: %s" % self.account_3.account.name) + virtual_machine_3.stop(self.apiclient) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM state should be stopped" + ) + self.debug("All user VMs stopped") + self.debug("Upgrading the network: %s" % self.network_3.id) + self.network_3.update( + self.apiclient, + networkofferingid=self.network_offering_shared.id, + changecidr=True + ) + networks = Network.list( + self.apiclient, + id=self.network_3.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List Networks should return a valid list for given network ID" + ) + self.assertNotEqual( + len(networks), + 0, + "Length of list networks should not be 0" + ) + network = networks[0] + self.assertEqual( + network.networkofferingid, + self.network_offering_shared.id, + "Network offering ID should match with new offering ID" + ) + self.debug("Starting instances in account: %s" % self.account_3.account.name) + virtual_machine_3.start(self.apiclient) + + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_3.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_3.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + try: + self.debug( + "Associating public Ip to the network: %s" % + self.network_3.name) + + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account_3.account.name, + zoneid=self.zone.id, + domainid=self.account_3.account.domainid, + networkid=self.network_3.id + ) + self.debug( + "Creating LB rule for IP address: %s with round robin algo" % + public_ip.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip.ipaddress.id, + accountid=self.account_3.account.name, + networkid=self.network_3.id + ) + self.debug("Created the load balancing rule for public IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to create load balancing rule - %s" % e) + return diff --git a/test/integration/component/test_stopped_vm.py b/test/integration/component/test_stopped_vm.py new file mode 100644 index 00000000000..2ff2f811148 --- /dev/null +++ b/test/integration/component/test_stopped_vm.py @@ -0,0 +1,1876 @@ +# -*- encoding: utf-8 -*- +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +""" P1 for stopped Virtual Maschine life cycle +""" +#Import Local Modules +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.remoteSSHClient import remoteSSHClient +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * +#Import System modules +import time + +class Services: + """Test Stopped VM Life Cycle Services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended in create account to + # ensure unique username generated each time + "password": "password", + }, + "virtual_machine": + { + "displayname": "testserver", + "username": "root", # VM creds for SSH + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "service_offering": + { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "disk_offering": { + "displaytext": "Small volume", + "name": "Small volume", + "disksize": 20 + }, + "volume": { + "diskname": "DataDisk", + "url": '', + "format": 'VHD' + }, + "iso": # ISO settings for Attach/Detach ISO tests + { + "displaytext": "Test ISO", + "name": "testISO", + "url": "http://nfs1.lab.vmops.com/isos_32bit/dsl-4.4.10.iso", + # Source URL where ISO is located + "ostypeid": '19e6a39f-92db-4d2c-b375-33e7f42d86be', + "mode": 'HTTP_DOWNLOAD', # Downloading existing ISO + }, + "template": { + "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", + "hypervisor": 'XenServer', + "format" : 'VHD', + "isfeatured": True, + "ispublic": True, + "isextractable": True, + "displaytext": "Cent OS Template", + "name": "Cent OS Template", + "ostypeid": '19e6a39f-92db-4d2c-b375-33e7f42d86be', + "templatefilter": 'self', + "passwordenabled": True, + }, + "sleep": 60, + "timeout": 10, + #Migrate VM to hostid + "ostypeid": '19e6a39f-92db-4d2c-b375-33e7f42d86be', + # CentOS 5.3 (64-bit) + } + + +class TestDeployVM(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestDeployVM, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + # Create service offerings, disk offerings etc + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + # Cleanup + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.services = Services().services + self.services["virtual_machine"]["zoneid"] = self.zone.id + self.services["iso"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["template"] = self.template.id + self.account = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + def test_01_deploy_vm_no_startvm(self): + """Test Deploy Virtual Machine with no startVM parameter + """ + + # Validate the following: + # 1. deploy Vm without specifying the startvm parameter + # 2. Should be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Running". + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + mode=self.zone.networktype + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in Running state after deployment" + ) + try: + ssh = self.virtual_machine.get_ssh_client() + except Exception as e: + self.fail("SSH to VM instance failed!") + return + + def test_02_deploy_vm_startvm_true(self): + """Test Deploy Virtual Machine with startVM=true parameter + """ + + # Validate the following: + # 1. deploy Vm with the startvm=true + # 2. Should be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Running". + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=True, + diskofferingid=self.disk_offering.id, + mode=self.zone.networktype + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in Running state after deployment" + ) + try: + ssh = self.virtual_machine.get_ssh_client() + except Exception as e: + self.fail("SSH to VM instance failed!") + return + + def test_03_deploy_vm_startvm_false(self): + """Test Deploy Virtual Machine with startVM=false parameter + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false + # 2. Should not be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 4. Check listRouters call for that account. List routers should + # return empty response + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + diskofferingid=self.disk_offering.id, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + routers = Router.list( + self.apiclient, + account=self.account.account.name, + domainid=self.account.account.domainid, + listall=True + ) + self.assertEqual( + routers, + None, + "List routers should return empty response" + ) + self.debug("Destroying instance: %s" % self.virtual_machine.name) + self.virtual_machine.delete(self.apiclient) + self.debug("Instance is destroyed!") + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + self.debug("Instance destroyed..waiting till expunge interval") + + interval = list_configurations( + self.apiclient, + name='expunge.interval' + ) + delay = list_configurations( + self.apiclient, + name='expunge.delay' + ) + # Sleep to ensure that all resources are deleted + time.sleep((int(interval[0].value) + int(delay[0].value))) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.assertEqual( + list_vm_response, + None, + "Check list response returns a valid list" + ) + return + + def test_04_deploy_startvm_false_attach_volume(self): + """Test Deploy Virtual Machine with startVM=false and attach volume + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false. Attach volume to the instance + # 2. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 3. Attach volume should be successful + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + diskofferingid=self.disk_offering.id, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + self.debug("Creating a volume in account: %s" % + self.account.account.name) + volume = Volume.create( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.account.name, + domainid=self.account.account.domainid, + diskofferingid=self.disk_offering.id + ) + self.debug("Created volume in account: %s" % self.account.account.name) + self.debug("Attaching volume to instance: %s" % + self.virtual_machine.name) + try: + self.virtual_machine.attach_volume(self.apiclient, volume) + except Exception as e: + self.fail("Attach volume failed!") + return + + def test_05_deploy_startvm_false_change_so(self): + """Test Deploy Virtual Machine with startVM=false and + change service offering + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false. Attach volume to the instance + # 2. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 3. Attach volume should be successful + # 4. Change service offering + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + diskofferingid=self.disk_offering.id, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + self.debug("Creating a volume in account: %s" % + self.account.account.name) + volume = Volume.create( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.account.name, + domainid=self.account.account.domainid, + diskofferingid=self.disk_offering.id + ) + self.debug("Created volume in account: %s" % self.account.account.name) + self.debug("Attaching volume to instance: %s" % + self.virtual_machine.name) + try: + self.virtual_machine.attach_volume(self.apiclient, volume) + except Exception as e: + self.fail("Attach volume failed!") + self.debug("Fetching details of medium service offering") + medium_service_offs = ServiceOffering.list( + self.apiclient, + name="Medium Instance" + ) + if isinstance(medium_service_offs, list): + medium_service_off = medium_service_offs[0] + else: + self.debug("Service offering not found! Creating a new one..") + medium_service_off = ServiceOffering.create( + self.apiclient, + self.services["service_offering"] + ) + self.cleanup.append(medium_service_off) + + self.debug("Changing service offering for instance: %s" % + self.virtual_machine.name) + try: + self.virtual_machine.change_service_offering( + self.apiclient, + medium_service_off.id + ) + except Exception as e: + self.fail("Change service offering failed: %s" % e) + + self.debug("Starting the instance: %s" % self.virtual_machine.name) + self.virtual_machine.start(self.apiclient) + self.debug("Instance: %s started" % self.virtual_machine.name) + + self.debug("Detaching the disk: %s" % volume.name) + self.virtual_machine.detach_volume(self.apiclient, volume) + self.debug("Datadisk %s detached!" % volume.name) + + volumes = Volume.list( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='DATADISK', + id=volume.id, + listall=True + ) + self.assertEqual( + volumes, + None, + "List Volumes should not list any volume for instance" + ) + return + + def test_06_deploy_startvm_attach_detach(self): + """Test Deploy Virtual Machine with startVM=false and + attach detach volumes + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false. Attach volume to the instance + # 2. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 3. Attach volume should be successful + # 4. Detach volume from instance. Detach should be successful + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + diskofferingid=self.disk_offering.id, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + self.debug("Creating a volume in account: %s" % + self.account.account.name) + volume = Volume.create( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.account.name, + domainid=self.account.account.domainid, + diskofferingid=self.disk_offering.id + ) + self.debug("Created volume in account: %s" % self.account.account.name) + self.debug("Attaching volume to instance: %s" % + self.virtual_machine.name) + try: + self.virtual_machine.attach_volume(self.apiclient, volume) + except Exception as e: + self.fail("Attach volume failed!") + + self.debug("Detaching the disk: %s" % volume.name) + self.virtual_machine.detach_volume(self.apiclient, volume) + self.debug("Datadisk %s detached!" % volume.name) + + volumes = Volume.list( + self.apiclient, + virtualmachineid=self.virtual_machine.id, + type='DATADISK', + id=volume.id, + listall=True + ) + self.assertEqual( + volumes, + None, + "List Volumes should not list any volume for instance" + ) + return + + def test_07_deploy_startvm_attach_iso(self): + """Test Deploy Virtual Machine with startVM=false and attach ISO + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false. Attach volume to the instance + # 2. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 3. Attach ISO to the instance. Attach ISO should be successful + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + diskofferingid=self.disk_offering.id, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + self.debug("Registering a ISO in account: %s" % + self.account.account.name) + iso = Iso.create( + self.apiclient, + self.services["iso"], + account=self.account.account.name, + domainid=self.account.account.domainid + ) + + self.debug("Successfully created ISO with ID: %s" % iso.id) + try: + iso.download(self.apiclient) + self.cleanup.append(iso) + except Exception as e: + self.fail("Exception while downloading ISO %s: %s"\ + % (iso.id, e)) + + self.debug("Attach ISO with ID: %s to VM ID: %s" % ( + iso.id, + self.virtual_machine.id + )) + try: + self.virtual_machine.attach_iso(self.apiclient, iso) + except Exception as e: + self.fail("Attach ISO failed!") + + vms = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.isoid, + iso.id, + "The ISO status should be reflected in list Vm call" + ) + return + + def test_08_deploy_attach_volume(self): + """Test Deploy Virtual Machine with startVM=false and + attach volume already attached to different machine + """ + + # Validate the following: + # 1. deploy Vm with the startvm=false. Attach volume to the instance + # 2. listVM command should return the deployed VM.State of this VM + # should be "Stopped". + # 3. Create an instance with datadisk attached to it. Detach DATADISK + # 4. Attach the volume to first virtual machine. + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment with startvm=false" + ) + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM should be in Stopped state after deployment with startvm=false" + ) + + self.debug( + "Fetching DATADISK details for instance: %s" % + self.virtual_machine_2.name) + volumes = Volume.list( + self.apiclient, + type='DATADISK', + account=self.account.account.name, + domainid=self.account.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(volumes, list), + True, + "List volumes should return a valid list" + ) + volume = volumes[0] + + self.debug("Detaching the disk: %s" % volume.name) + + try: + self.virtual_machine_2.detach_volume(self.apiclient, volume) + self.debug("Datadisk %s detached!" % volume.name) + except Exception as e: + self.fail("Detach volume failed!") + + self.debug("Attaching volume to instance: %s" % + self.virtual_machine_1.name) + try: + self.virtual_machine_1.attach_volume(self.apiclient, volume) + except Exception as e: + self.fail("Attach volume failed!") + + volumes = Volume.list( + self.apiclient, + virtualmachineid=self.virtual_machine_1.id, + type='DATADISK', + id=volume.id, + listall=True + ) + self.assertNotEqual( + volumes, + None, + "List Volumes should not list any volume for instance" + ) + return + + + +class TestDeployHaEnabledVM(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestDeployHaEnabledVM, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + # Create service, disk offerings etc + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"], + offerha=True + ) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + # Cleanup + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.services = Services().services + self.services["virtual_machine"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["template"] = self.template.id + self.services["iso"]["zoneid"] = self.zone.id + self.account = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + def test_01_deploy_ha_vm_startvm_false(self): + """Test Deploy HA enabled Virtual Machine with startvm=false + """ + + # Validate the following: + # 1. deployHA enabled Vm with the startvm parameter = false + # 2. listVM command should return the deployed VM. State of this VM + # should be "Created". + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + startvm=False + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Stopped", + "VM should be in Stopped state after deployment" + ) + return + + def test_02_deploy_ha_vm_from_iso(self): + """Test Deploy HA enabled Virtual Machine from ISO + """ + + # Validate the following: + # 1. deployHA enabled Vm using ISO with the startvm parameter=true + # 2. listVM command should return the deployed VM. State of this VM + # should be "Running". + + self.iso = Iso.create( + self.apiclient, + self.services["iso"], + account=self.account.account.name, + domainid=self.account.account.domainid + ) + try: + # Dowanload the ISO + self.iso.download(self.apiclient) + self.cleanup.append(self.iso) + except Exception as e: + raise Exception("Exception while downloading ISO %s: %s"\ + % (self.iso.id, e)) + + self.debug("Registered ISO: %s" % self.iso.name) + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + templateid=self.iso.id, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + startvm=True + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in Running state after deployment" + ) + return + + def test_03_deploy_ha_vm_iso_startvm_false(self): + """Test Deploy HA enabled Virtual Machine from ISO with startvm=false + """ + + # Validate the following: + # 1. deployHA enabled Vm using ISO with the startvm parameter=false + # 2. listVM command should return the deployed VM. State of this VM + # should be "Stopped". + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + startvm=False + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Stopped", + "VM should be in Running state after deployment" + ) + return + + +class TestRouterStateAfterDeploy(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestRouterStateAfterDeploy, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + # Create service offerings, disk offerings etc + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + # Cleanup + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.services = Services().services + self.services["virtual_machine"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["template"] = self.template.id + self.services["iso"]["zoneid"] = self.zone.id + self.account = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + def test_01_deploy_vm_no_startvm(self): + """Test Deploy Virtual Machine with no startVM parameter + """ + + # Validate the following: + # 1. deploy Vm without specifying the startvm parameter + # 2. Should be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Running". + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + startvm=False + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Stopped", + "VM should be in stopped state after deployment" + ) + self.debug("Checking the router state after VM deployment") + routers = Router.list( + self.apiclient, + account=self.account.account.name, + domainid=self.account.account.domainid, + listall=True + ) + self.assertEqual( + routers, + None, + "List routers should return empty response" + ) + self.debug( + "Deploying another instance (startvm=true) in the account: %s" % + self.account.account.name) + self.virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + diskofferingid=self.disk_offering.id, + startvm=True + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in Running state after deployment" + ) + self.debug("Checking the router state after VM deployment") + routers = Router.list( + self.apiclient, + account=self.account.account.name, + domainid=self.account.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "List routers should not return empty response" + ) + for router in routers: + self.debug("Router state: %s" % router.state) + self.assertEqual( + router.state, + "Running", + "Router should be in running state when instance is running in the account" + ) + self.debug("Destroying the running VM:%s" % + self.virtual_machine_2.name) + self.virtual_machine_2.delete(self.apiclient) + self.debug("Instance destroyed..waiting till expunge interval") + + interval = list_configurations( + self.apiclient, + name='expunge.interval' + ) + delay = list_configurations( + self.apiclient, + name='expunge.delay' + ) + # Sleep to ensure that all resources are deleted + time.sleep((int(interval[0].value) + int(delay[0].value)) * 2) + + self.debug("Checking the router state after VM deployment") + routers = Router.list( + self.apiclient, + account=self.account.account.name, + domainid=self.account.account.domainid, + listall=True + ) + self.assertNotEqual( + routers, + None, + "Router should get deleted after expunge delay+wait" + ) + return + + +class TestDeployVMBasicZone(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestDeployVMBasicZone, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + + # Create service offerings, disk offerings etc + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + # Cleanup + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.services = Services().services + self.services["virtual_machine"]["zoneid"] = self.zone.id + self.services["iso"]["zoneid"] = self.zone.id + self.services["virtual_machine"]["template"] = self.template.id + self.account = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + def test_01_deploy_vm_startvm_true(self): + """Test Deploy Virtual Machine with startVM=true parameter + """ + + # Validate the following: + # 1. deploy Vm with the startvm=true + # 2. Should be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Running". + + + self.debug("Checking the network type of the zone: %s" % + self.zone.networktype) + self.assertEqual( + self.zone.networktype, + 'Basic', + "Zone must be configured in basic networking mode" + ) + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=True, + diskofferingid=self.disk_offering.id, + mode=self.zone.networktype + ) + + self.debug("Deployed instance ion account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in Running state after deployment" + ) + return + + def test_02_deploy_vm_startvm_false(self): + """Test Deploy Virtual Machine with startVM=true parameter + """ + + # Validate the following: + # 1. deploy Vm with the startvm=true + # 2. Should be able to login to the VM. + # 3. listVM command should return the deployed VM.State of this VM + # should be "Running". + + + self.debug("Checking the network type of the zone: %s" % + self.zone.networktype) + self.assertEqual( + self.zone.networktype, + 'Basic', + "Zone must be configured in basic networking mode" + ) + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False, + mode=self.zone.networktype + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Stopped", + "VM should be in stopped state after deployment" + ) + self.debug("Starting the instance: %s" % self.virtual_machine.name) + self.virtual_machine.start(self.apiclient) + self.debug("Started the instance: %s" % self.virtual_machine.name) + + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Running", + "VM should be in running state after deployment" + ) + return + + +class TestDeployVMFromTemplate(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestDeployVMFromTemplate, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + # Create service, disk offerings etc + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"], + offerha=True + ) + cls.disk_offering = DiskOffering.create( + cls.api_client, + cls.services["disk_offering"] + ) + # Cleanup + cls._cleanup = [ + cls.service_offering, + cls.disk_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.services = Services().services + self.services["virtual_machine"]["zoneid"] = self.zone.id + self.account = Account.create( + self.apiclient, + self.services["account"], + domainid=self.domain.id + ) + self.template = Template.register( + self.apiclient, + self.services["template"], + zoneid=self.zone.id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + try: + self.template.download(self.apiclient) + except Exception as e: + raise Exception("Template download failed: %s" % e) + + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + self.debug("Cleanup complete!") + except Exception as e: + self.debug("Warning! Exception in tearDown: %s" % e) + + def test_deploy_vm_password_enabled(self): + """Test Deploy Virtual Machine with startVM=false & enabledpassword in + template + """ + + # Validate the following: + # 1. Create the password enabled template + # 2. Deploy Vm with this template and passing startvm=false + # 3. Start VM. Deploy VM should be successful and it should be in Up + # and running state + + self.debug("Deploying instance in the account: %s" % + self.account.account.name) + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + startvm=False, + ) + + self.debug("Deployed instance in account: %s" % + self.account.account.name) + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + + vm_response.state, + "Stopped", + "VM should be in stopped state after deployment" + ) + self.debug("Starting the instance: %s" % self.virtual_machine.name) + self.virtual_machine.start(self.apiclient) + self.debug("Started the instance: %s" % self.virtual_machine.name) + + list_vm_response = list_virtual_machines( + self.apiclient, + id=self.virtual_machine.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM should be in running state after deployment" + ) + return + + +class TestVMAccountLimit(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestVMAccountLimit, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + + # Create Account, VMs etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_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, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_vm_per_account(self): + """Test VM limit per account + """ + + # Validate the following + # 1. Set the resource limit for VM per account. + # 2. Deploy VMs more than limit in that account. + # 3. AIP should error out + + self.debug( + "Updating instance resource limit for account: %s" % + self.account.account.name) + # Set usage_vm=1 for Account 1 + update_resource_limit( + self.apiclient, + 0, # Instance + account=self.account.account.name, + domainid=self.account.account.domainid, + max=1 + ) + self.debug( + "Deploying VM instance in account: %s" % + self.account.account.name) + + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + templateid=self.template.id, + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False + ) + + # Verify VM state + self.assertEqual( + virtual_machine.state, + 'Stopped', + "Check VM state is Running or not" + ) + + # Exception should be raised for second instance (account_1) + with self.assertRaises(Exception): + VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + templateid=self.template.id, + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False + ) + return + + +class TestUploadAttachVolume(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestUploadAttachVolume, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + + # Create Account, VMs etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup = [ + cls.service_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, terminate the created instance, volumes and snapshots + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_upload_attach_volume(self): + """Test Upload volume and attach to VM in stopped state + """ + + # Validate the following + # 1. Upload the volume using uploadVolume API call + # 2. Deploy VM with startvm=false. + # 3. Attach the volume to the deployed VM in step 2 + + self.debug( + "Uploading the volume: %s" % + self.services["volume"]["diskname"]) + try: + volume = Volume.upload( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.account.name, + domainid=self.account.account.domainid + ) + self.debug("Uploading the volume: %s" % volume.name) + volume.wait_for_upload(self.apiclient) + self.debug("Volume: %s uploaded successfully") + except Exception as e: + self.fail("Failed to upload the volume: %s" % e) + + self.debug( + "Deploying VM instance in account: %s" % + self.account.account.name) + + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + templateid=self.template.id, + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id, + startvm=False + ) + # Verify VM state + self.assertEqual( + virtual_machine.state, + 'Stopped', + "Check VM state is Running or not" + ) + try: + virtual_machine.attach_volume(self.apiclient) + except Exception as e: + self.fail("Failed to attach the volume: %s" % e) + return diff --git a/test/integration/component/test_vmware_drs.py b/test/integration/component/test_vmware_drs.py new file mode 100644 index 00000000000..ec0228bf62f --- /dev/null +++ b/test/integration/component/test_vmware_drs.py @@ -0,0 +1,603 @@ +# -*- encoding: utf-8 -*- +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by 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. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +""" P1 for VMware DRS testing +""" +#Import Local Modules +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.remoteSSHClient import remoteSSHClient +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * +#Import System modules +import time + +class Services: + """Test vmware DRS services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended in create account to + # ensure unique username generated each time + "password": "password", + }, + "virtual_machine": + { + "displayname": "testserver", + "username": "root", # VM creds for SSH + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "service_offering": + { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "anti_affinity": { + "host_1": "10.147.29.55", + "host_2": "10.147.29.61", + "vm_2": '73973255-9354-4b1a-b98f-30a3531fd16d', + "vm_1": '11d4e127-7e07-47bb-8ec9-6a9e9ac672ce', + # VM IDs created manually on host 1 and anti-affinity rules added + }, + "affinity": { + "host_1": "10.147.29.55", + "host_2": "10.147.29.61", + "vm_2": '73973255-9354-4b1a-b98f-30a3531fd16d', + "vm_1": '11d4e127-7e07-47bb-8ec9-6a9e9ac672ce', + # VM IDs created manually on host 1 and affinity rules added + }, + "sleep": 60, + "timeout": 10, + "full_host": "10.147.29.53", + "ostypeid": 'd96fc3f0-a1d3-4498-88aa-a7a1ca96c1bb', + # CentOS 5.3 (64-bit) + } + + +class TestVMPlacement(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestVMPlacement, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain( + cls.api_client, + cls.services + ) + cls.zone = get_zone( + cls.api_client, + cls.services + ) + cls.pod = get_pod( + cls.api_client, + zoneid=cls.zone.id, + services=cls.services + ) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"], + offerha=True + ) + cls._cleanup = [ + cls.service_offering, + ] + 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.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + #Clean up, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + self.testClient.close() + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_vm_creation_in_fully_automated_mode(self): + """ Test VM Creation in automation mode = Fully automated + This test requires following preconditions: + - There should be minimum 2 hosts added to cluster + - One of the host should be full of capacity. This host's name + should be specified in "full_host" configuration + - Another host should have some capacity remaining + - DRS Cluster is configured in "Fully automated" mode + """ + + # Validate the following + # 1. Create a new VM in a host which is almost fully utilized + # 2 Automatically places VM on the other host + # 3. VM state is running after deployment + + hosts = Host.list( + self.apiclient, + zoneid=self.zone.id, + resourcestate='Enabled', + type='Routing' + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should return valid host response" + ) + self.assertGreaterEqual( + len(hosts), + 2, + "There must be two hosts present in a cluster" + ) + self.debug( + "Finding the host details of host: %s" % + self.services["full_host"]) + + host = [host for host in hosts if host.name == self.services["full_host"]][0] + + self.debug("Deploying VM in account: %s" % self.account.account.name) + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.account.name, + domainid=self.account.account.domainid, + serviceofferingid=self.service_offering.id + ) + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Deployed VM should be in RUnning state" + ) + self.assertNotEqual( + vm.hostid, + host.id, + "Host Ids of two should not match as one host is full" + ) + return + + +class TestAntiAffinityRules(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestAntiAffinityRules, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain( + cls.api_client, + cls.services + ) + cls.zone = get_zone( + cls.api_client, + cls.services + ) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls._cleanup = [] + 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, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + self.testClient.close() + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_vmware_anti_affinity(self): + """ Test Set up anti-affinity rules + + The test requires following pre-requisites + - VMWare cluster configured in fully automated mode + - There should be atleast 2 VMs deployed on one of the clusters + through cloudstack UI manually + - Anti affinity rule should be set on the 2 VMs deployed. + - Add host names to host_1,host_2 and IDs of VM 1,2 in the settings + class "anti_affinity" above. + """ + + # Validate the following + # 1. Deploy VMs on host 1 and 2 + # 2. Enable maintenance mode for host 1 + # 3. VM should be migrated to 3rd host + + hosts = Host.list( + self.apiclient, + zoneid=self.zone.id, + resourcestate='Enabled', + type='Routing' + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should return valid host response" + ) + self.assertGreaterEqual( + len(hosts), + 3, + "There must be two hosts present in a cluster" + ) + self.debug( + "Finding the host details of host_1: %s" % + self.services["anti_affinity"]["host_1"]) + + host_1 = [host for host in hosts if host.name == self.services["anti_affinity"]["host_1"]][0] + + host_2 = [host for host in hosts if host.name == self.services["anti_affinity"]["host_2"]][0] + + vms = VirtualMachine.list( + self.apiclient, + id=self.services["anti_affinity"]["vm_1"], + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + virtual_machine_1 = vms[0] + + self.debug("VM State: %s" % virtual_machine_1.state) + self.assertEqual( + virtual_machine_1.state, + "Running", + "Deployed VM should be in RUnning state" + ) + + vms = VirtualMachine.list( + self.apiclient, + id=self.services["anti_affinity"]["vm_2"], + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + virtual_machine_2 = vms[0] + self.debug("VM %s State: %s" % ( + virtual_machine_2.name, + virtual_machine_2.state + )) + self.assertEqual( + virtual_machine_2.state, + "Running", + "Deployed VM should be in RUnning state" + ) + self.debug("Enabling maintenance mode on host_1: %s" % host_1.name) + + cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() + cmd.id = host_1.id + self.apiclient.prepareHostForMaintenance(cmd) + + timeout = self.services["timeout"] + while True: + hosts = Host.list( + self.apiclient, + zoneid=self.zone.id, + type='Routing', + id=host_1.id + ) + if isinstance(hosts, list): + host = hosts[0] + if host.resourcestate == 'Maintenance': + break + elif timeout == 0: + self.fail("Failed to put host: %s in maintenance mode" % host.name) + + time.sleep(self.services["sleep"]) + timeout = timeout - 1 + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Deployed VM should be in RUnning state" + ) + self.assertNotEqual( + vm.hostid, + host_2.id, + "The host name should not match with second host name" + ) + + self.debug("Canceling host maintenance for ID: %s" % host_1.id) + cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() + cmd.id = host_1.id + self.apiclient.cancelHostMaintenance(cmd) + self.debug("Maintenance mode canceled for host: %s" % host_1.id) + return + + +class TestAffinityRules(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + + cls.api_client = super( + TestAffinityRules, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain( + cls.api_client, + cls.services + ) + cls.zone = get_zone( + cls.api_client, + cls.services + ) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostypeid"] + ) + cls._cleanup = [] + 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, terminate the created accounts, domains etc + cleanup_resources(self.apiclient, self.cleanup) + self.testClient.close() + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def test_vmware_affinity(self): + """ Test Set up affinity rules + + The test requires following pre-requisites + - VMWare cluster configured in fully automated mode + - There should be atleast 2 VMs deployed on one of the clusters + through cloudstack UI manually + - Anti affinity rule should be set on the 2 VMs deployed. + - Add host names to host_1,host_2 and IDs of VM 1,2 in the settings + class "affinity" above. + """ + + # Validate the following + # 1. Deploy VMs 2 VMs on same hosts + # 2. Migrate one VM from one host to another + # 3. The second VM should also get migrated + + hosts = Host.list( + self.apiclient, + zoneid=self.zone.id, + resourcestate='Enabled', + type='Routing' + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should return valid host response" + ) + self.assertGreaterEqual( + len(hosts), + 2, + "There must be two hosts present in a cluster" + ) + self.debug( + "Finding the host details of host_1: %s" % + self.services["affinity"]["host_1"]) + + host_1 = [host for host in hosts if host.name == self.services["affinity"]["host_1"]][0] + + host_2 = [host for host in hosts if host.name == self.services["affinity"]["host_2"]][0] + + vms = VirtualMachine.list( + self.apiclient, + id=self.services["affinity"]["vm_1"], + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + + virtual_machine_1 = vms[0] + self.assertEqual( + virtual_machine_1.state, + "Running", + "Deployed VM should be in RUnning state" + ) + + self.debug("Deploying VM on account: %s" % self.account.account.name) + + vms = VirtualMachine.list( + self.apiclient, + id=self.services["affinity"]["vm_2"], + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + virtual_machine_2 = vms[0] + self.assertEqual( + virtual_machine_2.state, + "Running", + "Deployed VM should be in RUnning state" + ) + + self.debug("Migrate VM from host_1 to host_2") + cmd = migrateVirtualMachine.migrateVirtualMachineCmd() + cmd.virtualmachineid = virtual_machine_2.id + cmd.hostid = host_2.id + self.apiclient.migrateVirtualMachine(cmd) + self.debug("Migrated VM from host_1 to host_2") + + vms = VirtualMachine.list( + self.apiclient, + hostid=host_2.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List VMs should return valid response for deployed VM" + ) + self.assertNotEqual( + len(vms), + 0, + "List VMs should return valid response for deployed VM" + ) + vmids = [vm.id for vm in vms] + self.assertIn( + virtual_machine_1.id, + vmids, + "VM 1 should be successfully migrated to host 2" + ) + self.assertIn( + virtual_machine_2.id, + vmids, + "VM 2 should be automatically migrated to host 2" + ) + return diff --git a/test/integration/lib/base.py b/test/integration/lib/base.py index 04adbc9a030..69882bcb13d 100644 --- a/test/integration/lib/base.py +++ b/test/integration/lib/base.py @@ -171,7 +171,8 @@ class VirtualMachine: @classmethod def create(cls, apiclient, services, templateid=None, accountid=None, domainid=None, networkids=None, serviceofferingid=None, - securitygroupids=None, projectid=None, mode='basic'): + securitygroupids=None, projectid=None, startvm=None, + diskofferingid=None, mode='basic'): """Create the instance""" cmd = deployVirtualMachine.deployVirtualMachineCmd() @@ -204,7 +205,9 @@ class VirtualMachine: elif "template" in services: cmd.templateid = services["template"] - if "diskoffering" in services: + if diskofferingid: + cmd.diskofferingid = diskofferingid + elif "diskoffering" in services: cmd.diskofferingid = services["diskoffering"] if securitygroupids: @@ -216,8 +219,16 @@ class VirtualMachine: if projectid: cmd.projectid = projectid + if startvm is not None: + cmd.startvm = startvm + virtual_machine = apiclient.deployVirtualMachine(cmd) + if startvm == False: + virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress + virtual_machine.public_ip = virtual_machine.nic[0].ipaddress + return VirtualMachine(virtual_machine.__dict__, services) + # VM should be in Running state after deploy timeout = 10 while True: @@ -315,6 +326,14 @@ class VirtualMachine: cmd.id = self.id apiclient.destroyVirtualMachine(cmd) + def migrate(self, apiclient, hostid=None): + """migrate an Instance""" + cmd = migrateVirtualMachine.migrateVirtualMachineCmd() + cmd.virtualmachineid = self.id + if hostid: + cmd.hostid = hostid + apiclient.migrateVirtualMachine(cmd) + def attach_volume(self, apiclient, volume): """Attach volume to instance""" cmd = attachVolume.attachVolumeCmd() @@ -328,6 +347,26 @@ class VirtualMachine: cmd.id = volume.id return apiclient.detachVolume(cmd) + def attach_iso(self, apiclient, iso): + """Attach ISO to instance""" + cmd = attachIso.attachIsoCmd() + cmd.id = iso.id + cmd.virtualmachineid = self.id + return apiclient.attachIso(cmd) + + def detach_iso(self, apiclient): + """Detach ISO to instance""" + cmd = detachIso.detachIsoCmd() + cmd.id = self.id + return apiclient.detachIso(cmd) + + def change_service_offering(self, apiclient, serviceOfferingId): + """Change service offering of the instance""" + cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() + cmd.id = self.id + cmd.serviceofferingid = serviceOfferingId + return apiclient.changeServiceForVirtualMachine(cmd) + @classmethod def list(cls, apiclient, **kwargs): """List all VMs matching criteria""" @@ -343,10 +382,8 @@ class VirtualMachine: cmd.id = self.id try: response = apiclient.resetPasswordForVirtualMachine(cmd) - print response except Exception as e: raise Exception("Reset Password failed! - %s" % e) - print type(response) if isinstance(response, list): return response[0].password @@ -443,6 +480,57 @@ class Volume: [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.listVolumes(cmd)) + @classmethod + def upload(cls, apiclient, services, zoneid=None, account=None, domainid=None): + """Uploads the volume to specified account""" + + cmd = uploadVolume.uploadVolumeCmd() + if zoneid: + cmd.zoneid = zoneid + if account: + cmd.account = account + if domainid: + cmd.domainid = domainid + cmd.format = services["format"] + cmd.name = services["diskname"] + cmd.url = services["url"] + return Volume(apiclient.uploadVolume(cmd).__dict__) + + def wait_for_upload(self, apiclient, timeout=5, interval=60): + """Wait for upload""" + #Sleep to ensure template is in proper state before download + time.sleep(interval) + + while True: + volume_response = Volume.list( + apiclient, + id=self.id, + zoneid=self.zoneid, + templatefilter='self' + ) + if isinstance(volume_response, list): + + volume = volume_response[0] + # If volume is ready, + # volume.state = Allocated + if volue.state == 'Allocated': + break + + elif 'Uploading' in volume.state: + time.sleep(interval) + + elif 'Installing' not in volume.state: + raise Exception( + "Error in uploading volume: status - %s" % + volume.state) + + elif timeout == 0: + break + + else: + time.sleep(interval) + timeout = timeout - 1 + return class Snapshot: """Manage Snapshot Lifecycle @@ -499,7 +587,6 @@ class Template: cmd.ispublic = services["ispublic"] if "ispublic" in services else False cmd.isextractable = services["isextractable"] if "isextractable" in services else False cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False - cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False if volumeid: cmd.volumeid = volumeid @@ -685,7 +772,6 @@ class Iso: response = iso_response[0] # Again initialize timeout to avoid listISO failure timeout = 5 - print response.status # Check whether download is in progress(for Ex:10% Downloaded) # or ISO is 'Successfully Installed' if response.status == 'Successfully Installed': @@ -1006,10 +1092,10 @@ class NetworkOffering: 'provider': provider }) if "servicecapabilitylist" in services: - cmd.servicecapabilitylist = [] + cmd.serviceCapabilityList = [] for service, capability in services["servicecapabilitylist"].items(): for ctype, value in capability.items(): - cmd.servicecapabilitylist.append({ + cmd.serviceCapabilityList.append({ 'service': service, 'capabilitytype': ctype, 'capabilityvalue': value @@ -1018,6 +1104,7 @@ class NetworkOffering: cmd.specifyVlan = services["specifyVlan"] if "specifyIpRanges" in services: cmd.specifyIpRanges = services["specifyIpRanges"] + cmd.availability = 'Optional' [setattr(cmd, k, v) for k, v in kwargs.items()] @@ -1172,19 +1259,19 @@ class LoadBalancerRule: for name, value in param.items(): cmd.param.append({'name': name, 'value': value}) return apiclient.createLBStickinessPolicy(cmd) - + def deleteSticky(self, apiclient, id): """Deletes stickyness policy""" - + cmd = deleteLBStickinessPolicy.deleteLBStickinessPolicyCmd() cmd.id = id return apiclient.deleteLBStickinessPolicy(cmd) - + @classmethod def listStickyPolicies(cls, apiclient, lbruleid, **kwargs): """Lists stickiness policies for load balancing rule""" - - cmd= listLBStickinessPolicies.listLBStickinessPoliciesCmd() + + cmd = listLBStickinessPolicies.listLBStickinessPoliciesCmd() cmd.lbruleid = lbruleid [setattr(cmd, k, v) for k, v in kwargs.items()] return apiclient.listLBStickinessPolicies(cmd) @@ -1443,7 +1530,7 @@ class Network: cmd = restartNetwork.restartNetworkCmd() cmd.id = self.id if cleanup: - cmd.cleanup = cleanup + cmd.cleanup = cleanup return(apiclient.restartNetwork(cmd)) @classmethod @@ -2090,3 +2177,55 @@ class NetworkServiceProvider: cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.listNetworkServiceProviders(cmd)) + +class Router: + """Manage router life cycle""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def start(cls, apiclient, id): + """Starts the router""" + cmd = startRouter.startRouterCmd() + cmd.id = id + return apiclient.startRouter(cmd) + + @classmethod + def stop(cls, apiclient, id, forced=None): + """Stops the router""" + cmd = stopRouter.stopRouterCmd() + cmd.id = id + if forced: + cmd.forced = forced + return apiclient.stopRouter(cmd) + + @classmethod + def reboot(cls, apiclient, id): + """Reboots the router""" + cmd = rebootRouter.rebootRouterCmd() + cmd.id = id + return apiclient.rebootRouter(cmd) + + @classmethod + def destroy(cls, apiclient, id): + """Destroy the router""" + cmd = destroyRouter.destroyRouterCmd() + cmd.id = id + return apiclient.destroyRouter(cmd) + + @classmethod + def change_service_offering(cls, apiclient, id, serviceofferingid): + """Change service offering of the router""" + cmd = changeServiceForRouter.changeServiceForRouterCmd() + cmd.id = id + cmd.serviceofferingid = serviceofferingid + return apiclient.changeServiceForRouter(cmd) + + @classmethod + def list(cls, apiclient, **kwargs): + """List routers""" + + cmd = listRouters.listRoutersCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listRouters(cmd)) diff --git a/tools/testClient/testcase/BVT-tests/README b/test/integration/smoke-simulator/README similarity index 100% rename from tools/testClient/testcase/BVT-tests/README rename to test/integration/smoke-simulator/README diff --git a/tools/testClient/testcase/BVT-tests/__init__.py b/test/integration/smoke-simulator/__init__.py similarity index 100% rename from tools/testClient/testcase/BVT-tests/__init__.py rename to test/integration/smoke-simulator/__init__.py diff --git a/tools/testClient/sandbox/simulator/sandbox.cfg b/test/integration/smoke-simulator/simulator-smoke.cfg similarity index 71% rename from tools/testClient/sandbox/simulator/sandbox.cfg rename to test/integration/smoke-simulator/simulator-smoke.cfg index ee87b0d1a75..4516add3052 100644 --- a/tools/testClient/sandbox/simulator/sandbox.cfg +++ b/test/integration/smoke-simulator/simulator-smoke.cfg @@ -10,22 +10,22 @@ } ], "dns1": "10.147.28.6", - "vlan": "100-500", + "vlan": "100-200", "ipranges": [ { - "startip": "172.2.1.2", - "endip": "172.2.1.252", + "startip": "10.147.31.2", + "endip": "10.147.31.200", "netmask": "255.255.255.0", - "vlan": "30", - "gateway": "172.2.1.1" + "vlan": "31", + "gateway": "10.147.31.1" } ], "networktype": "Advanced", "pods": [ { - "endip": "172.1.2.252", + "endip": "10.147.29.200", "name": "POD0", - "startip": "172.1.2.2", + "startip": "10.147.29.2", "netmask": "255.255.255.0", "clusters": [ { @@ -34,26 +34,31 @@ "hosts": [ { "username": "root", - "url": "http://sim", + "url": "http://sim/c0/h0", + "password": "password" + }, + { + "username": "root", + "url": "http://sim/c0/h1", "password": "password" } ], "clustertype": "CloudManaged", "primaryStorages": [ { - "url": "nfs://172.2.2.6:/export/home/primary", + "url": "nfs://10.147.28.6:/export/home/sandbox/kamakura", "name": "PS0" } ] } ], - "gateway": "172.1.2.1" + "gateway": "10.147.29.1" } ], "internaldns1": "10.147.28.6", "secondaryStorages": [ { - "url": "nfs://172.2.2.6:/export/home/secondary" + "url": "nfs://10.147.28.6:/export/home/sandbox/sstor" } ] } @@ -97,8 +102,8 @@ "value": "10" }, { - "name": "direct.agent.load.size", - "value": "1000" + "name": "use.user.concentrated.pod.allocation", + "value": "false" }, { "name": "account.cleanup.interval", @@ -112,9 +117,17 @@ "name": "expunge.delay", "value": "60" }, + { + "name": "network.gc.wait", + "value": "60" + }, + { + "name": "network.gc.interval", + "value": "60" + }, { "name": "vm.allocation.algorithm", - "value": "userdispersing" + "value": "random" }, { "name": "expunge.interval", @@ -127,6 +140,14 @@ { "name": "check.pod.cidrs", "value": "true" + }, + { + "name": "secstorage.allowed.internal.sites", + "value": "10.147.28.0/24" + }, + { + "name": "direct.agent.load.size", + "value": "1000" } ], "mgtSvr": [ @@ -135,4 +156,4 @@ "port": 8096 } ] -} \ No newline at end of file +} diff --git a/test/integration/smoke-simulator/simulator.properties b/test/integration/smoke-simulator/simulator.properties new file mode 100644 index 00000000000..954e519fb33 --- /dev/null +++ b/test/integration/smoke-simulator/simulator.properties @@ -0,0 +1,11 @@ +DBUSER=cloud +DBPW=cloud +DBROOTPW= +MSLOG=vmops.log +APISERVERLOG=api.log +DBHOST=localhost +AGENTLOGDIR=logs +AGENTLOG=logs/agent.log +MSMNTDIR=/mnt +COMPONENTS-SPEC=components-simulator.xml +AWSAPILOG=awsapi.log diff --git a/test/integration/smoke-simulator/testSetupSuccess.py b/test/integration/smoke-simulator/testSetupSuccess.py new file mode 100644 index 00000000000..ed167a17f20 --- /dev/null +++ b/test/integration/smoke-simulator/testSetupSuccess.py @@ -0,0 +1,64 @@ +import marvin +import unittest +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from time import sleep as delay + +class TestSetupSuccess(cloudstackTestCase): + """ + Test to verify if the cloudstack is ready to launch tests upon + 1. Verify that system VMs are up and running in all zones + 2. Verify that built-in templates are Ready in all zones + """ + @classmethod + def setUpClass(cls): + cls.apiClient = super(TestSetupSuccess, cls).getClsTestClient().getApiClient() + + zones = listZones.listZonesCmd() + cls.zones_list = cls.apiClient.listZones(zones) + cls.retry = 50 + + def test_systemVmReady(self): + """ + system VMs need to be ready and Running for each zone in cloudstack + """ + for z in self.zones_list: + retry = self.retry + while retry != 0: + self.debug("looking for system VMs in zone: %s, %s"%(z.id, z.name)) + sysvms = listSystemVms.listSystemVmsCmd() + sysvms.zoneid = z.id + sysvms.state = 'Running' + sysvms_list = self.apiClient.listSystemVms(sysvms) + if sysvms_list is not None and len(sysvms_list) == 2: + assert len(sysvms_list) == 2 + self.debug("found %d system VMs running {%s}"%(len(sysvms_list), sysvms_list)) + break + retry = retry - 1 + delay(60) #wait a minute for retry + self.assertNotEqual(retry, 0, "system VMs not Running in zone %s"%z.name) + + def test_templateBuiltInReady(self): + """ + built-in templates CentOS to be ready + """ + for z in self.zones_list: + retry = self.retry + while retry != 0: + self.debug("Looking for at least one ready builtin template") + templates = listTemplates.listTemplatesCmd() + templates.templatefilter = 'featured' + templates.listall = 'true' + templates_list = self.apiClient.listTemplates(templates) + if templates_list is not None: + builtins = [tmpl for tmpl in templates_list if tmpl.templatetype == 'BUILTIN' and tmpl.isready == True] + if len(builtins) > 0: + self.debug("Found %d builtins ready for use %s"%(len(builtins), builtins)) + break + retry = retry - 1 + delay(60) #wait a minute for retry + self.assertNotEqual(retry, 0, "builtIn templates not ready in zone %s"%z.name) + + @classmethod + def tearDownClass(cls): + pass diff --git a/tools/testClient/testcase/BVT-tests/test_disk_offerings.py b/test/integration/smoke-simulator/test_disk_offerings.py similarity index 97% rename from tools/testClient/testcase/BVT-tests/test_disk_offerings.py rename to test/integration/smoke-simulator/test_disk_offerings.py index ef72c0a7704..f38e73ba2a7 100644 --- a/tools/testClient/testcase/BVT-tests/test_disk_offerings.py +++ b/test/integration/smoke-simulator/test_disk_offerings.py @@ -14,11 +14,12 @@ """ BVT tests for Disk offerings""" #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * class Services: """Test Disk offerings Services @@ -209,4 +210,4 @@ class TestDiskOfferings(cloudstackTestCase): None, "Check if disk offering exists in listDiskOfferings" ) - return \ No newline at end of file + return diff --git a/tools/testClient/testcase/BVT-tests/test_network.py b/test/integration/smoke-simulator/test_network.py similarity index 74% rename from tools/testClient/testcase/BVT-tests/test_network.py rename to test/integration/smoke-simulator/test_network.py index 234281c213a..d7a984d8d4b 100644 --- a/tools/testClient/testcase/BVT-tests/test_network.py +++ b/test/integration/smoke-simulator/test_network.py @@ -14,12 +14,12 @@ """ BVT tests for Network Life Cycle """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * #Import System modules import time @@ -30,7 +30,7 @@ class Services: def __init__(self): self.services = { - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": '52e14b2f-dea6-46dc-94e1-fba3ee264fc8', # Cent OS 5.3 (64 bit) "mode": 'advanced', # Networking mode: Basic or advanced @@ -96,6 +96,7 @@ class Services: # Algorithm used for load balancing "privateport": 22, "publicport": 2222, + "protocol": 'TCP' } } @@ -130,12 +131,12 @@ class TestPublicIP(cloudstackTestCase): cls.services["network"]["zoneid"] = cls.zone.id cls.network_offering = NetworkOffering.create( - cls.api_client, + 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, @@ -353,26 +354,26 @@ class TestPortForwarding(cloudstackTestCase): account=self.account.account.name, domainid=self.account.account.domainid ) - + self.assertEqual( isinstance(src_nat_ip_addrs, list), True, "Check list response returns a valid list" ) src_nat_ip_addr = src_nat_ip_addrs[0] - + # Check if VM is in Running state before creating NAT rule vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) - + self.assertEqual( isinstance(vm_response, list), True, "Check list VM returns a valid list" ) - + self.assertNotEqual( len(vm_response), 0, @@ -383,6 +384,16 @@ class TestPortForwarding(cloudstackTestCase): 'Running', "VM state should be Running before creating a NAT rule." ) + # Open up firewall port for SSH + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=src_nat_ip_addr.id, + protocol=self.services["natrule"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=self.services["natrule"]["publicport"], + endport=self.services["natrule"]["publicport"] + ) + #Create NAT rule nat_rule = NATRule.create( self.apiclient, @@ -400,7 +411,7 @@ class TestPortForwarding(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_nat_rule_response), 0, @@ -411,21 +422,6 @@ class TestPortForwarding(cloudstackTestCase): nat_rule.id, "Check Correct Port forwarding Rule is returned" ) - #SSH virtual machine to test port forwarding - try: - self.debug("SSHing into VM with IP address %s with NAT IP %s" % - ( - self.virtual_machine.ipaddress, - src_nat_ip_addr.ipaddress - )) - - self.virtual_machine.get_ssh_client(src_nat_ip_addr.ipaddress) - - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) nat_rule.delete(self.apiclient) @@ -439,18 +435,6 @@ class TestPortForwarding(cloudstackTestCase): None, "Check Port Forwarding Rule is deleted" ) - # Check if the Public SSH port is inaccessible - with self.assertRaises(Exception): - self.debug( - "SSHing into VM with IP address %s after NAT rule deletion" % - self.virtual_machine.ipaddress) - - remoteSSHClient.remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.virtual_machine.ssh_port, - self.virtual_machine.username, - self.virtual_machine.password - ) return def test_02_port_fwd_on_non_src_nat(self): @@ -468,19 +452,19 @@ class TestPortForwarding(cloudstackTestCase): self.services["server"] ) self.cleanup.append(ip_address) - + # Check if VM is in Running state before creating NAT rule vm_response = VirtualMachine.list( self.apiclient, id=self.virtual_machine.id ) - + self.assertEqual( isinstance(vm_response, list), True, "Check list VM returns a valid list" ) - + self.assertNotEqual( len(vm_response), 0, @@ -491,7 +475,15 @@ class TestPortForwarding(cloudstackTestCase): 'Running', "VM state should be Running before creating a NAT rule." ) - + # Open up firewall port for SSH + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=ip_address.ipaddress.id, + protocol=self.services["natrule"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=self.services["natrule"]["publicport"], + endport=self.services["natrule"]["publicport"] + ) #Create NAT rule nat_rule = NATRule.create( self.apiclient, @@ -523,19 +515,6 @@ class TestPortForwarding(cloudstackTestCase): "Check Correct Port forwarding Rule is returned" ) - try: - self.debug("SSHing into VM with IP address %s with NAT IP %s" % - ( - self.virtual_machine.ipaddress, - ip_address.ipaddress.ipaddress - )) - self.virtual_machine.get_ssh_client(ip_address.ipaddress.ipaddress) - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - nat_rule.delete(self.apiclient) list_nat_rule_response = list_nat_rules( @@ -547,18 +526,6 @@ class TestPortForwarding(cloudstackTestCase): None, "Check Port Forwarding Rule is deleted" ) - # Check if the Public SSH port is inaccessible - with self.assertRaises(Exception): - self.debug( - "SSHing into VM with IP address %s after NAT rule deletion" % - self.virtual_machine.ipaddress) - - remoteSSHClient.remoteSSHClient( - ip_address.ipaddress.ipaddress, - self.virtual_machine.ssh_port, - self.virtual_machine.username, - self.virtual_machine.password - ) return @@ -613,6 +580,15 @@ class TestLoadBalancingRule(cloudstackTestCase): cls.account.account.domainid, cls.services["server"] ) + # Open up firewall port for SSH + cls.fw_rule = FireWallRule.create( + cls.api_client, + ipaddressid=cls.non_src_nat_ip.ipaddress.id, + protocol=cls.services["lbrule"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=cls.services["lbrule"]["publicport"], + endport=cls.services["lbrule"]["publicport"] + ) cls._cleanup = [ cls.account, cls.service_offering @@ -652,20 +628,20 @@ class TestLoadBalancingRule(cloudstackTestCase): "Check list response returns a valid list" ) src_nat_ip_addr = src_nat_ip_addrs[0] - + # Check if VM is in Running state before creating LB rule vm_response = VirtualMachine.list( self.apiclient, account=self.account.account.name, domainid=self.account.account.domainid ) - + self.assertEqual( isinstance(vm_response, list), True, "Check list VM returns a valid list" ) - + self.assertNotEqual( len(vm_response), 0, @@ -677,7 +653,7 @@ class TestLoadBalancingRule(cloudstackTestCase): 'Running', "VM state should be Running before creating a NAT rule." ) - + #Create Load Balancer rule and assign VMs to rule lb_rule = LoadBalancerRule.create( self.apiclient, @@ -726,12 +702,12 @@ class TestLoadBalancingRule(cloudstackTestCase): 0, "Check Load Balancer instances Rule in its List" ) - self.debug("lb_instance_rules Ids: %s, %s" % ( + self.debug("lb_instance_rules Ids: %s, %s" % ( lb_instance_rules[0].id, lb_instance_rules[1].id )) - self.debug("VM ids: %s, %s" % (self.vm_1.id, self.vm_2.id)) - + self.debug("VM ids: %s, %s" % (self.vm_1.id, self.vm_2.id)) + self.assertIn( lb_instance_rules[0].id, [self.vm_1.id, self.vm_2.id], @@ -743,100 +719,7 @@ class TestLoadBalancingRule(cloudstackTestCase): [self.vm_1.id, self.vm_2.id], "Check List Load Balancer instances Rules returns valid VM ID" ) - try: - self.debug( - "SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)"% - (self.vm_1.ipaddress, src_nat_ip_addr.ipaddress) - ) - - ssh_1 = remoteSSHClient.remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - hostnames = [ssh_1.execute("hostname")[0]] - - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) - - time.sleep(self.services["lb_switch_wait"]) - - try: - self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" % - ( - src_nat_ip_addr.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - - ssh_2 = remoteSSHClient.remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - hostnames.append(ssh_2.execute("hostname")[0]) - - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) - - self.debug("Hostnames: %s" % str(hostnames)) - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_2.name, - hostnames, - "Check if ssh succeeded for server2" - ) - - #SSH should pass till there is a last VM associated with LB rule - lb_rule.remove(self.apiclient, [self.vm_2]) - try: - self.debug("SSHing into IP address: %s after removing VM (ID: %s)" % - ( - src_nat_ip_addr.ipaddress, - self.vm_2.id - )) - - ssh_1 = remoteSSHClient.remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - hostnames.append(ssh_1.execute("hostname")[0]) - - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, src_nat_ip_addr.ipaddress)) - - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - lb_rule.remove(self.apiclient, [self.vm_1]) - - with self.assertRaises(Exception): - self.debug("Removed all VMs, trying to SSH") - ssh_1 = remoteSSHClient.remoteSSHClient( - src_nat_ip_addr.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - ssh_1.execute("hostname")[0] return def test_02_create_lb_rule_non_nat(self): @@ -847,20 +730,20 @@ class TestLoadBalancingRule(cloudstackTestCase): #2. attempt to ssh twice on the load balanced IP #3. verify using the hostname of the VM that # round robin is indeed happening as expected - + # Check if VM is in Running state before creating LB rule vm_response = VirtualMachine.list( self.apiclient, account=self.account.account.name, domainid=self.account.account.domainid ) - + self.assertEqual( isinstance(vm_response, list), True, "Check list VM returns a valid list" ) - + self.assertNotEqual( len(vm_response), 0, @@ -872,7 +755,7 @@ class TestLoadBalancingRule(cloudstackTestCase): 'Running', "VM state should be Running before creating a NAT rule." ) - + #Create Load Balancer rule and assign VMs to rule lb_rule = LoadBalancerRule.create( self.apiclient, @@ -888,7 +771,7 @@ class TestLoadBalancingRule(cloudstackTestCase): self.apiclient, id=lb_rule.id ) - + self.assertEqual( isinstance(lb_rules, list), True, @@ -933,93 +816,6 @@ class TestLoadBalancingRule(cloudstackTestCase): [self.vm_1.id, self.vm_2.id], "Check List Load Balancer instances Rules returns valid VM ID" ) - try: - self.debug("SSHing into IP address: %s after adding VMs (ID: %s , %s)" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - hostnames = [ssh_1.execute("hostname")[0]] - - time.sleep(self.services["lb_switch_wait"]) - - self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_2 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - hostnames.append(ssh_2.execute("hostname")[0]) - self.debug("Hostnames after adding 2 VMs to LB rule: %s" % str(hostnames)) - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_2.name, - hostnames, - "Check if ssh succeeded for server2" - ) - - #SSH should pass till there is a last VM associated with LB rule - lb_rule.remove(self.apiclient, [self.vm_2]) - - self.debug("SSHing into IP address: %s after removing VM (ID: %s) from LB rule" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_2.id - )) - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - - hostnames.append(ssh_1.execute("hostname")[0]) - self.debug("Hostnames after removing VM2: %s" % str(hostnames)) - except Exception as e: - self.fail("%s: SSH failed for VM with IP Address: %s" % - (e, self.non_src_nat_ip.ipaddress.ipaddress)) - - self.assertIn( - self.vm_1.name, - hostnames, - "Check if ssh succeeded for server1" - ) - - lb_rule.remove(self.apiclient, [self.vm_1]) - with self.assertRaises(Exception): - self.fail("SSHing into IP address: %s after removing VM (ID: %s) from LB rule" % - ( - self.non_src_nat_ip.ipaddress.ipaddress, - self.vm_1.id - )) - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress.ipaddress, - self.services['lbrule']["publicport"], - self.vm_1.username, - self.vm_1.password - ) - ssh_1.execute("hostname")[0] return @@ -1059,7 +855,7 @@ class TestRebootRouter(cloudstackTestCase): domainid=self.account.account.domainid, serviceofferingid=self.service_offering.id ) - + src_nat_ip_addrs = list_publicIP( self.apiclient, account=self.account.account.name, @@ -1069,7 +865,7 @@ class TestRebootRouter(cloudstackTestCase): src_nat_ip_addr = src_nat_ip_addrs[0] except Exception as e: raise Exception("Warning: Exception during fetching source NAT: %s" % e) - + self.public_ip = PublicIPAddress.create( self.apiclient, self.vm_1.account, @@ -1077,6 +873,15 @@ class TestRebootRouter(cloudstackTestCase): self.vm_1.domainid, self.services["server"] ) + # Open up firewall port for SSH + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=self.public_ip.ipaddress.id, + protocol=self.services["lbrule"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=self.services["lbrule"]["publicport"], + endport=self.services["lbrule"]["publicport"] + ) lb_rule = LoadBalancerRule.create( self.apiclient, @@ -1119,55 +924,39 @@ class TestRebootRouter(cloudstackTestCase): True, "Check list routers returns a valid list" ) - + router = routers[0] - + self.debug("Rebooting the router (ID: %s)" % router.id) - + cmd = rebootRouter.rebootRouterCmd() cmd.id = router.id self.apiclient.rebootRouter(cmd) - + # Poll listVM to ensure VM is stopped properly timeout = self.services["timeout"] - + while True: time.sleep(self.services["sleep"]) - + # Ensure that VM is in stopped state list_vm_response = list_virtual_machines( self.apiclient, id=self.vm_1.id ) - + if isinstance(list_vm_response, list): - + vm = list_vm_response[0] if vm.state == 'Running': self.debug("VM state: %s" % vm.state) break - - if timeout == 0: + + if timeout == 0: raise Exception( "Failed to start VM (ID: %s) in change service offering" % vm.id) - - timeout = timeout - 1 - #we should be able to SSH after successful reboot - try: - self.debug("SSH into VM (ID : %s ) after reboot" % self.vm_1.id) - - remoteSSHClient.remoteSSHClient( - self.nat_rule.ipaddress, - self.services["natrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.vm_1.ipaddress, e) - ) + timeout = timeout - 1 return def tearDown(self): @@ -1257,20 +1046,30 @@ class TestAssignRemoveLB(cloudstackTestCase): "Check list response returns a valid list" ) self.non_src_nat_ip = src_nat_ip_addrs[0] - + + # Open up firewall port for SSH + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=self.non_src_nat_ip.id, + protocol=self.services["lbrule"]["protocol"], + cidrlist=['0.0.0.0/0'], + startport=self.services["lbrule"]["publicport"], + endport=self.services["lbrule"]["publicport"] + ) + # Check if VM is in Running state before creating LB rule vm_response = VirtualMachine.list( self.apiclient, account=self.account.account.name, domainid=self.account.account.domainid ) - + self.assertEqual( isinstance(vm_response, list), True, "Check list VM returns a valid list" ) - + self.assertNotEqual( len(vm_response), 0, @@ -1282,7 +1081,7 @@ class TestAssignRemoveLB(cloudstackTestCase): 'Running', "VM state should be Running before creating a NAT rule." ) - + lb_rule = LoadBalancerRule.create( self.apiclient, self.services["lbrule"], @@ -1290,131 +1089,9 @@ class TestAssignRemoveLB(cloudstackTestCase): self.account.account.name ) lb_rule.assign(self.apiclient, [self.vm_1, self.vm_2]) - - try: - self.debug("SSHing into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - #Create SSH client for each VM - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - try: - self.debug("SSHing again into IP address: %s with VMs (ID: %s , %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress, - self.vm_1.id, - self.vm_2.id - )) - ssh_2 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_2.username, - self.vm_2.password - ) - - # If Round Robin Algorithm is chosen, - # each ssh command should alternate between VMs - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) - - time.sleep(self.services["lb_switch_wait"]) - - res_2 = ssh_2.execute("hostname")[0] - self.debug(res_2) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_2.name, - res_2, - "Check if ssh succeeded for server2" - ) #Removing VM and assigning another VM to LB rule lb_rule.remove(self.apiclient, [self.vm_2]) - - try: - self.debug("SSHing again into IP address: %s with VM (ID: %s) added to LB rule" % - ( - self.non_src_nat_ip.ipaddress, - self.vm_1.id, - )) - # Again make a SSH connection, as previous is not used after LB remove - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - - lb_rule.assign(self.apiclient, [self.vm_3]) - - try: - ssh_1 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_1.username, - self.vm_1.password - ) - ssh_3 = remoteSSHClient.remoteSSHClient( - self.non_src_nat_ip.ipaddress, - self.services["lbrule"]["publicport"], - self.vm_3.username, - self.vm_3.password - ) - - res_1 = ssh_1.execute("hostname")[0] - self.debug(res_1) - - time.sleep(self.services["lb_switch_wait"]) - - res_3 = ssh_3.execute("hostname")[0] - self.debug(res_3) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.non_src_nat_ip.ipaddress) - - self.assertIn( - self.vm_1.name, - res_1, - "Check if ssh succeeded for server1" - ) - self.assertIn( - self.vm_3.name, - res_3, - "Check if ssh succeeded for server3" - ) return def tearDown(self): @@ -1477,7 +1154,7 @@ class TestReleaseIP(cloudstackTestCase): except Exception as e: raise Exception("Failed: During acquiring source NAT for account: %s" % self.account.account.name) - + self.nat_rule = NATRule.create( self.apiclient, self.virtual_machine, @@ -1501,21 +1178,21 @@ class TestReleaseIP(cloudstackTestCase): def test_releaseIP(self): """Test for Associate/Disassociate public IP address""" - + self.debug("Deleting Public IP : %s" % self.ip_addr.id) - + self.ip_address.delete(self.apiclient) - + # Sleep to ensure that deleted state is reflected in other calls time.sleep(self.services["sleep"]) - + # ListPublicIpAddresses should not list deleted Public IP address list_pub_ip_addr_resp = list_publicIP( self.apiclient, id=self.ip_addr.id ) self.debug("List Public IP response" + str(list_pub_ip_addr_resp)) - + self.assertEqual( list_pub_ip_addr_resp, None, @@ -1542,21 +1219,13 @@ class TestReleaseIP(cloudstackTestCase): id=self.lb_rule.id ) self.debug("List LB Rule response" + str(list_lb_rule)) - + self.assertEqual( list_lb_rule, None, "Check if LB rules for IP Address are no longer available" ) - # SSH Attempt though public IP should fail - with self.assertRaises(Exception): - ssh_2 = remoteSSHClient.remoteSSHClient( - self.ip_addr.ipaddress, - self.services["natrule"]["publicport"], - self.virtual_machine.username, - self.virtual_machine.password - ) return @@ -1602,12 +1271,12 @@ class TestDeleteAccount(cloudstackTestCase): account=self.account.account.name, domainid=self.account.account.domainid ) - + try: src_nat_ip_addr = src_nat_ip_addrs[0] - + except Exception as e: - self.fail("SSH failed for VM with IP: %s" % + self.fail("SSH failed for VM with IP: %s" % src_nat_ip_addr.ipaddress) self.lb_rule = LoadBalancerRule.create( @@ -1617,7 +1286,7 @@ class TestDeleteAccount(cloudstackTestCase): self.account.account.name ) self.lb_rule.assign(self.apiclient, [self.vm_1]) - + self.nat_rule = NATRule.create( self.apiclient, self.vm_1, @@ -1665,14 +1334,14 @@ class TestDeleteAccount(cloudstackTestCase): "Check load balancing rule is properly deleted." ) except Exception as e: - + raise Exception( "Exception raised while fetching LB rules for account: %s" % self.account.account.name) # ListPortForwardingRules should not # list associated rules with deleted account try: - list_nat_reponse= list_nat_rules( + list_nat_reponse = list_nat_rules( self.apiclient, account=self.account.account.name, domainid=self.account.account.domainid @@ -1683,7 +1352,7 @@ class TestDeleteAccount(cloudstackTestCase): "Check load balancing rule is properly deleted." ) except Exception as e: - + raise Exception( "Exception raised while fetching NAT rules for account: %s" % self.account.account.name) @@ -1700,7 +1369,7 @@ class TestDeleteAccount(cloudstackTestCase): "Check routers are properly deleted." ) except Exception as e: - + raise Exception( "Exception raised while fetching routers for account: %s" % self.account.account.name) diff --git a/tools/testClient/testcase/BVT-tests/test_routers.py b/test/integration/smoke-simulator/test_routers.py similarity index 87% rename from tools/testClient/testcase/BVT-tests/test_routers.py rename to test/integration/smoke-simulator/test_routers.py index dca593a842c..7f792484cf1 100644 --- a/tools/testClient/testcase/BVT-tests/test_routers.py +++ b/test/integration/smoke-simulator/test_routers.py @@ -14,13 +14,12 @@ """ BVT tests for routers """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * #Import System modules import time @@ -42,7 +41,7 @@ class Services: { "displayname": "Test VM", "username": "root", - "password": "fr3sca", + "password": "password", "ssh_port": 22, "hypervisor": 'XenServer', "privateport": 22, @@ -54,9 +53,9 @@ class Services: "firstname": "Test", "lastname": "User", "username": "testuser", - "password": "fr3sca", + "password": "password", }, - "ostypeid":'5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid":'52e14b2f-dea6-46dc-94e1-fba3ee264fc8', "sleep": 60, "timeout": 10, "mode": 'advanced', #Networking mode: Basic, Advanced @@ -151,8 +150,7 @@ class TestRouterServices(cloudstackTestCase): self.apiclient, zoneid=router.zoneid, type='Routing', - state='Up', - virtualmachineid=self.vm_1.id + state='Up' ) self.assertEqual( isinstance(hosts, list), @@ -168,23 +166,6 @@ class TestRouterServices(cloudstackTestCase): 'Running', "Check list router response for router state" ) - - result = get_process_status( - host.ipaddress, - self.services['virtual_machine']["publicport"], - self.vm_1.username, - self.vm_1.password, - router.linklocalip, - "service dnsmasq status" - ) - res = str(result) - self.debug("Dnsmasq process status: %s" % res) - - self.assertEqual( - res.count("running"), - 1, - "Check dnsmasq service is running or not" - ) return def test_02_router_internal_adv(self): @@ -213,8 +194,7 @@ class TestRouterServices(cloudstackTestCase): self.apiclient, zoneid=router.zoneid, type='Routing', - state='Up', - virtualmachineid=self.vm_1.id + state='Up' ) self.assertEqual( isinstance(hosts, list), @@ -229,39 +209,6 @@ class TestRouterServices(cloudstackTestCase): 'Running', "Check list router response for router state" ) - - result = get_process_status( - host.ipaddress, - self.services['virtual_machine']["publicport"], - self.vm_1.username, - self.vm_1.password, - router.linklocalip, - "service dnsmasq status" - ) - res = str(result) - self.debug("Dnsmasq process status: %s" % res) - - self.assertEqual( - res.count("running"), - 1, - "Check dnsmasq service is running or not" - ) - - result = get_process_status( - host.ipaddress, - self.services['virtual_machine']["publicport"], - self.vm_1.username, - self.vm_1.password, - router.linklocalip, - "service haproxy status" - ) - res = str(result) - self.assertEqual( - res.count("running"), - 1, - "Check haproxy service is running or not" - ) - self.debug("Haproxy process status: %s" % res) return def test_03_restart_network_cleanup(self): @@ -399,8 +346,7 @@ class TestRouterServices(cloudstackTestCase): self.apiclient, zoneid=router.zoneid, type='Routing', - state='Up', - virtualmachineid=self.vm_1.id + state='Up' ) self.assertEqual( isinstance(hosts, list), @@ -409,38 +355,6 @@ class TestRouterServices(cloudstackTestCase): ) host = hosts[0] - res = get_process_status( - host.ipaddress, - self.services['virtual_machine']["publicport"], - self.vm_1.username, - self.vm_1.password, - router.linklocalip, - "uptime" - ) - - # res = 12:37:14 up 1 min, 0 users, load average: 0.61, 0.22, 0.08 - # Split result to check the uptime - result = res[0].split() - self.debug("Router Uptime: %s" % result) - self.assertEqual( - str(result[1]), - 'up', - "Check router is running or not" - ) - if str(result[3]) == "min,": - self.assertEqual( - (int(result[2]) < 3), - True, - "Check uptime is less than 3 mins or not" - ) - else: - self.assertEqual( - str(result[3]), - 'sec,', - "Check uptime is in seconds" - ) - return - def test_05_router_basic(self): """Test router basic setup """ diff --git a/tools/testClient/testcase/BVT-tests/test_service_offerings.py b/test/integration/smoke-simulator/test_service_offerings.py similarity index 97% rename from tools/testClient/testcase/BVT-tests/test_service_offerings.py rename to test/integration/smoke-simulator/test_service_offerings.py index 125b9dd1ac9..bf9ccd14a6c 100644 --- a/tools/testClient/testcase/BVT-tests/test_service_offerings.py +++ b/test/integration/smoke-simulator/test_service_offerings.py @@ -14,11 +14,12 @@ """ BVT tests for Service offerings""" #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * class Services: diff --git a/tools/testClient/testcase/BVT-tests/test_snapshots.py b/test/integration/smoke-simulator/test_snapshots.py similarity index 67% rename from tools/testClient/testcase/BVT-tests/test_snapshots.py rename to test/integration/smoke-simulator/test_snapshots.py index e877e31934b..8c31a8047fe 100644 --- a/tools/testClient/testcase/BVT-tests/test_snapshots.py +++ b/test/integration/smoke-simulator/test_snapshots.py @@ -14,12 +14,12 @@ """ BVT tests for Snapshots """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * class Services: @@ -35,7 +35,7 @@ class Services: "username": "test", # Random characters are appended for unique # username - "password": "fr3sca", + "password": "password", }, "service_offering": { "name": "Tiny Instance", @@ -88,10 +88,10 @@ class Services: { "displaytext": 'Template from snapshot', "name": 'Template from snapshot', - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": '52e14b2f-dea6-46dc-94e1-fba3ee264fc8', "templatefilter": 'self', }, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": 'adsfasdf', # Cent OS 5.3 (64 bit) "diskdevice": "/dev/xvdb", # Data Disk "rootdisk": "/dev/xvda", # Root Disk @@ -114,7 +114,7 @@ class Services: # Networking mode, Advanced, Basic } - +@unittest.skip("skip snapshot tests") class TestSnapshotRootDisk(cloudstackTestCase): @classmethod @@ -193,10 +193,6 @@ class TestSnapshotRootDisk(cloudstackTestCase): # Validate the following # 1. listSnapshots should list the snapshot that was created. - # 2. verify that secondary storage NFS share contains - # the reqd volume under - # /secondary/snapshots//$account_id/$volumeid/$snapshot_uuid - # 3. verify backup_snap_id was non null in the `snapshots` table volumes = list_volumes( self.apiclient, @@ -255,7 +251,7 @@ class TestSnapshotRootDisk(cloudstackTestCase): self.assertNotEqual( str(snapshot_uuid), - 'NULL', + '', "Check if backup_snap_id is not null" ) @@ -270,71 +266,9 @@ class TestSnapshotRootDisk(cloudstackTestCase): True, "Check list response returns a valid list" ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - try: - # Login to VM to check snapshot present on sec disk - ssh_client = self.virtual_machine_with_disk.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception: - self.fail("SSH failed for Virtual machine: %s" % - self.virtual_machine_with_disk.ipaddress) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for Virtual machine: %s" % - self.virtual_machine_with_disk.ipaddress) - - res = str(uuids) - # Check snapshot UUID in secondary storage and database - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) return - +@unittest.skip("skip snapshot tests") class TestSnapshots(cloudstackTestCase): @classmethod @@ -490,81 +424,10 @@ class TestSnapshots(cloudstackTestCase): self.assertNotEqual( str(snapshot_uuid), - 'NULL', + '', "Check if backup_snap_id is not null" ) - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export - - try: - # Login to VM to check snapshot present on sec disk - ssh_client = self.virtual_machine_with_disk.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine_with_disk.ipaddress) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine_with_disk.ipaddress) - - res = str(uuids) - # Check snapshot UUID in secondary storage and database - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) return def test_03_volume_from_snapshot(self): @@ -573,67 +436,6 @@ class TestSnapshots(cloudstackTestCase): #1. Login to machine; create temp/test directories on data volume #2. Snapshot the Volume #3. Create another Volume from snapshot - #4. Mount/Attach volume to another server - #5. Compare data - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - try: - ssh_client = self.virtual_machine.get_ssh_client() - - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), - ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - list_volume_response = list_volumes( self.apiclient, virtualmachineid=self.virtual_machine.id, @@ -690,62 +492,6 @@ class TestSnapshots(cloudstackTestCase): cmd.virtualmachineid = new_virtual_machine.id self.apiclient.attachVolume(cmd) - try: - #Login to VM to verify test directories and files - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - ] - - for c in cmds: - self.debug(c) - result = ssh.execute(c) - self.debug(result) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) - - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) return def test_04_delete_snapshot(self): @@ -983,59 +729,6 @@ class TestSnapshots(cloudstackTestCase): #5. Login to newly created virtual machine #6. Compare data - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - try: - #Login to virtual machine - ssh_client = self.virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["rootdisk"], - self.services["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), - "sync", - ] - - for c in cmds: - self.debug(c) - result = ssh_client.execute(c) - self.debug(result) - - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - self.virtual_machine.ipaddress) - - # Unmount the Volume - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) - volumes = list_volumes( self.apiclient, virtualmachineid=self.virtual_machine.id, @@ -1100,59 +793,4 @@ class TestSnapshots(cloudstackTestCase): ) self.cleanup.append(new_virtual_machine) - try: - #Login to VM & mount directory - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["rootdisk"], - self.services["mount_dir"] - ) - ] - - for c in cmds: - ssh.execute(c) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - self.debug(returned_data_0) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) - self.debug(returned_data_1) - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - new_virtual_machine.ipaddress) - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the volume - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP address: %s" % - new_virtual_machine.ipaddress) return diff --git a/tools/testClient/testcase/BVT-tests/test_ssvm.py b/test/integration/smoke-simulator/test_ssvm.py similarity index 81% rename from tools/testClient/testcase/BVT-tests/test_ssvm.py rename to test/integration/smoke-simulator/test_ssvm.py index d3e9e7eb3eb..9ee682352ae 100644 --- a/tools/testClient/testcase/BVT-tests/test_ssvm.py +++ b/test/integration/smoke-simulator/test_ssvm.py @@ -14,13 +14,12 @@ """ BVT tests for SSVM """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import telnetlib +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * #Import System modules import time @@ -289,152 +288,6 @@ class TestSSVMs(cloudstackTestCase): ) return - def test_03_ssvm_internals(self): - """Test SSVM Internals""" - - # Validate the following - # 1. The SSVM check script should not return any - # WARN|ERROR|FAIL messages - # 2. If you are unable to login to the SSVM with the signed key - # then test is deemed a failure - # 3. There should be only one ""cloud"" process running within the SSVM - # 4. If no process is running/multiple process are running - # then the test is a failure - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - ssvm = list_ssvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=ssvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - host = hosts[0] - - self.debug("Running SSVM check script") - - result = get_process_status( - host.ipaddress, - self.services['host']["publicport"], - self.services['host']["username"], - self.services['host']["password"], - ssvm.linklocalip, - "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL" - ) - res = str(result) - self.debug("SSVM script output: %s" % res) - - self.assertEqual( - res.count("ERROR"), - 1, - "Check for Errors in tests" - ) - - self.assertEqual( - res.count("WARNING"), - 1, - "Check for warnings in tests" - ) - - #Check status of cloud service - result = get_process_status( - host.ipaddress, - self.services['host']["publicport"], - self.services['host']["username"], - self.services['host']["password"], - ssvm.linklocalip, - "service cloud status" - ) - res = str(result) - self.debug("Cloud Process status: %s" % res) - # cloud.com service (type=secstorage) is running: process id: 2346 - self.assertEqual( - res.count("is running"), - 1, - "Check cloud service is running or not" - ) - return - - def test_04_cpvm_internals(self): - """Test CPVM Internals""" - - # Validate the following - # 1. test that telnet access on 8250 is available to - # the management server for the CPVM - # 2. No telnet access, test FAIL - # 3. Service cloud status should report cloud agent status to be - # running - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - cpvm = list_cpvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=cpvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - host = hosts[0] - - try: - telnet = telnetlib.Telnet( - str(self.apiclient.connection.mgtSvr), - '8250' - ) - self.debug("Telnet management server (IP: %s)" % - self.apiclient.connection.mgtSvr) - except Exception as e: - self.fail( - "Telnet Access failed for %s: %s" % \ - (self.apiclient.connection.mgtSvr, e) - ) - - self.debug("Checking cloud process status") - - result = get_process_status( - host.ipaddress, - self.services['host']["publicport"], - self.services['host']["username"], - self.services['host']["password"], - cpvm.linklocalip, - "service cloud status" - ) - res = str(result) - self.debug("Cloud Process status: %s" % res) - self.assertEqual( - res.count("is running"), - 1, - "Check cloud service is running or not" - ) - return - def test_05_stop_ssvm(self): """Test stop SSVM """ @@ -507,7 +360,6 @@ class TestSSVMs(cloudstackTestCase): ) # Call above tests to ensure SSVM is properly running self.test_01_list_sec_storage_vm() - self.test_03_ssvm_internals() return def test_06_stop_cpvm(self): @@ -579,7 +431,6 @@ class TestSSVMs(cloudstackTestCase): ) # Call above tests to ensure CPVM is properly running self.test_02_list_cpvm_vm() - self.test_04_cpvm_internals() return def test_07_reboot_ssvm(self): @@ -663,8 +514,6 @@ class TestSSVMs(cloudstackTestCase): old_private_ip, "Check Private IP after reboot with that of before reboot" ) - #Call to verify cloud process is running - self.test_03_ssvm_internals() return def test_08_reboot_cpvm(self): @@ -749,8 +598,6 @@ class TestSSVMs(cloudstackTestCase): old_private_ip, "Check Private IP after reboot with that of before reboot" ) - #Call to verify cloud process is running - self.test_04_cpvm_internals() return def test_09_destroy_ssvm(self): @@ -830,8 +677,6 @@ class TestSSVMs(cloudstackTestCase): "Check whether SSVM has public IP field" ) - #Call to verify cloud process is running - self.test_03_ssvm_internals() return def test_10_destroy_cpvm(self): @@ -910,6 +755,4 @@ class TestSSVMs(cloudstackTestCase): "Check whether CPVM has public IP field" ) - #Call to verify cloud process is running - self.test_04_cpvm_internals() return diff --git a/tools/testClient/testcase/BVT-tests/test_vm_life_cycle.py b/test/integration/smoke-simulator/test_vm_life_cycle.py similarity index 74% rename from tools/testClient/testcase/BVT-tests/test_vm_life_cycle.py rename to test/integration/smoke-simulator/test_vm_life_cycle.py index 5c29dbf14cd..0e8497db8cc 100644 --- a/tools/testClient/testcase/BVT-tests/test_vm_life_cycle.py +++ b/test/integration/smoke-simulator/test_vm_life_cycle.py @@ -14,12 +14,12 @@ """ BVT tests for Virtual Machine Life Cycle """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * #Import System modules import time @@ -41,7 +41,7 @@ class Services: "username": "test", # Random characters are appended in create account to # ensure unique username generated each time - "password": "fr3sca", + "password": "password", }, "small": # Create a small virtual machine instance with disk offering @@ -101,18 +101,23 @@ class Services: { "displaytext": "Test ISO", "name": "testISO", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", + "url": "http://nfs1.lab.vmops.com/isos_32bit/dsl-4.4.10.iso", # Source URL where ISO is located - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": '52e14b2f-dea6-46dc-94e1-fba3ee264fc8', "mode": 'HTTP_DOWNLOAD', # Downloading existing ISO }, + "template": { + "displaytext": "Cent OS Template", + "name": "Cent OS Template", + "passwordenabled": True, + }, "diskdevice": '/dev/xvdd', # Disk device where ISO is attached to instance "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": '52e14b2f-dea6-46dc-94e1-fba3ee264fc8', # CentOS 5.3 (64-bit) "mode":'advanced', } @@ -164,7 +169,6 @@ class TestDeployVM(cloudstackTestCase): """ # Validate the following: - # 1. Virtual Machine is accessible via SSH # 2. listVirtualMachines returns accurate information # 3. The Cloud Database contains the valid information @@ -185,20 +189,20 @@ class TestDeployVM(cloudstackTestCase): "Verify listVirtualMachines response for virtual machine: %s" \ % self.virtual_machine.id ) - + self.assertEqual( isinstance(list_vm_response, list), True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_vm_response), 0, "Check VM available in List Virtual Machines" ) vm_response = list_vm_response[0] - + self.assertEqual( vm_response.id, @@ -322,7 +326,7 @@ class TestVMLifeCycle(cloudstackTestCase): self.apiclient, id=self.small_virtual_machine.id ) - + self.assertEqual( isinstance(list_vm_response, list), True, @@ -347,7 +351,7 @@ class TestVMLifeCycle(cloudstackTestCase): # Validate the following # 1. listVM command should return this VM.State # of this VM should be Running". - + self.debug("Starting VM - ID: %s" % self.virtual_machine.id) self.small_virtual_machine.start(self.apiclient) @@ -360,7 +364,7 @@ class TestVMLifeCycle(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_vm_response), 0, @@ -399,7 +403,7 @@ class TestVMLifeCycle(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_vm_response), 0, @@ -422,39 +426,39 @@ class TestVMLifeCycle(cloudstackTestCase): # this Vm matches the one specified for "Small" service offering. # 2. Using listVM command verify that this Vm # has Small service offering Id. - + self.debug("Stopping VM - ID: %s" % self.medium_virtual_machine.id) - + self.medium_virtual_machine.stop(self.apiclient) - + # Poll listVM to ensure VM is stopped properly timeout = self.services["timeout"] - + while True: time.sleep(self.services["sleep"]) - + # Ensure that VM is in stopped state list_vm_response = list_virtual_machines( self.apiclient, id=self.medium_virtual_machine.id ) - + if isinstance(list_vm_response, list): - + vm = list_vm_response[0] if vm.state == 'Stopped': self.debug("VM state: %s" % vm.state) break - - if timeout == 0: + + if timeout == 0: raise Exception( "Failed to stop VM (ID: %s) in change service offering" % vm.id) - + timeout = timeout - 1 - - self.debug("Change Service offering VM - ID: %s" % + + self.debug("Change Service offering VM - ID: %s" % self.medium_virtual_machine.id) - + cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() cmd.id = self.medium_virtual_machine.id cmd.serviceofferingid = self.small_offering.id @@ -462,72 +466,32 @@ class TestVMLifeCycle(cloudstackTestCase): self.debug("Starting VM - ID: %s" % self.medium_virtual_machine.id) self.medium_virtual_machine.start(self.apiclient) - + # Poll listVM to ensure VM is started properly timeout = self.services["timeout"] - + while True: time.sleep(self.services["sleep"]) - + # Ensure that VM is in running state list_vm_response = list_virtual_machines( self.apiclient, id=self.medium_virtual_machine.id ) - + if isinstance(list_vm_response, list): - + vm = list_vm_response[0] if vm.state == 'Running': self.debug("VM state: %s" % vm.state) break - - if timeout == 0: + + if timeout == 0: raise Exception( "Failed to start VM (ID: %s) after changing service offering" % vm.id) - + timeout = timeout - 1 - - try: - ssh = self.medium_virtual_machine.get_ssh_client() - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.medium_virtual_machine.ipaddress, e) - ) - cpuinfo = ssh.execute("cat /proc/cpuinfo") - - cpu_cnt = len([i for i in cpuinfo if "processor" in i]) - #'cpu MHz\t\t: 2660.499' - cpu_speed = [i for i in cpuinfo if "cpu MHz" in i ][0].split()[3] - - meminfo = ssh.execute("cat /proc/meminfo") - #MemTotal: 1017464 kB - total_mem = [i for i in meminfo if "MemTotal" in i][0].split()[1] - - self.debug( - "CPU count: %s, CPU Speed: %s, Mem Info: %s" % ( - cpu_cnt, - cpu_speed, - total_mem - )) - self.assertAlmostEqual( - int(cpu_cnt), - self.small_offering.cpunumber, - "Check CPU Count for small offering" - ) - - self.assertAlmostEqual( - list_vm_response[0].cpuspeed, - self.small_offering.cpuspeed, - "Check CPU Speed for small offering" - ) - self.assertAlmostEqual( - int(total_mem) / 1024, # In MBs - self.small_offering.memory, - "Check Memory(kb) for small offering" - ) return def test_05_change_offering_medium(self): @@ -538,117 +502,76 @@ class TestVMLifeCycle(cloudstackTestCase): # this Vm matches the one specified for "Medium" service offering. # 2. Using listVM command verify that this Vm # has Medium service offering Id. - + self.debug("Stopping VM - ID: %s" % self.small_virtual_machine.id) self.small_virtual_machine.stop(self.apiclient) - + # Poll listVM to ensure VM is stopped properly timeout = self.services["timeout"] - + while True: time.sleep(self.services["sleep"]) - + # Ensure that VM is in stopped state list_vm_response = list_virtual_machines( self.apiclient, id=self.small_virtual_machine.id ) - + if isinstance(list_vm_response, list): - + vm = list_vm_response[0] if vm.state == 'Stopped': self.debug("VM state: %s" % vm.state) break - - if timeout == 0: + + if timeout == 0: raise Exception( "Failed to stop VM (ID: %s) in change service offering" % vm.id) - + timeout = timeout - 1 - - self.debug("Change service offering VM - ID: %s" % + + self.debug("Change service offering VM - ID: %s" % self.small_virtual_machine.id) - + cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd() cmd.id = self.small_virtual_machine.id cmd.serviceofferingid = self.medium_offering.id self.apiclient.changeServiceForVirtualMachine(cmd) - + self.debug("Starting VM - ID: %s" % self.small_virtual_machine.id) self.small_virtual_machine.start(self.apiclient) - + # Poll listVM to ensure VM is started properly timeout = self.services["timeout"] - + while True: time.sleep(self.services["sleep"]) - + # Ensure that VM is in running state list_vm_response = list_virtual_machines( self.apiclient, id=self.small_virtual_machine.id ) - + if isinstance(list_vm_response, list): - + vm = list_vm_response[0] if vm.state == 'Running': self.debug("VM state: %s" % vm.state) break - - if timeout == 0: + + if timeout == 0: raise Exception( "Failed to start VM (ID: %s) after changing service offering" % vm.id) - + timeout = timeout - 1 - + list_vm_response = list_virtual_machines( self.apiclient, id=self.small_virtual_machine.id ) - - try: - ssh_client = self.small_virtual_machine.get_ssh_client() - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.small_virtual_machine.ipaddress, e) - ) - - cpuinfo = ssh_client.execute("cat /proc/cpuinfo") - cpu_cnt = len([i for i in cpuinfo if "processor" in i]) - #'cpu MHz\t\t: 2660.499' - cpu_speed = [i for i in cpuinfo if "cpu MHz" in i][0].split()[3] - - meminfo = ssh_client.execute("cat /proc/meminfo") - #MemTotal: 1017464 kB - total_mem = [i for i in meminfo if "MemTotal" in i][0].split()[1] - - self.debug( - "CPU count: %s, CPU Speed: %s, Mem Info: %s" % ( - cpu_cnt, - cpu_speed, - total_mem - )) - self.assertAlmostEqual( - int(cpu_cnt), - self.medium_offering.cpunumber, - "Check CPU Count for medium offering" - ) - - self.assertAlmostEqual( - list_vm_response[0].cpuspeed, - self.medium_offering.cpuspeed, - "Check CPU Speed for medium offering" - ) - - self.assertAlmostEqual( - int(total_mem) / 1024, # In MBs - self.medium_offering.memory, - "Check Memory(kb) for medium offering" - ) return def test_06_destroy_vm(self): @@ -659,7 +582,7 @@ class TestVMLifeCycle(cloudstackTestCase): # 1. Should not be able to login to the VM. # 2. listVM command should return this VM.State # of this VM should be "Destroyed". - + self.debug("Destroy VM - ID: %s" % self.small_virtual_machine.id) self.small_virtual_machine.delete(self.apiclient) @@ -672,7 +595,7 @@ class TestVMLifeCycle(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_vm_response), 0, @@ -694,9 +617,9 @@ class TestVMLifeCycle(cloudstackTestCase): # 1. listVM command should return this VM. # State of this VM should be "Stopped". # 2. We should be able to Start this VM successfully. - + self.debug("Recovering VM - ID: %s" % self.small_virtual_machine.id) - + cmd = recoverVirtualMachine.recoverVirtualMachineCmd() cmd.id = self.small_virtual_machine.id self.apiclient.recoverVirtualMachine(cmd) @@ -710,7 +633,7 @@ class TestVMLifeCycle(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( len(list_vm_response), 0, @@ -733,21 +656,21 @@ class TestVMLifeCycle(cloudstackTestCase): # 2. listVM command should return this VM.State of this VM # should be "Running" and the host should be the host # to which the VM was migrated to - + hosts = Host.list( - self.apiclient, + self.apiclient, zoneid=self.medium_virtual_machine.zoneid, type='Routing' ) - + self.assertEqual( - isinstance(hosts, list), - True, + isinstance(hosts, list), + True, "Check the number of hosts in the zone" ) self.assertEqual( - len(hosts), - 2, + len(hosts), + 2, "Atleast 2 hosts should be present in a zone for VM migration" ) @@ -756,12 +679,12 @@ class TestVMLifeCycle(cloudstackTestCase): host = hosts[1] else: host = hosts[0] - + self.debug("Migrating VM-ID: %s to Host: %s" % ( self.medium_virtual_machine.id, host.id )) - + cmd = migrateVirtualMachine.migrateVirtualMachineCmd() cmd.hostid = host.id cmd.virtualmachineid = self.medium_virtual_machine.id @@ -776,7 +699,7 @@ class TestVMLifeCycle(cloudstackTestCase): True, "Check list response returns a valid list" ) - + self.assertNotEqual( list_vm_response, None, @@ -803,9 +726,9 @@ class TestVMLifeCycle(cloudstackTestCase): """ # Validate the following # 1. listVM command should NOT return this VM any more. - + self.debug("Expunge VM-ID: %s" % self.small_virtual_machine.id) - + cmd = destroyVirtualMachine.destroyVirtualMachineCmd() cmd.id = self.small_virtual_machine.id self.apiclient.destroyVirtualMachine(cmd) @@ -830,117 +753,3 @@ class TestVMLifeCycle(cloudstackTestCase): ) return - def test_10_attachAndDetach_iso(self): - """Test for detach ISO to virtual machine""" - - # Validate the following - # 1. Create ISO - # 2. Attach ISO to VM - # 3. Log in to the VM. - # 4. The device should be available for use - # 5. Detach ISO - # 6. Check the device is properly detached by logging into VM - - iso = Iso.create( - self.apiclient, - self.services["iso"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.debug("Successfully created ISO with ID: %s" % iso.id) - try: - iso.download(self.apiclient) - except Exception as e: - self.fail("Exception while downloading ISO %s: %s"\ - % (iso.id, e)) - - self.debug("Attach ISO with ID: %s to VM ID: %s" % ( - iso.id, - self.virtual_machine.id - )) - #Attach ISO to virtual machine - cmd = attachIso.attachIsoCmd() - cmd.id = iso.id - cmd.virtualmachineid = self.virtual_machine.id - self.apiclient.attachIso(cmd) - - try: - ssh_client = self.virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount -rt iso9660 %s %s" \ - % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - ] - - for c in cmds: - res = ssh_client.execute(c) - - self.assertEqual(res, [], "Check mount is successful or not") - - c = "fdisk -l|grep %s|head -1" % self.services["diskdevice"] - res = ssh_client.execute(c) - #Disk /dev/xvdd: 4393 MB, 4393723904 bytes - - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Res may contain more than one strings depending on environment - # Split strings to form new list which is used for assertion on ISO size - result = [] - for i in res: - for k in i.split(): - result.append(k) - - # Get ISO size - iso_response = list_isos( - self.apiclient, - id=iso.id - ) - self.assertEqual( - isinstance(iso_response, list), - True, - "Check list response returns a valid list" - ) - iso_size = iso_response[0].size - - self.assertEqual( - str(iso_size) in result, - True, - "Check size of the attached ISO" - ) - try: - #Unmount ISO - command = "umount %s" % self.services["mount_dir"] - ssh_client.execute(command) - - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - #Detach from VM - cmd = detachIso.detachIsoCmd() - cmd.virtualmachineid = self.virtual_machine.id - self.apiclient.detachIso(cmd) - - try: - res = ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Check if ISO is properly detached from VM (using fdisk) - result = self.services["diskdevice"] in str(res) - - self.assertEqual( - result, - False, - "Check if ISO is detached from virtual machine" - ) - return diff --git a/tools/testClient/testcase/BVT-tests/test_volumes.py b/test/integration/smoke-simulator/test_volumes.py similarity index 88% rename from tools/testClient/testcase/BVT-tests/test_volumes.py rename to test/integration/smoke-simulator/test_volumes.py index 4f250d5e3d9..d7c1487c077 100644 --- a/tools/testClient/testcase/BVT-tests/test_volumes.py +++ b/test/integration/smoke-simulator/test_volumes.py @@ -14,17 +14,16 @@ """ BVT tests for Volumes """ #Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient +import marvin +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from integration.lib.utils import * +from integration.lib.base import * +from integration.lib.common import * #Import System modules import os import urllib import time -import tempfile class Services: @@ -40,7 +39,7 @@ class Services: "username": "test", # Random characters are appended for unique # username - "password": "fr3sca", + "password": "password", }, "service_offering": { "name": "Tiny Instance", @@ -69,7 +68,7 @@ class Services: "publicport": 22, "protocol": 'TCP', "diskdevice": "/dev/xvdb", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', + "ostypeid": '52e14b2f-dea6-46dc-94e1-fba3ee264fc8', "mode": 'advanced', "sleep": 60, "timeout": 10, @@ -194,14 +193,6 @@ class TestCreateVolume(cloudstackTestCase): self.apiClient, volume ) - try: - ssh = self.virtual_machine.get_ssh_client() - ssh.execute("reboot") - - except Exception as e: - self.fail("SSH access failed for VM %s - %s" % - (self.virtual_machine.ipaddress, e)) - # Poll listVM to ensure VM is started properly timeout = self.services["timeout"] while True: @@ -226,27 +217,6 @@ class TestCreateVolume(cloudstackTestCase): timeout = timeout - 1 - try: - ssh = self.virtual_machine.get_ssh_client( - reconnect=True - ) - c = "fdisk -l" - res = ssh.execute(c) - - except Exception as e: - self.fail("SSH access failed for VM: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Disk /dev/sda doesn't contain a valid partition table - # Disk /dev/sda: 21.5 GB, 21474836480 bytes - result = str(res) - self.debug("fdisk result: %s" % result) - - self.assertEqual( - str(list_volume_response[0].size) in result, - True, - "Check if promised disk size actually available" - ) self.virtual_machine.detach_volume(self.apiClient, volume) def tearDown(self): @@ -365,14 +335,6 @@ class TestVolumes(cloudstackTestCase): None, "Check if volume state (attached) is reflected" ) - try: - #Format the attached volume to a known fs - format_volume_to_ext3(self.virtual_machine.get_ssh_client()) - - except Exception as e: - - self.fail("SSH failed for VM: %s - %s" % - (self.virtual_machine.ipaddress, e)) return def test_03_download_attached_volume(self): @@ -471,22 +433,6 @@ class TestVolumes(cloudstackTestCase): cmd.zoneid = self.services["zoneid"] extract_vol = self.apiClient.extractVolume(cmd) - #Attempt to download the volume and save contents locally - try: - formatted_url = urllib.unquote_plus(extract_vol.url) - response = urllib.urlopen(formatted_url) - fd, path = tempfile.mkstemp() - os.close(fd) - fd = open(path, 'wb') - fd.write(response.read()) - fd.close() - - except Exception: - self.fail( - "Extract Volume Failed with invalid URL %s (vol id: %s)" \ - % (extract_vol.url, self.volume.id) - ) - def test_07_delete_detached_volume(self): """Delete a Volume unattached to an VM """ @@ -513,4 +459,4 @@ class TestVolumes(cloudstackTestCase): None, "Check if volume exists in ListVolumes" ) - return \ No newline at end of file + return diff --git a/test/setup.sh b/test/setup.sh new file mode 100755 index 00000000000..623fc7631c5 --- /dev/null +++ b/test/setup.sh @@ -0,0 +1,72 @@ +#!/bin/bash +usage() { + printf "Usage: %s:\n + [-t path to tests ] \n + [-m mgmt-server ] \n + [-c config-file ] \n + [-d db node url ]\n" $(basename $0) >&2 +} + +failed() { + exit $1 +} + +#defaults +FMT=$(date +"%d_%I_%Y_%s") +MGMT_SVR="localhost" +BASEDIR="/root/cloudstack-oss/test" +TESTDIR="/root/cloudstack-oss/test/integration/smoke-simulator/" +CONFIG="/root/cloudstack-oss/test/integration/smoke-simulator/simulator-smoke.cfg" +DB_SVR="localhost" + +while getopts 't:d:m:c:' OPTION +do + case $OPTION in + d) dflag=1 + DB_SVR="$OPTARG" + ;; + t) tflag=1 + TESTDIR="$OPTARG" + ;; + m) mflag=1 + MGMT_SVR="$OPTARG" + ;; + c) cflag=1 + CONFIG="$OPTARG" + ;; + ?) usage + failed 2 + ;; + esac +done + +ostypeid=$(mysql -uroot -Dcloud -h$MGMT_SVR -s -N -r -e"select uuid from guest_os where id=11") +$(mysql -uroot -Dcloud -h$MGMT_SVR -s -N -r -e"update configuration set value='8096' where name='integration.api.port'") + +pushd $BASEDIR +for file in `find $TESTDIR -name *.py -type f` +do + old_ostypeid=$(grep ostypeid $file | head -1 | cut -d: -f2 | tr -d " ,'") + if [[ $old_ostypeid != "" ]] + then + echo "replacing:" $old_ostypeid, "with:" $ostypeid,"in " $file + sed -i "s/$old_ostypeid/$ostypeid/g" $file + sed -i "s/http:\/\/iso.linuxquestions.org\/download\/504\/1819\/http\/gd4.tuwien.ac.at\/dsl-4.4.10.iso/http:\/\/nfs1.lab.vmops.com\/isos_32bit\/dsl-4.4.10.iso/g" $file + sed -i "s/fr3sca/password/g" $file + fi +done + +version_tuple=$(python -c 'import sys; print(sys.version_info[:2])') + +if [[ $version_tuple == "(2, 7)" ]] +then + python -m marvin.deployAndRun -c $CONFIG -t /tmp/t.log -r /tmp/r.log -d /tmp + sleep 60 + python -m marvin.deployAndRun -c $CONFIG -t /tmp/t.log -r /tmp/r.log -f $TESTDIR/testSetupSuccess.py -l + cat /tmp/r.log + python -m marvin.deployAndRun -c $CONFIG -t /tmp/t.log -r /tmp/r.log -d $TESTDIR -l + echo "Done" +else + echo "Python version 2.7 not detected on system. Aborting" +fi +popd diff --git a/tools/marvin/marvin/TestCaseExecuteEngine.py b/tools/marvin/marvin/TestCaseExecuteEngine.py index 67ed14a6aab..ccb8bf728d1 100644 --- a/tools/marvin/marvin/TestCaseExecuteEngine.py +++ b/tools/marvin/marvin/TestCaseExecuteEngine.py @@ -87,4 +87,4 @@ class TestCaseExecuteEngine(object): if self.format == "text": unittest.TextTestRunner(stream=self.testResultLogFile, verbosity=2).run(self.suite) elif self.format == "xml": - xmlrunner.XMLTestRunner(output=self.testResultLogFile, verbose=True).run(self.suite) \ No newline at end of file + xmlrunner.XMLTestRunner(output='xml-reports', verbose=True).run(self.suite) \ No newline at end of file diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 39b5e4e6f26..5c7880e60ae 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -83,7 +83,7 @@ class deployDataCenters(): primarycmd.clusterid = clusterId self.apiClient.createStoragePool(primarycmd) - def createpods(self, pods, zone, zoneId): + def createpods(self, pods, zone, zoneId, networkId=None): if pods is None: return for pod in pods: @@ -97,9 +97,9 @@ class deployDataCenters(): createpodResponse = self.apiClient.createPod(createpod) podId = createpodResponse.id - if pod.guestIpRanges is not None: + if pod.guestIpRanges is not None and networkId is not None: self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId,\ - podId) + podId, networkId) self.createClusters(pod.clusters, zoneId, podId) @@ -155,8 +155,7 @@ class deployDataCenters(): networkcmdresponse = self.apiClient.createNetwork(networkcmd) networkId = networkcmdresponse.id - - self.createVlanIpRanges(mode, ipranges, zoneId, networkId) + return networkId def createPhysicalNetwork(self, name, zoneid, vlan=None): phynet = createPhysicalNetwork.createPhysicalNetworkCmd() @@ -249,13 +248,12 @@ class deployDataCenters(): phynetwrk = self.createPhysicalNetwork(zone.name + "-pnet", \ zoneId) - self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \ - "Management"]) - self.configureProviders(phynetwrk, zone) self.updatePhysicalNetwork(phynetwrk.id, "Enabled", vlan=zone.vlan) if zone.networktype == "Basic": + self.addTrafficTypes(phynetwrk.id, ["Guest", "Management"]) + listnetworkoffering = \ listNetworkOfferings.listNetworkOfferingsCmd() @@ -271,11 +269,13 @@ class deployDataCenters(): guestntwrk.zoneid = zoneId guestntwrk.networkofferingid = \ listnetworkofferingresponse[0].id - self.createnetworks([guestntwrk], zoneId, zone.networktype) - - self.createpods(zone.pods, zone, zoneId) + networkid = self.createnetworks([guestntwrk], zoneId, zone.networktype) + self.createpods(zone.pods, zone, zoneId, networkid) if zone.networktype == "Advanced": + self.createpods(zone.pods, zone, zoneId) + self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \ + "Management"]) self.createVlanIpRanges(zone.networktype, zone.ipranges, \ zoneId) diff --git a/tools/marvin/marvin/remoteSSHClient.py b/tools/marvin/marvin/remoteSSHClient.py index 8836844dc9f..6d9a1751fe8 100644 --- a/tools/marvin/marvin/remoteSSHClient.py +++ b/tools/marvin/marvin/remoteSSHClient.py @@ -53,6 +53,14 @@ class remoteSSHClient(object): return results + def scp(self, srcFile, destPath): + transport = paramiko.Transport((self.host, int(self.port))) + transport.connect(username = self.user, password=self.passwd) + sftp = paramiko.SFTPClient.from_transport(transport) + try: + sftp.put(srcFile, destPath) + except IOError, e: + raise e if __name__ == "__main__": ssh = remoteSSHClient("192.168.137.2", 22, "root", "password") diff --git a/tools/marvin/marvin/sandbox/advanced/advanced_env.py b/tools/marvin/marvin/sandbox/advanced/advanced_env.py index 25e83dbb0f4..701a3a3f58a 100644 --- a/tools/marvin/marvin/sandbox/advanced/advanced_env.py +++ b/tools/marvin/marvin/sandbox/advanced/advanced_env.py @@ -7,11 +7,11 @@ # * Only a sandbox ############################################################ ''' - +import random +import marvin from ConfigParser import SafeConfigParser from optparse import OptionParser -from configGenerator import * -import random +from marvin.configGenerator import * def getGlobalSettings(config): @@ -28,7 +28,7 @@ def describeResources(config): z = zone() z.dns1 = config.get('environment', 'dns') z.internaldns1 = config.get('environment', 'dns') - z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) + z.name = 'Sandbox-%s'%(config.get('cloudstack', 'hypervisor')) z.networktype = 'Advanced' z.guestcidraddress = '10.1.1.0/24' @@ -37,37 +37,37 @@ def describeResources(config): p.gateway = config.get('cloudstack', 'private.gateway') p.startip = config.get('cloudstack', 'private.pod.startip') p.endip = config.get('cloudstack', 'private.pod.endip') - p.netmask = '255.255.255.0' + p.netmask = config.get('cloudstack', 'private.netmask') v = iprange() v.gateway = config.get('cloudstack', 'public.gateway') v.startip = config.get('cloudstack', 'public.vlan.startip') v.endip = config.get('cloudstack', 'public.vlan.endip') - v.netmask = '255.255.255.0' + v.netmask = config.get('cloudstack', 'public.netmask') v.vlan = config.get('cloudstack', 'public.vlan') z.ipranges.append(v) c = cluster() c.clustername = 'C0' - c.hypervisor = config.get('environment', 'hypervisor') + c.hypervisor = config.get('cloudstack', 'hypervisor') c.clustertype = 'CloudManaged' h = host() h.username = 'root' - h.password = 'password' + h.password = config.get('cloudstack', 'host.password') h.url = 'http://%s'%(config.get('cloudstack', 'host')) c.hosts.append(h) ps = primaryStorage() ps.name = 'PS0' - ps.url = config.get('cloudstack', 'pool') + ps.url = config.get('cloudstack', 'primary.pool') c.primaryStorages.append(ps) p.clusters.append(c) z.pods.append(p) secondary = secondaryStorage() - secondary.url = config.get('cloudstack', 'secondary') + secondary.url = config.get('cloudstack', 'secondary.pool') z.secondaryStorages.append(secondary) '''Add zone''' @@ -80,7 +80,9 @@ def describeResources(config): '''Add a database''' db = dbServer() - db.dbSvr = config.get('environment', 'database') + db.dbSvr = config.get('environment', 'mysql.host') + db.user = config.get('environment', 'mysql.cloud.user') + db.passwd = config.get('environment', 'mysql.cloud.passwd') zs.dbSvr = db '''Add some configuration''' diff --git a/tools/marvin/marvin/sandbox/advanced/setup.properties b/tools/marvin/marvin/sandbox/advanced/setup.properties index 48b082e4f37..9c025f58aa2 100644 --- a/tools/marvin/marvin/sandbox/advanced/setup.properties +++ b/tools/marvin/marvin/sandbox/advanced/setup.properties @@ -1,4 +1,5 @@ [globals] +#global settings in cloudstack expunge.delay=60 expunge.interval=60 storage.cleanup.interval=300 @@ -17,20 +18,27 @@ secstorage.allowed.internal.sites=10.147.28.0/24 [environment] dns=10.147.28.6 mshost=10.147.29.111 -database=10.147.29.111 +mysql.host=10.147.29.111 +mysql.cloud.user=cloud +mysql.cloud.passwd=cloud [cloudstack] +#guest VLAN zone.vlan=675-679 -#pod configuration +#management network private.gateway=10.147.29.1 private.pod.startip=10.147.29.150 private.pod.endip=10.147.29.159 -#public vlan range +private.netmask=255.255.255.0 +#public network public.gateway=10.147.31.1 public.vlan=31 public.vlan.startip=10.147.31.150 public.vlan.endip=10.147.31.159 -#hosts +public.netmask=255.255.255.0 +#hypervisor host information +hypervisor=XenServer host=10.147.29.58 -#pools -pool=nfs://10.147.28.6:/export/home/sandbox/kamakura -secondary=nfs://10.147.28.6:/export/home/sandbox/sstor +host.password=password +#storage pools +primary.pool=nfs://10.147.28.6:/export/home/sandbox/kamakura +secondary.pool=nfs://10.147.28.6:/export/home/sandbox/sstor diff --git a/tools/marvin/marvin/sandbox/basic/basic_env.py b/tools/marvin/marvin/sandbox/basic/basic_env.py index e69de29bb2d..07b6a9b7008 100644 --- a/tools/marvin/marvin/sandbox/basic/basic_env.py +++ b/tools/marvin/marvin/sandbox/basic/basic_env.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +''' +############################################################ +# Experimental state of scripts +# * Need to be reviewed +# * Only a sandbox +############################################################ +''' +import random +import marvin +from ConfigParser import SafeConfigParser +from optparse import OptionParser +from marvin.configGenerator import * + + +def getGlobalSettings(config): + for k, v in dict(config.items('globals')).iteritems(): + cfg = configuration() + cfg.name = k + cfg.value = v + yield cfg + + +def describeResources(config): + zs = cloudstackConfiguration() + + z = zone() + z.dns1 = config.get('environment', 'dns') + z.internaldns1 = config.get('environment', 'dns') + z.name = 'Sandbox-%s'%(config.get('cloudstack', 'hypervisor')) + z.networktype = 'Basic' + z.securitygroupenabled = 'true' + + p = pod() + p.name = 'POD0' + p.gateway = config.get('cloudstack', 'private.gateway') + p.startip = config.get('cloudstack', 'private.pod.startip') + p.endip = config.get('cloudstack', 'private.pod.endip') + p.netmask = config.get('cloudstack', 'private.netmask') + + v = iprange() + v.gateway = config.get('cloudstack', 'public.gateway') + v.startip = config.get('cloudstack', 'public.vlan.startip') + v.endip = config.get('cloudstack', 'public.vlan.endip') + v.netmask = config.get('cloudstack', 'public.netmask') + p.guestIpRanges.append(v) + + c = cluster() + c.clustername = 'C0' + c.hypervisor = config.get('cloudstack', 'hypervisor') + c.clustertype = 'CloudManaged' + + h = host() + h.username = 'root' + h.password = config.get('cloudstack', 'host.password') + h.url = 'http://%s'%(config.get('cloudstack', 'host')) + c.hosts.append(h) + + ps = primaryStorage() + ps.name = 'PS0' + ps.url = config.get('cloudstack', 'primary.pool') + c.primaryStorages.append(ps) + + p.clusters.append(c) + z.pods.append(p) + + secondary = secondaryStorage() + secondary.url = config.get('cloudstack', 'secondary.pool') + z.secondaryStorages.append(secondary) + + '''Add zone''' + zs.zones.append(z) + + '''Add mgt server''' + mgt = managementServer() + mgt.mgtSvrIp = config.get('environment', 'mshost') + zs.mgtSvr.append(mgt) + + '''Add a database''' + db = dbServer() + db.dbSvr = config.get('environment', 'mysql.host') + db.user = config.get('environment', 'mysql.cloud.user') + db.passwd = config.get('environment', 'mysql.cloud.passwd') + zs.dbSvr = db + + '''Add some configuration''' + [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)] + + ''''add loggers''' + testClientLogger = logger() + testClientLogger.name = 'TestClient' + testClientLogger.file = '/var/log/testclient.log' + + testCaseLogger = logger() + testCaseLogger.name = 'TestCase' + testCaseLogger.file = '/var/log/testcase.log' + + zs.logger.append(testClientLogger) + zs.logger.append(testCaseLogger) + return zs + + +if __name__ == '__main__': + parser = OptionParser() + parser.add_option('-i', '--input', action='store', default='setup.properties', \ + dest='input', help='file containing environment setup information') + parser.add_option('-o', '--output', action='store', default='./sandbox.cfg', \ + dest='output', help='path where environment json will be generated') + + + (opts, args) = parser.parse_args() + + cfg_parser = SafeConfigParser() + cfg_parser.read(opts.input) + + cfg = describeResources(cfg_parser) + generate_setup_config(cfg, opts.output) diff --git a/tools/testClient/sandbox/advanced/setup.properties b/tools/marvin/marvin/sandbox/basic/setup.properties similarity index 59% rename from tools/testClient/sandbox/advanced/setup.properties rename to tools/marvin/marvin/sandbox/basic/setup.properties index a90630c13f8..08cdb79abea 100644 --- a/tools/testClient/sandbox/advanced/setup.properties +++ b/tools/marvin/marvin/sandbox/basic/setup.properties @@ -1,4 +1,5 @@ [globals] +#global settings in cloudstack expunge.delay=60 expunge.interval=60 storage.cleanup.interval=300 @@ -16,21 +17,27 @@ check.pod.cidrs=true secstorage.allowed.internal.sites=10.147.28.0/24 [environment] dns=10.147.28.6 -mshost=10.147.29.111 -database=10.147.29.111 +mshost=localhost +mysql.host=localhost +mysql.cloud.user=cloud +mysql.cloud.passwd=cloud [cloudstack] +#guest VLAN zone.vlan=675-679 -#pod configuration +#management network private.gateway=10.147.29.1 private.pod.startip=10.147.29.150 private.pod.endip=10.147.29.159 -#public vlan range +private.netmask=255.255.255.0 +#public network public.gateway=10.147.31.1 -public.vlan=31 public.vlan.startip=10.147.31.150 public.vlan.endip=10.147.31.159 -#hosts -host=10.147.29.58 -#pools -pool=nfs://10.147.28.6:/export/home/prasanna/kamakura -secondary=nfs://10.147.28.6:/export/home/prasanna/sstor +public.netmask=255.255.255.0 +#hypervisor host information +hypervisor=Simulator +host=sim +host.password=password +#storage pools +primary.pool=nfs://10.147.28.6:/export/home/sandbox/kamakura +secondary.pool=nfs://10.147.28.6:/export/home/sandbox/sstor diff --git a/tools/marvin/marvin/testSetupSuccess.py b/tools/marvin/marvin/testSetupSuccess.py new file mode 100644 index 00000000000..ed167a17f20 --- /dev/null +++ b/tools/marvin/marvin/testSetupSuccess.py @@ -0,0 +1,64 @@ +import marvin +import unittest +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from time import sleep as delay + +class TestSetupSuccess(cloudstackTestCase): + """ + Test to verify if the cloudstack is ready to launch tests upon + 1. Verify that system VMs are up and running in all zones + 2. Verify that built-in templates are Ready in all zones + """ + @classmethod + def setUpClass(cls): + cls.apiClient = super(TestSetupSuccess, cls).getClsTestClient().getApiClient() + + zones = listZones.listZonesCmd() + cls.zones_list = cls.apiClient.listZones(zones) + cls.retry = 50 + + def test_systemVmReady(self): + """ + system VMs need to be ready and Running for each zone in cloudstack + """ + for z in self.zones_list: + retry = self.retry + while retry != 0: + self.debug("looking for system VMs in zone: %s, %s"%(z.id, z.name)) + sysvms = listSystemVms.listSystemVmsCmd() + sysvms.zoneid = z.id + sysvms.state = 'Running' + sysvms_list = self.apiClient.listSystemVms(sysvms) + if sysvms_list is not None and len(sysvms_list) == 2: + assert len(sysvms_list) == 2 + self.debug("found %d system VMs running {%s}"%(len(sysvms_list), sysvms_list)) + break + retry = retry - 1 + delay(60) #wait a minute for retry + self.assertNotEqual(retry, 0, "system VMs not Running in zone %s"%z.name) + + def test_templateBuiltInReady(self): + """ + built-in templates CentOS to be ready + """ + for z in self.zones_list: + retry = self.retry + while retry != 0: + self.debug("Looking for at least one ready builtin template") + templates = listTemplates.listTemplatesCmd() + templates.templatefilter = 'featured' + templates.listall = 'true' + templates_list = self.apiClient.listTemplates(templates) + if templates_list is not None: + builtins = [tmpl for tmpl in templates_list if tmpl.templatetype == 'BUILTIN' and tmpl.isready == True] + if len(builtins) > 0: + self.debug("Found %d builtins ready for use %s"%(len(builtins), builtins)) + break + retry = retry - 1 + delay(60) #wait a minute for retry + self.assertNotEqual(retry, 0, "builtIn templates not ready in zone %s"%z.name) + + @classmethod + def tearDownClass(cls): + pass diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 83c9c8a0a32..9706e32a7cf 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -20,11 +20,11 @@ setup(name="Marvin", long_description="Marvin is the cloudstack testclient written around the python unittest framework", platforms=("Any",), url="http://jenkins.cloudstack.org:8080/job/marvin", - packages=["marvin", "marvin.cloudstackAPI", "marvin.sandbox", "marvin.pymysql", "marvin.pymysql.constants", "marvin.pymysql.tests"], + packages=["marvin", "marvin.cloudstackAPI", "marvin.sandbox", "marvin.sandbox.advanced", "marvin.sandbox.basic", "marvin.pymysql", "marvin.pymysql.constants", "marvin.pymysql.tests"], license="LICENSE.txt", install_requires=[ - "Python>=2.7", "paramiko", - "nose" + "nose", + "unittest-xml-reporting" ], ) diff --git a/tools/testClient/.project b/tools/testClient/.project deleted file mode 100644 index c6e95d9c21b..00000000000 --- a/tools/testClient/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - testClient - - - - - - org.python.pydev.PyDevBuilder - - - - - - org.python.pydev.pythonNature - - diff --git a/tools/testClient/.pydevproject b/tools/testClient/.pydevproject deleted file mode 100644 index 505117b6626..00000000000 --- a/tools/testClient/.pydevproject +++ /dev/null @@ -1,10 +0,0 @@ - - - - -Default -python 2.7 - -/testClient/ - - diff --git a/tools/testClient/README b/tools/testClient/README deleted file mode 100644 index d2fc5129c06..00000000000 --- a/tools/testClient/README +++ /dev/null @@ -1,24 +0,0 @@ -CloudStack Test Client - -0. Generate API XML spec file - ant build-apidocs, the output xml file is dist/commands.xml - -1. generate Cloudstack API python code from an API XML spec file generated by step 0 - python codegenerator.py -o where-to-put-the-cloudstack-api -s where-the-spec-file - -1a. If you will be running XML based tests, you will need to run them through the - translator script. To do that execute translator.py -h for command line help. - Example: - python translator.py -i example.xml - - this will create an example.xml.py script in the current directory. Run - that to run the test. - - -2. Facility it provides: - 1. very handy cloudstack API python wrapper - 2. support async job executing in parallel - 3. remote ssh login/execute command - 4. mysql query - -3. sample code is under unitTest diff --git a/tools/testClient/TestCaseExecuteEngine.py b/tools/testClient/TestCaseExecuteEngine.py deleted file mode 100644 index 77ca95b694c..00000000000 --- a/tools/testClient/TestCaseExecuteEngine.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -try: - import unittest2 as unittest -except ImportError: - import unittest - -from functools import partial -import os -import sys -import logging - -def testCaseLogger(message, logger=None): - if logger is not None: - logger.debug(message) - -class TestCaseExecuteEngine(object): - def __init__(self, testclient, testCaseFolder, testcaseLogFile=None, testResultLogFile=None): - self.testclient = testclient - self.testCaseFolder = testCaseFolder - self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") - - if testcaseLogFile is not None: - self.logfile = testcaseLogFile - self.logger = logging.getLogger("TestCaseExecuteEngine") - fh = logging.FileHandler(self.logfile) - fh.setFormatter(self.logformat) - self.logger.addHandler(fh) - self.logger.setLevel(logging.DEBUG) - if testResultLogFile is not None: - ch = logging.StreamHandler() - ch.setLevel(logging.ERROR) - ch.setFormatter(self.logformat) - self.logger.addHandler(ch) - fp = open(testResultLogFile, "w") - self.testResultLogFile = fp - else: - self.testResultLogFile = sys.stdout - - def injectTestCase(self, testSuites): - for test in testSuites: - if isinstance(test, unittest.BaseTestSuite): - self.injectTestCase(test) - else: - #logger bears the name of the test class - testcaselogger = logging.getLogger("testclient.testcase.%s"%test.__class__.__name__) - fh = logging.FileHandler(self.logfile) - fh.setFormatter(self.logformat) - testcaselogger.addHandler(fh) - testcaselogger.setLevel(logging.DEBUG) - - #inject testclient and logger into each unittest - setattr(test, "testClient", self.testclient) - setattr(test, "debug", partial(testCaseLogger, logger=testcaselogger)) - setattr(test.__class__, "clstestclient", self.testclient) - if hasattr(test, "UserName"): - self.testclient.createNewApiClient(test.UserName, test.DomainName, test.AcctType) - - def run(self): - loader = unittest.loader.TestLoader() - suite = loader.discover(self.testCaseFolder) - self.injectTestCase(suite) - - unittest.TextTestRunner(stream=self.testResultLogFile, verbosity=2).run(suite) diff --git a/tools/testClient/__init__.py b/tools/testClient/__init__.py deleted file mode 100644 index 37f96cecb27..00000000000 --- a/tools/testClient/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 diff --git a/tools/testClient/asyncJobMgr.py b/tools/testClient/asyncJobMgr.py deleted file mode 100644 index 0b4499bb645..00000000000 --- a/tools/testClient/asyncJobMgr.py +++ /dev/null @@ -1,230 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import threading -import cloudstackException -import time -import Queue -import copy -import sys -import jsonHelper -import datetime - -class job(object): - def __init__(self): - self.id = None - self.cmd = None -class jobStatus(object): - def __init__(self): - self.result = None - self.status = None - self.startTime = None - self.endTime = None - self.duration = None - self.jobId = None - self.responsecls = None - def __str__(self): - return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) -class workThread(threading.Thread): - def __init__(self, in_queue, outqueue, apiClient, db=None, lock=None): - threading.Thread.__init__(self) - self.inqueue = in_queue - self.output = outqueue - self.connection = apiClient.connection.__copy__() - self.db = None - self.lock = lock - - def queryAsynJob(self, job): - if job.jobId is None: - return job - - try: - self.lock.acquire() - result = self.connection.pollAsyncJob(job.jobId, job.responsecls).jobresult - except cloudstackException.cloudstackAPIException, e: - result = str(e) - finally: - self.lock.release() - - job.result = result - return job - - def executeCmd(self, job): - cmd = job.cmd - - jobstatus = jobStatus() - jobId = None - try: - self.lock.acquire() - - if cmd.isAsync == "false": - jobstatus.startTime = datetime.datetime.now() - - result = self.connection.make_request(cmd) - jobstatus.result = result - jobstatus.endTime = datetime.datetime.now() - jobstatus.duration = time.mktime(jobstatus.endTime.timetuple()) - time.mktime(jobstatus.startTime.timetuple()) - else: - result = self.connection.make_request(cmd, None, True) - if result is None: - jobstatus.status = False - else: - jobId = result.jobid - jobstatus.jobId = jobId - try: - responseName = cmd.__class__.__name__.replace("Cmd", "Response") - jobstatus.responsecls = jsonHelper.getclassFromName(cmd, responseName) - except: - pass - jobstatus.status = True - except cloudstackException.cloudstackAPIException, e: - jobstatus.result = str(e) - jobstatus.status = False - except: - jobstatus.status = False - jobstatus.result = sys.exc_info() - finally: - self.lock.release() - - return jobstatus - - def run(self): - while self.inqueue.qsize() > 0: - job = self.inqueue.get() - if isinstance(job, jobStatus): - jobstatus = self.queryAsynJob(job) - else: - jobstatus = self.executeCmd(job) - - self.output.put(jobstatus) - self.inqueue.task_done() - - '''release the resource''' - self.connection.close() - -class jobThread(threading.Thread): - def __init__(self, inqueue, interval): - threading.Thread.__init__(self) - self.inqueue = inqueue - self.interval = interval - def run(self): - while self.inqueue.qsize() > 0: - job = self.inqueue.get() - try: - job.run() - '''release the api connection''' - job.apiClient.connection.close() - except: - pass - - self.inqueue.task_done() - time.sleep(self.interval) - -class outputDict(object): - def __init__(self): - self.lock = threading.Condition() - self.dict = {} - -class asyncJobMgr(object): - def __init__(self, apiClient, db): - self.inqueue = Queue.Queue() - self.output = outputDict() - self.outqueue = Queue.Queue() - self.apiClient = apiClient - self.db = db - - def submitCmds(self, cmds): - if not self.inqueue.empty(): - return False - id = 0 - ids = [] - for cmd in cmds: - asyncjob = job() - asyncjob.id = id - asyncjob.cmd = cmd - self.inqueue.put(asyncjob) - id += 1 - ids.append(id) - return ids - - def updateTimeStamp(self, jobstatus): - jobId = jobstatus.jobId - if jobId is not None and self.db is not None: - result = self.db.execute("select job_status, created, last_updated from async_job where id=%s"%jobId) - if result is not None and len(result) > 0: - if result[0][0] == 1: - jobstatus.status = True - else: - jobstatus.status = False - jobstatus.startTime = result[0][1] - jobstatus.endTime = result[0][2] - delta = jobstatus.endTime - jobstatus.startTime - jobstatus.duration = delta.total_seconds() - - def waitForComplete(self, workers=10): - self.inqueue.join() - lock = threading.Lock() - resultQueue = Queue.Queue() - '''intermediate result is stored in self.outqueue''' - for i in range(workers): - worker = workThread(self.outqueue, resultQueue, self.apiClient, self.db, lock) - worker.start() - - self.outqueue.join() - - asyncJobResult = [] - while resultQueue.qsize() > 0: - jobstatus = resultQueue.get() - self.updateTimeStamp(jobstatus) - asyncJobResult.append(jobstatus) - - return asyncJobResult - - '''put commands into a queue at first, then start workers numbers threads to execute this commands''' - def submitCmdsAndWait(self, cmds, workers=10): - self.submitCmds(cmds) - lock = threading.Lock() - for i in range(workers): - worker = workThread(self.inqueue, self.outqueue, self.apiClient, self.db, lock) - worker.start() - - return self.waitForComplete(workers) - - '''submit one job and execute the same job ntimes, with nums_threads of threads''' - def submitJobExecuteNtimes(self, job, ntimes=1, nums_threads=1, interval=1): - inqueue1 = Queue.Queue() - lock = threading.Condition() - for i in range(ntimes): - newjob = copy.copy(job) - setattr(newjob, "apiClient", copy.copy(self.apiClient)) - setattr(newjob, "lock", lock) - inqueue1.put(newjob) - - for i in range(nums_threads): - work = jobThread(inqueue1, interval) - work.start() - inqueue1.join() - - '''submit n jobs, execute them with nums_threads of threads''' - def submitJobs(self, jobs, nums_threads=1, interval=1): - inqueue1 = Queue.Queue() - lock = threading.Condition() - - for job in jobs: - setattr(job, "apiClient", copy.copy(self.apiClient)) - setattr(job, "lock", lock) - inqueue1.put(job) - - for i in range(nums_threads): - work = jobThread(inqueue1, interval) - work.start() - inqueue1.join() diff --git a/tools/testClient/automated/automated.sh b/tools/testClient/automated/automated.sh deleted file mode 100644 index cf7588cf09e..00000000000 --- a/tools/testClient/automated/automated.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -# wec -export CATALINA_HOME=${HOME}/automated -# macos tomcat -#ORIG_TOMCAT=/usr/local/tomcat -# linux/jenkins host tomcat -ORIG_TOMCAT=/usr/share/tomcat6 - -mkdir_copy_files() { - if [ -z "$1" ]; then - return 0 - fi - - echo "Copying $1 files to $2..." - - mkdir -p $2 - cp -R $1/* $2 - return $? -} - -if [ ! -d ${ORIG_TOMCAT} ]; then - echo "Tomcat must be installed on this system" - exit 1 -fi - -if [ -d ${CATALINA_HOME} ]; then - echo "Existing test Tomcat exists!!!" - exit 1 -fi - -# now let's copy over the required files... -mkdir_copy_files ${ORIG_TOMCAT}/conf ${CATALINA_HOME}/conf -mkdir_copy_files ${ORIG_TOMCAT}/bin ${CATALINA_HOME}/bin -mkdir_copy_files ${ORIG_TOMCAT}/lib ${CATALINA_HOME}/lib -mkdir_copy_files ${ORIG_TOMCAT}/logs ${CATALINA_HOME}/logs -mkdir_copy_files ${ORIG_TOMCAT}/temp ${CATALINA_HOME}/temp -mkdir_copy_files ${ORIG_TOMCAT}/webapps ${CATALINA_HOME}/webapps -mkdir_copy_files ${ORIG_TOMCAT}/work ${CATALINA_HOME}/work - -ant clean-all - -ant automated-test-run - -# clean up our temp tomcat! -rm -rf ${CATALINA_HOME} - -exit $? diff --git a/tools/testClient/automated/automated.xml b/tools/testClient/automated/automated.xml deleted file mode 100644 index 63b6d1de3e9..00000000000 --- a/tools/testClient/automated/automated.xml +++ /dev/null @@ -1,4425 +0,0 @@ - - - - - createAccount - [Create the Account and a User for the account] - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - email - admin@gmail.com - - - firstname - admin - - - lastname - adminlastname - - - username - usernameparam - - - password - password - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmavailable - Unlimited - - - vmlimit - Unlimited - - - vmtotal - 0 - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - enabled - - - - - - - listUsers - 5 [List the Created User in (3)] - - - account - accountname - - - - - - id - userid - - - username - usernameparam - - - firstname - admin - - - lastname - adminlastname - - - email - admin@gmail.com - - - created - createtimestamp - - - state - enabled - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - - - - - - - createUser - 3 [Create User Command] - - - account - accountname - - - accounttype - 1 - - - username - secondusernameparam - - - password - password - - - firstname - nimbus-user - - - lastname - nimbus-userlastname - - - email - nimbus-user@gmail.com - - - domainid - 1 - - - - - - id - seconduserid - - - username - usernameparam - - - firstname - nimbus-user - - - lastname - nimbus-userlastname - - - email - nimbus-user@gmail.com - - - account - accountname - - - accounttype - 0 - - - domainid - 1 - - - domain - ROOT - - - created - createtimestamp - - - state - enabled - - - - - - - listAccounts - 950 [List the Account of the User created in (3)] - - - name - accountname - - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmlimit - Unlimited - - - vmtotal - 0 - - - vmavailable - Unlimited - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - enabled - - - - - - - updateUser - 6 [Update the User created in (3)] - - - id - userid - - - username - newuser - - - password - password - - - firstname - updatednimbus - - - lastname - updatednimbuslastname - - - email - updatednimbus@gmail.com - - - timezone - PST - - - apikey - userapikey - - - secretkey - usersecretkey - - - - - - id - userid - - - username - newuser - - - firstname - updatednimbus - - - lastname - updatednimbuslastname - - - email - updatednimbus@gmail.com - - - created - createtimestamp - - - state - enabled - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - timezone - PST - - - apikey - userapikey - - - secretkey - usersecretkey - - - - - - - listUsers - 5 [List the Updated User updated in (6)] - - - id - userid - - - - - id - userid - - - username - newuser - - - firstname - updatednimbus - - - lastname - updatednimbuslastname - - - email - updatednimbus@gmail.com - - - created - createtimestamp - - - state - enabled - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - timezone - PST - - - apikey - userapikey - - - secretkey - usersecretkey - - - - - - - - - - - - - disableUser - 428 [Disable the User created in (3)] - - - id - userid - - - - - id - userid - - - username - newuser - - - firstname - updatednimbus - - - lastname - updatednimbuslastname - - - email - updatednimbus@gmail.com - - - created - createtimestamp - - - state - disabled - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - timezone - PST - - - apikey - userapikey - - - secretkey - usersecretkey - - - - - - - enableUser - 9 [Enable the User created in (3)] - - - id - userid - - - - - id - userid - - - username - newuser - - - firstname - updatednimbus - - - lastname - updatednimbuslastname - - - email - updatednimbus@gmail.com - - - created - createtimestamp - - - state - enabled - - - account - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - timezone - PST - - - apikey - userapikey - - - secretkey - usersecretkey - - - - - - - disableAccount - [Disable the Account] - - - account - accountname - - - domainid - 1 - - - lock - true - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmlimit - Unlimited - - - vmtotal - 0 - - - vmavailable - Unlimited - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - locked - - - - - - - enableAccount - [Enable the Locked Account] - - - account - accountname - - - domainid - 1 - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmlimit - Unlimited - - - vmtotal - 0 - - - vmavailable - Unlimited - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - enabled - - - - - - - disableAccount - [Lock the Account] - - - account - accountname - - - domainid - 1 - - - lock - false - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmlimit - Unlimited - - - vmtotal - 0 - - - vmavailable - Unlimited - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - disabled - - - - - - - enableAccount - [Enable the Locked Account] - - - account - accountname - - - domainid - 1 - - - - - id - accountid - - - name - accountname - - - accounttype - 1 - - - domainid - 1 - - - domain - ROOT - - - receivedbytes - 0 - - - sentbytes - 0 - - - vmlimit - Unlimited - - - vmtotal - 0 - - - vmavailable - Unlimited - - - ipavailable - Unlimited - - - iptotal - 0 - - - iplimit - Unlimited - - - volumelimit - Unlimited - - - volumetotal - 0 - - - volumeavailable - Unlimited - - - snapshotlimit - Unlimited - - - snapshottotal - 0 - - - snapshotavailable - Unlimited - - - templatelimit - Unlimited - - - templatetotal - 0 - - - templateavailable - Unlimited - - - vmstopped - 0 - - - vmrunning - 0 - - - state - enabled - - - - - - - - createDomain - 10 [Create Domain] - - - name - domainname - - - - - - name - domainname - - - id - newdomainid - - - level - 1 - - - parentdomainid - 1 - - - parentdomainname - ROOT - - - haschild - false - - - - - - - - - listDomains - 11 [List Domains] - - - name - domainname - - - - - - id - newdomainid - - - name - domainname - - - level - 1 - - - parentdomainid - 1 - - - parentdomainname - ROOT - - - haschild - false - - - - - - - - - updateDomain - 952 [Update the Domain created in (10)] - - - id - newdomainid - - - name - newdomainname - - - - - - id - newdomainid - - - name - newdomainname - - - level - 1 - - - parentdomainid - 1 - - - parentdomainname - ROOT - - - haschild - false - - - - - - - - - - listDomainChildren - - [List One of the Children of the Parent Domain] - - - id - 1 - - - - - domain - 0 - - id - newdomainid - - - name - newdomainname - - - level - 1 - - - parentdomainid - 1 - - - parentdomainname - ROOT - - - haschild - false - - - - - - - - - deleteDomain - 654 [Delete Domain created in (10)] - - - id - newdomainid - - - cleanup - true - - - - - - success - true - - - - - - - - - listTemplates - 27 [List Templates - List System Template] - - - templatefilter - self - - - id - 1 - - - - - template - 0 - - id - debian50templateid - - - name - debian50templatename - - - displaytext - debian50templatedisplaytext - - - ispublic - debian50templateispublic - - - created - debian50templatecreated - - - isready - true - - - passwordenabled - debian50templatepasswordenabled - - - format - VHD - - - - isfeatured - false - - - crossZones - true - - - ostypeid - debian50templateostypeid - - - ostypename - debian50templateostypename - - - size - debian50templatesize - - - account - system - - - zoneid - globalzoneid - - - zonename - globalzonename - - - status - Download Complete - - - templatetype - SYSTEM - - - hypervisor - XenServer - - - domain - ROOT - - - domainid - 1 - - - - - - - - listTemplates - - Verify All the Parameters of the Listed Template - - - - name - debian50templatename - - - templatefilter - self - - - - template - 0 - - id - debian50templateid - - - name - debian50templatename - - - displaytext - debian50templatedisplaytext - - - ispublic - debian50templateispublic - - - created - debian50templatecreated - - - isready - true - - - isfeatured - false - - - passwordenabled - debian50templatepasswordenabled - - - crossZones - true - - - format - VHD - - - ostypeid - debian50templateostypeid - - - ostypename - debian50templateostypename - - - account - system - - - domainid - 1 - - - domain - ROOT - - - zoneid - globalzoneid - - - zonename - globalzonename - - - status - Download Complete - - - size - debian50templatesize - - - templatetype - SYSTEM - - - hypervisor - XenServer - - - - - - - - - listServiceOfferings - 28 [List the Small Instance Service Offering] - - - id - globalserviceofferingid - - - - - id - smallofferingid - - - name - smallofferingname - - - displaytext - smallofferingdisplaytext - - - cpunumber - smallofferingcpunumber - - - cpuspeed - smallofferingcpuspeed - - - memory - smallofferingmemory - - - created - smallofferingcreatetime - - - storagetype - smallofferingstoragetype - - - offerha - false - - - - - - listServiceOfferings - 876 [Verify the First Service Offering] - - - name - smallofferingname - - - - serviceoffering - 0 - - id - smallofferingid - - - name - smallofferingname - - - displaytext - smallofferingdisplaytext - - - cpunumber - smallofferingcpunumber - - - cpuspeed - smallofferingcpuspeed - - - memory - smallofferingmemory - - - created - smallofferingcreatetime - - - storagetype - smallofferingstoragetype - - - offerha - false - - - - - - - - listZones - 39 [List the Global Zone with id-2] - - zone - 0 - - id - globalzoneid - - - name - globalzonename - - - dns1 - dns1 - - - dns2 - dns2 - - - internaldns1 - internaldns1 - - - vlan - - - guestcidraddress - - - networktype - Advanced - - - - - - - createNetwork - [Creating default network] - - - zoneid - globalzoneid - - - networkOfferingId - globalnetworkofferingid - - - account - accountname - - - domainid - 1 - - - name - defaultregressionnetwork - - - displaytext - defaultregressionnetwork - - - - - id - networkid - - - - - - - deployVirtualMachine - 13 - - - zoneid - globalzoneid - - - serviceofferingid - globalserviceofferingid - - - diskofferingid - globaldiskofferingid - - - templateid - globaltemplateid - - - account - accountname - - - domainid - 1 - - - displayname - namefordisplay - - - group - group1 - - - networkids - networkid - - - - - id - vmid - - - name - vmname - - - ipaddress - vmipaddress - - - created - - - zoneid - globalzoneid - - - zonename - globalzonename - - - haenable - false - - - state - Running - - - account - accountname - - - templateid - globaltemplateid - - - serviceofferingid - globalserviceofferingid - - - cpunumber - smallofferingcpunumber - - - cpuspeed - smallofferingcpuspeed - - - memory - smallofferingmemory - - - displayname - namefordisplay - - - group - group1 - - - - - - - - listVirtualMachines - 957 - false - - - name - vmname - - - - - id - vmid - - - name - vmname - - - ipaddress - vmipaddress - - - created - - - zoneid - globalzoneid - - - zonename - globalzonename - - - haenable - false - - - state - Running - - - account - accountname - - - templateid - globaltemplateid - - - serviceofferingid - smallofferingid - - - serviceofferingname - smallofferingname - - - cpunumber - smallofferingcpunumber - - - cpuspeed - smallofferingcpuspeed - - - memory - smallofferingmemory - - - displayname - namefordisplay - - - group - group1 - - - - - - - listRouters - 35 - - - zoneid - globalzoneid - - - account - accountname - - - domainid - 1 - - - - router - 0 - - id - routerid - - - publicip - sourcenatpublicip - - - zoneid - globalzoneid - - - zonename - globalzonename - - - dns1 - dns1 - - - dns2 - dns2 - - - networkdomain - - - gateway - - - name - routername - - - podid - - - privateip - - - privatemacaddress - - - privatenetmask - - - publicmacaddress - routerpublicmacaddress - - - guestipaddress - routeripaddress - - - guestmacaddress - routermacaddress - - - created - - - hostid - - - state - Running - - - - - - - associateIpAddress - 546 - - - zoneid - globalzoneid - - - account - accountname - - - domainid - 1 - - - - - id - nonsourcenatpublicipid - - - ipaddress - nonsourcenatpublicip - - - allocated - - - zoneid - globalzoneid - - - zonename - globalzonename - - - issourcenat - false - - - - - - - - - createLoadBalancerRule - 986 - - - name - lbname - - - publicipid - nonsourcenatpublicipid - - - privateport - privateport - - - publicport - publicport - - - algorithm - roundrobin - - - account - accountname - - - domainid - 1 - - - - - id - lbid - - - name - lbname - - - privateport - privateport - - - publicport - publicport - - - algorithm - roundrobin - - - publicipid - nonsourcenatpublicipid - - - publicip - sourcenatpublicip - - - account - accountname - - - - - - - - listLoadBalancerRules - 988 - false - - - account - accountname - - - domainId - 1 - - - - - - - - assignToLoadBalancerRule - 989 - - - id - lbid - - - virtualmachineids - vmid - - - - - - - deleteLoadBalancerRule - 987 - - - id - lbid - - - - - - listLoadBalancerRules - true - - - - createLoadBalancerRule - - - name - lbname - - - publicipid - nonsourcenatpublicipid - - - privateport - privateport - - - publicport - publicport - - - algorithm - roundrobin - - - account - accountname - - - domainid - 1 - - - - - id - lbid - - - name - lbname - - - privateport - privateport - - - publicport - publicport - - - algorithm - roundrobin - - - publicipid - nonsourcenatpublicipid - - - publicip - sourcenatpublicip - - - account - accountname - - - - - - assignToLoadBalancerRule - - - id - lbid - - - virtualmachineids - vmid - - - - - - - - listLoadBalancerRuleInstances - 991 - false - - - id - lbid - - - - - - - removeFromLoadBalancerRule - 990 - - - id - lbid - - - virtualmachineids - vmid - - - account - accountname - - - - - - listLoadBalancerRuleInstances - true - - - id - lbid - - - - - - - - - - - - rebootVirtualMachine - 16 - - - id - vmid - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Running - - - - - - - - stopVirtualMachine - 17 - - - id - vmid - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Stopped - - - - - - - - - - listVolumes - - - virtualmachineid - vmid - - - type - ROOT - - - - - id - rootvolumeid - - - - - - listVolumes - - - virtualmachineid - vmid - - - type - DATADISK - - - - - id - datavolumeid - - - - - - - detachVolume - - - id - datavolumeid - - - - - - listVolumes - true - - - virtualmachineid - vmid - - - type - DATADISK - - - - - - - - createVolume - 1026 - - - account - accountname - - - domainid - 1 - - - name - - - zoneid - globalzoneid - - - diskofferingid - globaldiskofferingid - - - - - id - datavolumeid - - - - - - - - attachVolume - - - id - datavolumeid - - - virtualmachineid - vmid - - - - - - listVolumes - false - - - virtualmachineid - vmid - - - type - DATADISK - - - - - - - - createVolume - - - account - accountname - - - domainid - 1 - - - name - - - zoneid - globalzoneid - - - diskofferingid - globaldiskofferingid - - - - - id - datavolumeid1 - - - - - - deleteVolume - - - id - datavolumeid1 - - - - - - listVolumes - true - - - id - datavolumeid1 - - - - - - - - - createSnapshot - - - volumeid - rootvolumeid - - - - - id - snapshotid1 - - - volumeid - rootvolumeid - - - created - - - name - - - account - accountname - - - - - - listSnapshots - false - - - volumeid - rootvolumeid - - - - - - - deleteSnapshot - 24 - - - id - snapshotid1 - - - - - - - listSnapshots - 26 - true - - - volumeid - rootvolumeid - - - - - - - createSnapshot - - - volumeid - rootvolumeid - - - - - id - snapshotid1 - - - - - - createTemplate - 958 - - - snapshotid - snapshotid1 - - - name - privatetemplatename - - - displaytext - newtext - - - osTypeId - 1 - - - - - id - privatetemplateid - - - name - privatetemplatename - - - ispublic - false - - - isready - true - - - created - - - passwordenabled - false - - - - - - - listTemplates - 27 - - - name - privatetemplatename - - - templatefilter - self - - - - - id - privatetemplateid - - - name - privatetemplatename - - - ispublic - false - - - isready - true - - - created - - - passwordenabled - false - - - - - - - updateTemplate - Update template - - - id - privatetemplateid - - - displaytext - lalala - - - name - blah - - - - - - listTemplates - List updated template - - - id - privatetemplateid - - - templatefilter - self - - - - - displaytext - lalala - - - - - - - - listTemplatePermissions - list template permissions command - - - id - privatetemplateid - - - templatefilter - self - - - - - ispublic - false - - - - - - - - updateTemplatePermissions - update template permissions - - - id - privatetemplateid - - - ispublic - true - - - - - - listTemplates - List template with updated permission - - - id - privatetemplateid - - - templatefilter - self - - - - - ispublic - true - - - - - - - - deleteTemplate - 959 - - - id - privatetemplateid - - - - - - listTemplates - true - - - name - privatetemplatename - - - templatefilter - self - - - - - - - - - changeServiceForVirtualMachine - 20 - - - id - vmid - - - serviceofferingid - mediumglobalserviceofferingid - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Stopped - - - serviceofferingid - 2 - - - - - - - - resetPasswordForVirtualMachine - 19 - - - id - vmid - - - - - id - vmid - - - password - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Stopped - - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Stopped - - - - - - startVirtualMachine - 18 - - - id - vmid - - - - - id - vmid - - - name - vmname - - - ipaddress - vmipaddress - - - created - - - zoneid - globalzoneid - - - zonename - globalzonename - - - haenable - false - - - state - Running - - - account - accountname - - - templateid - globaltemplateid - - - serviceofferingid - 2 - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Running - - - - - - - updateVirtualMachine - - - id - vmid - - - haenable - true - - - - - - listVirtualMachines - 21 - - - account - accountname - - - name - vmname - - - - - haenable - true - - - - - - updateVirtualMachine - - - id - vmid - - - haenable - false - - - - - - listVirtualMachines - 21 - - - account - accountname - - - name - vmname - - - - - haenable - false - - - - - - - - - listPublicIpAddresses - 547 - - - account - accountname - - - - - - - - - - disassociateIpAddress - 548 - - - ipaddress - nonsourcenatpublicip - - - account - accountname - - - - - - - rebootRouter - 36 - - - id - routerid - - - - - - - stopRouter - 37 - - - id - routerid - - - - - - - startRouter - 38 - - - id - routerid - - - - - id - routerid - - - publicip - sourcenatpublicip - - - zoneid - globalzoneid - - - zonename - globalzonename - - - dns1 - dns1 - - - networkdomain - - - name - routername - - - podid - - - privateip - - - privatemacaddress - - - privatenetmask - - - publicmacaddress - routerpublicmacaddress - - - guestipaddress - routeripaddress - - - guestmacaddress - routermacaddress - - - created - - - hostid - - - state - Running - - - - - - - listEvents - 40 - - - account - accountname - - - - - - - destroyVirtualMachine - 14 - - - id - vmid - - - - - - listVirtualMachines - - - id - vmid - - - - - state - Destroyed - - - - - - - recoverVirtualMachine - 22 - - - id - vmid - - - - - - listVirtualMachines - - - account - accountname - - - name - vmname - - - - - state - Stopped - - - - - - - listConfigurations - 549 - false - - - - - listConfigurations - 878 - false - - - category - advanced - - - - - - - - updateConfiguration - 550 - - - name - update.wait - - - value - 35 - - - - - - listConfigurations - - - name - update.wait - - - - - value - 35 - - - - - - - - listPods - 552 - - - - - - - - - - createAccount - [Create the Account and a User for the account] - - - account - accountname1 - - - accounttype - 1 - - - domainid - 1 - - - email - admin@gmail.com - - - firstname - admin - - - lastname - adminlastname - - - username - usernameparam - - - password - password - - - - - - listAccounts - - - name - accountname1 - - - - - id - accountid1 - - - - - - updateAccount - 951 - - - account - accountname1 - - - domainid - 1 - - - newname - updatedname - - - - - - listAccounts - - - name - updatedname - - - - - id - accountid1 - - - name - updatedname - - - - - - - disableAccount - 7 - - - account - updatedname - - - domainid - 1 - - - lock - true - - - - - - - - - enableAccount - 8 - - - account - updatedname - - - domainid - 1 - - - - - - - - updateResourceLimit - 953 - - - resourcetype - 1 - - - max - 300 - - - domainid - 1 - - - - - domainid - 1 - - - domain - ROOT - - - resourcetype - 1 - - - max - 300 - - - - - - - listResourceLimits - true - 956 - - - domainid - 1 - - - resourcetype - 1 - - - - - max - 300 - - - - - - - updateResourceLimit - 954 - - - domainid - 1 - - - resourcetype - 1 - - - max - 65 - - - - - - listResourceLimits - - - domainid - 1 - - - resourcetype - 1 - - - - - max - 65 - - - - - - - - createDiskOffering - 932 - - - name - newdiskname - - - description - newdiskdesc - - - disksize - 1024 - - - displaytext - volumedisplay - - - - - id - diskid - - - domainid - 1 - - - name - newdiskname - - - displaytext - volumedisplay - - - disksize - 1099511627776 - - - - - - - - - listDiskOfferings - 934 - false - - - domainid - 1 - - - name - newdisk - - - - - - - - updateDiskOffering - - - id - diskid - - - name - newdiskname - - - - - - listDiskOfferings - - - domainid - 1 - - - name - newdiskname - - - - - name - newdiskname - - - - - - - - deleteDiskOffering - 933 - - - id - diskid - - - - - - listDiskOfferings - true - - - domainid - 1 - - - id - diskid - - - - - - - listAlerts - 750 - false - - - - - listCapacity - 974 - false - - - - - listHosts - false - 975 - - - - - - listIsos - 960 - true - - - - - createServiceOffering - 962 - - - name - - - displaytext - newoff - - - cpunumber - 1 - - - cpuspeed - 200 - - - memory - 256 - - - - - id - soid - - - - - - listServiceOfferings - - - id - soid - - - - - id - newofferingid - - - displaytext - newoff - - - cpunumber - 1 - - - cpuspeed - 200 - - - memory - 256 - - - created - - - - - - - - updateServiceOffering - 964 - - - id - newofferingid - - - name - - - displaytext - display - - - - - - - listServiceOfferings - - - id - newofferingid - - - - - id - newofferingid - - - displaytext - display - - - cpunumber - 1 - - - cpuspeed - 200 - - - memory - 256 - - - created - - - - - - - - deleteServiceOffering - 963-1 - - - id - newofferingid - - - - - - listServiceOfferings - 963-2 - true - - - id - newofferingid - - - - - - - - registerIso - Register iso - - - name - isoname - - - displaytext - isodisplay - - - url - http://172.16.0.220/images/sumita/iso/ubuntu-9.04-server-amd64.iso - - - ostypeid - 53 - - - zoneid - globalzoneid - - - account - accountname - - - domainid - 1 - - - - - id - privateisoid - - - created - - - ispublic - false - - - bootable - true - - - isready - false - - - isfeatured - false - - - name - registername - - - displaytext - registerdisplay - - - - - - - listIsos - List isos - false - - - id - privateisoid - - - - - - - registerTemplate - Register template - - - name - registername - - - displaytext - registerdisplay - - - url - globaltemplateurl - - - ostypeid - 1 - - - format - vhd - - - zoneid - globalzoneid - - - account - accountname - - - domainid - 1 - - - hypervisor - globalhypervisortype - - - - - id - systemtemplateid - - - created - - - ispublic - false - - - isfeatured - false - - - passwordenabled - false - - - format - VHD - - - isready - false - - - name - registername - - - displaytext - registerdisplay - - - - - - - - listSystemVms - List system vms - - - domainid - 1 - - - - systemvm - 0 - - id - consoleid - - - publicip - - - zoneid - - - zonename - - - dns1 - dns1 - - - dns2 - dns2 - - - networkdomain - - - gateway - - - name - - - podid - - - privateip - - - privatemacaddress - - - privatenetmask - - - publicmacaddress - - - privatemacaddress - - - created - - - hostid - - - state - Running - - - activeviewersessions - 0 - - - - - - - rebootSystemVm - Reboot system vm - - - id - consoleid - - - - - - - stopSystemVm - Stop system vm - - - id - consoleid - - - - - - - startSystemVm - Start system vm - - - id - consoleid - - - - - - - - deleteIso - Delete iso - - - id - privateisoid - - - - - - listIsos - List isos - true - - - id - privateisoid - - - - - - - deleteTemplate - Delete template - - - id - systemtemplateid - - - - - - listTemplates - List templates - true - - - id - systemtemplateid - - - templatefilter - self - - - - - - - deleteAccount - Deleting account - - - id - accountid - - - - - - \ No newline at end of file diff --git a/tools/testClient/cloudstackConnection.py b/tools/testClient/cloudstackConnection.py deleted file mode 100644 index b72e54c3c10..00000000000 --- a/tools/testClient/cloudstackConnection.py +++ /dev/null @@ -1,174 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import urllib2 -import urllib -import base64 -import hmac -import hashlib -import json -import xml.dom.minidom -import types -import time -import inspect -import cloudstackException -from cloudstackAPI import * -import jsonHelper - -class cloudConnection(object): - def __init__(self, mgtSvr, port=8096, apiKey = None, securityKey = None, asyncTimeout=3600, logging=None): - self.apiKey = apiKey - self.securityKey = securityKey - self.mgtSvr = mgtSvr - self.port = port - self.logging = logging - if port == 8096: - self.auth = False - else: - self.auth = True - - self.retries = 5 - self.asyncTimeout = asyncTimeout - - def close(self): - try: - self.connection.close() - except: - pass - - def __copy__(self): - return cloudConnection(self.mgtSvr, self.port, self.apiKey, self.securityKey, self.asyncTimeout, self.logging) - - def make_request_with_auth(self, command, requests={}): - requests["command"] = command - requests["apiKey"] = self.apiKey - requests["response"] = "json" - request = zip(requests.keys(), requests.values()) - request.sort(key=lambda x: str.lower(x[0])) - - requestUrl = "&".join(["=".join([r[0], urllib.quote_plus(str(r[1]))]) for r in request]) - hashStr = "&".join(["=".join([str.lower(r[0]), str.lower(urllib.quote_plus(str(r[1]))).replace("+", "%20")]) for r in request]) - - sig = urllib.quote_plus(base64.encodestring(hmac.new(self.securityKey, hashStr, hashlib.sha1).digest()).strip()) - requestUrl += "&signature=%s"%sig - - try: - self.connection = urllib2.urlopen("http://%s:%d/client/api?%s"%(self.mgtSvr, self.port, requestUrl)) - self.logging.debug("sending GET request: %s"%requestUrl) - response = self.connection.read() - self.logging.info("got response: %s"%response) - except IOError, e: - if hasattr(e, 'reason'): - self.logging.critical("failed to reach %s because of %s"%(self.mgtSvr, e.reason)) - elif hasattr(e, 'code'): - self.logging.critical("server returned %d error code"%e.code) - except HTTPException, h: - self.logging.debug("encountered http Exception %s"%h.args) - if self.retries > 0: - self.retries = self.retries - 1 - self.make_request_with_auth(command, requests) - else: - self.retries = 5 - raise h - else: - return response - - def make_request_without_auth(self, command, requests={}): - requests["command"] = command - requests["response"] = "json" - requests = zip(requests.keys(), requests.values()) - requestUrl = "&".join(["=".join([request[0], urllib.quote_plus(str(request[1]))]) for request in requests]) - - self.connection = urllib2.urlopen("http://%s:%d/client/api?%s"%(self.mgtSvr, self.port, requestUrl)) - self.logging.debug("sending GET request without auth: %s"%requestUrl) - response = self.connection.read() - self.logging.info("got response: %s"%response) - return response - - def pollAsyncJob(self, jobId, response): - cmd = queryAsyncJobResult.queryAsyncJobResultCmd() - cmd.jobid = jobId - timeout = self.asyncTimeout - - while timeout > 0: - asyncResonse = self.make_request(cmd, response, True) - - if asyncResonse.jobstatus == 2: - raise cloudstackException.cloudstackAPIException("asyncquery", asyncResonse.jobresult) - elif asyncResonse.jobstatus == 1: - return asyncResonse - - time.sleep(5) - self.logging.debug("job: %s still processing, will timeout in %ds"%(jobId, timeout)) - timeout = timeout - 5 - - raise cloudstackException.cloudstackAPIException("asyncquery", "Async job timeout %s"%jobId) - - def make_request(self, cmd, response = None, raw=False): - commandName = cmd.__class__.__name__.replace("Cmd", "") - isAsync = "false" - requests = {} - required = [] - for attribute in dir(cmd): - if attribute != "__doc__" and attribute != "__init__" and attribute != "__module__": - if attribute == "isAsync": - isAsync = getattr(cmd, attribute) - elif attribute == "required": - required = getattr(cmd, attribute) - else: - requests[attribute] = getattr(cmd, attribute) - - for requiredPara in required: - if requests[requiredPara] is None: - raise cloudstackException.cloudstackAPIException(commandName, "%s is required"%requiredPara) - '''remove none value''' - for param, value in requests.items(): - if value is None: - requests.pop(param) - elif isinstance(value, list): - if len(value) == 0: - requests.pop(param) - else: - if not isinstance(value[0], dict): - requests[param] = ",".join(value) - else: - requests.pop(param) - i = 0 - for v in value: - for key, val in v.iteritems(): - requests["%s[%d].%s"%(param,i,key)] = val - i = i + 1 - - if self.logging is not None: - self.logging.info("sending command: %s %s"%(commandName, str(requests))) - result = None - if self.auth: - result = self.make_request_with_auth(commandName, requests) - else: - result = self.make_request_without_auth(commandName, requests) - - if result is None: - return None - - result = jsonHelper.getResultObj(result, response) - if raw or isAsync == "false": - return result - else: - asynJobId = result.jobid - result = self.pollAsyncJob(asynJobId, response) - return result.jobresult - -if __name__ == '__main__': - xml = '407i-1-407-RS3i-1-407-RS3system1ROOT2011-07-30T14:45:19-0700Runningfalse1CA13kvm-50-2054CentOS 5.5(64-bit) no GUI (KVM)CentOS 5.5(64-bit) no GUI (KVM)false1Small Instance15005121120NetworkFilesystem380203255.255.255.065.19.181.165.19.181.110vlan://65vlan://65GuestDirecttrue06:52:da:00:00:08KVM' - conn = cloudConnection(None) - - print conn.paraseReturnXML(xml, deployVirtualMachine.deployVirtualMachineResponse()) diff --git a/tools/testClient/cloudstackException.py b/tools/testClient/cloudstackException.py deleted file mode 100644 index c8640975481..00000000000 --- a/tools/testClient/cloudstackException.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -class cloudstackAPIException(Exception): - def __init__(self, cmd = "", result = ""): - self.errorMsg = "Execute cmd: %s failed, due to: %s"%(cmd, result) - def __str__(self): - return self.errorMsg - -class InvalidParameterException(Exception): - def __init__(self, msg=''): - self.errorMsg = msg - def __str__(self): - return self.errorMsg - -class dbException(Exception): - def __init__(self, msg=''): - self.errorMsg = msg - def __str__(self): - return self.errorMsg - -class internalError(Exception): - def __init__(self, msg=''): - self.errorMsg = msg - def __str__(self): - return self.errorMsg \ No newline at end of file diff --git a/tools/testClient/cloudstackTestCase.py b/tools/testClient/cloudstackTestCase.py deleted file mode 100644 index cf822adc39e..00000000000 --- a/tools/testClient/cloudstackTestCase.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackAPI import * -try: - import unittest2 as unittest -except ImportError: - import unittest -import cloudstackTestClient - -#class UserName(object): -# def __init__(self, account, domain, type=0): -# self.account = account -# self.domain = domain -# self.accounttype = type -# def __call__(self, cls): -# class Wrapped(cls): -# cls.UserName = self.account -# cls.DomainName = self.domain -# cls.AcctType = self.accounttype -# return Wrapped - -def UserName(Name, DomainName, AcctType): - def wrapper(cls): - orig_init = cls.__init__ - def __init__(self, *args, **kws): - cls.UserName = Name - cls.DomainName = DomainName - cls.AcctType = AcctType - orig_init(self, *args, **kws) - cls.__init__ = __init__ - return cls - return wrapper - -class cloudstackTestCase(unittest.case.TestCase): - clstestclient = None - - def __init__(self, args): - unittest.case.TestCase.__init__(self, args) - self.testClient = cloudstackTestClient.cloudstackTestClient() - - @classmethod - def getClsTestClient(cls): - return cls.clstestclient diff --git a/tools/testClient/cloudstackTestClient.py b/tools/testClient/cloudstackTestClient.py deleted file mode 100644 index 097307f6ba0..00000000000 --- a/tools/testClient/cloudstackTestClient.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import cloudstackConnection -import asyncJobMgr -import dbConnection -from cloudstackAPI import * -import random -import string -import hashlib - -class cloudstackTestClient(object): - def __init__(self, mgtSvr=None, port=8096, apiKey = None, securityKey = None, asyncTimeout=3600, defaultWorkerThreads=10, logging=None): - self.connection = cloudstackConnection.cloudConnection(mgtSvr, port, apiKey, securityKey, asyncTimeout, logging) - self.apiClient = cloudstackAPIClient.CloudStackAPIClient(self.connection) - self.dbConnection = None - self.asyncJobMgr = None - self.ssh = None - self.defaultWorkerThreads = defaultWorkerThreads - - - def dbConfigure(self, host="localhost", port=3306, user='cloud', passwd='cloud', db='cloud'): - self.dbConnection = dbConnection.dbConnection(host, port, user, passwd, db) - - def isAdminContext(self): - """ - A user is a regular user if he fails to listDomains; - if he is a domain-admin, he can list only domains that are non-ROOT; - if he is an admin, he can list the ROOT domain successfully - """ - try: - listdom = listDomains.listDomainsCmd() - listdom.name = 'ROOT' - listdomres = self.apiClient.listDomains(listdom) - rootdom = listdomres[0].name - if rootdom == 'ROOT': - return 1 #admin - else: - return 2 #domain-admin - except: - return 0 #user - - def random_gen(self, size=6, chars=string.ascii_uppercase + string.digits): - """Generate Random Strings of variable length""" - return ''.join(random.choice(chars) for x in range(size)) - - def createNewApiClient(self, UserName, DomainName, acctType=0): - if not self.isAdminContext(): - return self.apiClient - - listDomain = listDomains.listDomainsCmd() - listDomain.listall = True - listDomain.name = DomainName - try: - domains = self.apiClient.listDomains(listDomain) - domId = domains[0].id - except: - cdomain = createDomain.createDomainCmd() - cdomain.name = DomainName - domain = self.apiClient.createDomain(cdomain) - domId = domain.id - - mdf = hashlib.md5() - mdf.update("password") - mdf_pass = mdf.hexdigest() - - cmd = listAccounts.listAccountsCmd() - cmd.name = UserName - cmd.domainid = domId - try: - accounts = self.apiClient.listAccounts(cmd) - acctId = accounts[0].id - except: - createAcctCmd = createAccount.createAccountCmd() - createAcctCmd.accounttype = acctType - createAcctCmd.domainid = domId - createAcctCmd.email = "test-" + self.random_gen() + "@citrix.com" - createAcctCmd.firstname = UserName - createAcctCmd.lastname = UserName - createAcctCmd.password = mdf_pass - createAcctCmd.username = UserName - acct = self.apiClient.createAccount(createAcctCmd) - acctId = acct.id - - listuser = listUsers.listUsersCmd() - listuser.username = UserName - - listuserRes = self.apiClient.listUsers(listuser) - userId = listuserRes[0].id - apiKey = listuserRes[0].apikey - securityKey = listuserRes[0].secretkey - - if apiKey is None: - registerUser = registerUserKeys.registerUserKeysCmd() - registerUser.id = userId - registerUserRes = self.apiClient.registerUserKeys(registerUser) - apiKey = registerUserRes.apikey - securityKey = registerUserRes.secretkey - - nConnection = cloudstackConnection.cloudConnection(self.connection.mgtSvr, self.connection.port, apiKey, securityKey, self.connection.asyncTimeout, self.connection.logging) - self.connection.close() - self.connection = nConnection - self.apiClient = cloudstackAPIClient.CloudStackAPIClient(self.connection) - - def close(self): - if self.connection is not None: - self.connection.close() - if self.dbConnection is not None: - self.dbConnection.close() - - def getDbConnection(self): - return self.dbConnection - - def executeSql(self, sql=None): - if sql is None or self.dbConnection is None: - return None - - return self.dbConnection.execute() - - def executeSqlFromFile(self, sqlFile=None): - if sqlFile is None or self.dbConnection is None: - return None - return self.dbConnection.executeSqlFromFile(sqlFile) - - def getApiClient(self): - return self.apiClient - - '''FixME, httplib has issue if more than one thread submitted''' - def submitCmdsAndWait(self, cmds, workers=1): - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection) - return self.asyncJobMgr.submitCmdsAndWait(cmds, workers) - - '''submit one job and execute the same job ntimes, with nums_threads of threads''' - def submitJob(self, job, ntimes=1, nums_threads=10, interval=1): - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection) - self.asyncJobMgr.submitJobExecuteNtimes(job, ntimes, nums_threads, interval) - - '''submit n jobs, execute them with nums_threads of threads''' - def submitJobs(self, jobs, nums_threads=10, interval=1): - if self.asyncJobMgr is None: - self.asyncJobMgr = asyncJobMgr.asyncJobMgr(self.apiClient, self.dbConnection) - self.asyncJobMgr.submitJobs(jobs, nums_threads, interval) \ No newline at end of file diff --git a/tools/testClient/codegenerator.py b/tools/testClient/codegenerator.py deleted file mode 100644 index c7190577096..00000000000 --- a/tools/testClient/codegenerator.py +++ /dev/null @@ -1,289 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import xml.dom.minidom -from optparse import OptionParser -import os -import sys -class cmdParameterProperty(object): - def __init__(self): - self.name = None - self.required = False - self.desc = "" - self.type = "planObject" - self.subProperties = [] - -class cloudStackCmd: - def __init__(self): - self.name = "" - self.desc = "" - self.async = "false" - self.request = [] - self.response = [] - -class codeGenerator: - space = " " - - cmdsName = [] - - def __init__(self, outputFolder, apiSpecFile): - self.cmd = None - self.code = "" - self.required = [] - self.subclass = [] - self.outputFolder = outputFolder - self.apiSpecFile = apiSpecFile - - def addAttribute(self, attr, pro): - value = pro.value - if pro.required: - self.required.append(attr) - desc = pro.desc - if desc is not None: - self.code += self.space - self.code += "''' " + pro.desc + " '''" - self.code += "\n" - - self.code += self.space - self.code += attr + " = " + str(value) - self.code += "\n" - - def generateSubClass(self, name, properties): - '''generate code for sub list''' - subclass = 'class %s:\n'%name - subclass += self.space + "def __init__(self):\n" - for pro in properties: - if pro.desc is not None: - subclass += self.space + self.space + '""""%s"""\n'%pro.desc - if len (pro.subProperties) > 0: - subclass += self.space + self.space + 'self.%s = []\n'%pro.name - self.generateSubClass(pro.name, pro.subProperties) - else: - subclass += self.space + self.space + 'self.%s = None\n'%pro.name - - self.subclass.append(subclass) - def generate(self, cmd): - - self.cmd = cmd - self.cmdsName.append(self.cmd.name) - self.code += "\n" - self.code += '"""%s"""\n'%self.cmd.desc - self.code += 'from baseCmd import *\n' - self.code += 'from baseResponse import *\n' - self.code += "class %sCmd (baseCmd):\n"%self.cmd.name - self.code += self.space + "def __init__(self):\n" - - self.code += self.space + self.space + 'self.isAsync = "%s"\n' %self.cmd.async - - for req in self.cmd.request: - if req.desc is not None: - self.code += self.space + self.space + '"""%s"""\n'%req.desc - if req.required == "true": - self.code += self.space + self.space + '"""Required"""\n' - - value = "None" - if req.type == "list" or req.type == "map": - value = "[]" - - self.code += self.space + self.space + 'self.%s = %s\n'%(req.name,value) - if req.required == "true": - self.required.append(req.name) - - self.code += self.space + self.space + "self.required = [" - for require in self.required: - self.code += '"' + require + '",' - self.code += "]\n" - self.required = [] - - - """generate response code""" - subItems = {} - self.code += "\n" - self.code += 'class %sResponse (baseResponse):\n'%self.cmd.name - self.code += self.space + "def __init__(self):\n" - if len(self.cmd.response) == 0: - self.code += self.space + self.space + "pass" - else: - for res in self.cmd.response: - if res.desc is not None: - self.code += self.space + self.space + '"""%s"""\n'%res.desc - - if len(res.subProperties) > 0: - self.code += self.space + self.space + 'self.%s = []\n'%res.name - self.generateSubClass(res.name, res.subProperties) - else: - self.code += self.space + self.space + 'self.%s = None\n'%res.name - self.code += '\n' - - for subclass in self.subclass: - self.code += subclass + "\n" - - fp = open(self.outputFolder + "/cloudstackAPI/%s.py"%self.cmd.name, "w") - fp.write(self.code) - fp.close() - self.code = "" - self.subclass = [] - - - def finalize(self): - '''generate an api call''' - - header = '"""Test Client for CloudStack API"""\n' - imports = "import copy\n" - initCmdsList = '__all__ = [' - body = '' - body += "class CloudStackAPIClient:\n" - body += self.space + 'def __init__(self, connection):\n' - body += self.space + self.space + 'self.connection = connection\n' - body += "\n" - - body += self.space + 'def __copy__(self):\n' - body += self.space + self.space + 'return CloudStackAPIClient(copy.copy(self.connection))\n' - body += "\n" - - for cmdName in self.cmdsName: - body += self.space + 'def %s(self,command):\n'%cmdName - body += self.space + self.space + 'response = %sResponse()\n'%cmdName - body += self.space + self.space + 'response = self.connection.make_request(command, response)\n' - body += self.space + self.space + 'return response\n' - body += '\n' - - imports += 'from %s import %sResponse\n'%(cmdName, cmdName) - initCmdsList += '"%s",'%cmdName - - fp = open(self.outputFolder + '/cloudstackAPI/cloudstackAPIClient.py', 'w') - for item in [header, imports, body]: - fp.write(item) - fp.close() - - '''generate __init__.py''' - initCmdsList += '"cloudstackAPIClient"]' - fp = open(self.outputFolder + '/cloudstackAPI/__init__.py', 'w') - fp.write(initCmdsList) - fp.close() - - fp = open(self.outputFolder + '/cloudstackAPI/baseCmd.py', 'w') - basecmd = '"""Base Command"""\n' - basecmd += 'class baseCmd:\n' - basecmd += self.space + 'pass\n' - fp.write(basecmd) - fp.close() - - fp = open(self.outputFolder + '/cloudstackAPI/baseResponse.py', 'w') - basecmd = '"""Base class for response"""\n' - basecmd += 'class baseResponse:\n' - basecmd += self.space + 'pass\n' - fp.write(basecmd) - fp.close() - - - def constructResponse(self, response): - paramProperty = cmdParameterProperty() - paramProperty.name = getText(response.getElementsByTagName('name')) - paramProperty.desc = getText(response.getElementsByTagName('description')) - if paramProperty.name.find('(*)') != -1: - '''This is a list''' - paramProperty.name = paramProperty.name.split('(*)')[0] - for subresponse in response.getElementsByTagName('arguments')[0].getElementsByTagName('arg'): - subProperty = self.constructResponse(subresponse) - paramProperty.subProperties.append(subProperty) - return paramProperty - - def loadCmdFromXML(self): - dom = xml.dom.minidom.parse(self.apiSpecFile) - cmds = [] - for cmd in dom.getElementsByTagName("command"): - csCmd = cloudStackCmd() - csCmd.name = getText(cmd.getElementsByTagName('name')) - assert csCmd.name - - desc = getText(cmd.getElementsByTagName('description')) - if desc: - csCmd.desc = desc - - async = getText(cmd.getElementsByTagName('isAsync')) - if async: - csCmd.async = async - - for param in cmd.getElementsByTagName("request")[0].getElementsByTagName("arg"): - paramProperty = cmdParameterProperty() - - paramProperty.name = getText(param.getElementsByTagName('name')) - assert paramProperty.name - - required = param.getElementsByTagName('required') - if required: - paramProperty.required = getText(required) - - requestDescription = param.getElementsByTagName('description') - if requestDescription: - paramProperty.desc = getText(requestDescription) - - type = param.getElementsByTagName("type") - if type: - paramProperty.type = getText(type) - - csCmd.request.append(paramProperty) - - responseEle = cmd.getElementsByTagName("response")[0] - for response in responseEle.getElementsByTagName("arg"): - if response.parentNode != responseEle: - continue - - paramProperty = self.constructResponse(response) - csCmd.response.append(paramProperty) - - cmds.append(csCmd) - return cmds - - def generateCode(self): - cmds = self.loadCmdFromXML() - for cmd in cmds: - self.generate(cmd) - self.finalize() - -def getText(elements): - return elements[0].childNodes[0].nodeValue.strip() - -if __name__ == "__main__": - parser = OptionParser() - - parser.add_option("-o", "--output", dest="output", help="the root path where code genereted, default is .") - parser.add_option("-s", "--specfile", dest="spec", help="the path and name of the api spec xml file, default is /etc/cloud/cli/commands.xml") - - (options, args) = parser.parse_args() - - apiSpecFile = "/etc/cloud/cli/commands.xml" - if options.spec is not None: - apiSpecFile = options.spec - - if not os.path.exists(apiSpecFile): - print "the spec file %s does not exists"%apiSpecFile - print parser.print_help() - exit(1) - - - folder = "." - if options.output is not None: - folder = options.output - apiModule=folder + "/cloudstackAPI" - if not os.path.exists(apiModule): - try: - os.mkdir(apiModule) - except: - print "Failed to create folder %s, due to %s"%(apiModule,sys.exc_info()) - print parser.print_help() - exit(2) - - cg = codeGenerator(folder, apiSpecFile) - cg.generateCode() - diff --git a/tools/testClient/configGenerator.py b/tools/testClient/configGenerator.py deleted file mode 100644 index ba639ff9882..00000000000 --- a/tools/testClient/configGenerator.py +++ /dev/null @@ -1,396 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import json -import os -from optparse import OptionParser -import jsonHelper - -class managementServer(): - def __init__(self): - self.mgtSvrIp = None - self.port = 8096 - self.apiKey = None - self.securityKey = None - -class dbServer(): - def __init__(self): - self.dbSvr = None - self.port = 3306 - self.user = "cloud" - self.passwd = "cloud" - self.db = "cloud" - -class configuration(): - def __init__(self): - self.name = None - self.value = None - -class logger(): - def __init__(self): - '''TestCase/TestClient''' - self.name = None - self.file = None - -class cloudstackConfiguration(): - def __init__(self): - self.zones = [] - self.mgtSvr = [] - self.dbSvr = None - self.globalConfig = [] - self.logger = [] - -class zone(): - def __init__(self): - self.dns1 = None - self.internaldns1 = None - self.name = None - '''Basic or Advanced''' - self.networktype = None - self.dns2 = None - self.internaldns2 = None - self.securitygroupenabled = None - ''' Guest Vlan range - only advanced zone''' - self.vlan = None - '''default public network, in advanced mode''' - self.ipranges = [] - self.networks = [] - self.pods = [] - self.secondaryStorages = [] - '''enable default virtual router provider''' - vrouter = provider() - vrouter.name = 'VirtualRouter' - self.providers = [vrouter] - -class provider(): - def __init__(self): - self.name = None - self.state = None - self.broadcastdomainrange = 'ZONE' - self.zoneid = None - self.servicelist = [] - -class pod(): - def __init__(self): - self.gateway = None - self.name = None - self.netmask = None - self.startip = None - self.endip = None - self.zoneid = None - self.clusters = [] - '''Used in basic network mode''' - self.guestIpRanges = [] - -class cluster(): - def __init__(self): - self.clustername = None - self.clustertype = None - self.hypervisor = None - self.zoneid = None - self.podid = None - self.password = None - self.url = None - self.username = None - self.hosts = [] - self.primaryStorages = [] - -class host(): - def __init__(self): - self.hypervisor = None - self.password = None - self.url = None - self.username = None - self.zoneid = None - self.podid = None - self.clusterid = None - self.clustername = None - self.cpunumber = None - self.cpuspeed = None - self.hostmac = None - self.hosttags = None - self.memory = None - -class network(): - def __init__(self): - self.displaytext = None - self.name = None - self.zoneid = None - self.acltype = None - self.domainid = None - self.networkdomain = None - self.networkofferingid = None - self.ipranges = [] - -class iprange(): - def __init__(self): - '''tagged/untagged''' - self.gateway = None - self.netmask = None - self.startip = None - self.endip = None - self.vlan = None - '''for account specific ''' - self.account = None - self.domain = None - -class primaryStorage(): - def __init__(self): - self.name = None - self.url = None - -class secondaryStorage(): - def __init__(self): - self.url = None - -'''sample code to generate setup configuration file''' -def describe_setup_in_basic_mode(): - zs = cloudstackConfiguration() - - for l in range(1): - z = zone() - z.dns1 = "8.8.8.8" - z.dns2 = "4.4.4.4" - z.internaldns1 = "192.168.110.254" - z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) - z.networktype = 'Basic' - - '''create 10 pods''' - for i in range(2): - p = pod() - p.name = "test" +str(l) + str(i) - p.gateway = "192.168.%d.1"%i - p.netmask = "255.255.255.0" - p.startip = "192.168.%d.150"%i - p.endip = "192.168.%d.220"%i - - '''add two pod guest ip ranges''' - for j in range(2): - ip = iprange() - ip.gateway = p.gateway - ip.netmask = p.netmask - ip.startip = "192.168.%d.%d"%(i,j*20) - ip.endip = "192.168.%d.%d"%(i,j*20+10) - - p.guestIpRanges.append(ip) - - '''add 10 clusters''' - for j in range(2): - c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) - c.clustertype = "CloudManaged" - c.hypervisor = "Simulator" - - '''add 10 hosts''' - for k in range(2): - h = host() - h.username = "root" - h.password = "password" - memory = 8*1024*1024*1024 - localstorage=1*1024*1024*1024*1024 - #h.url = "http://Sim/%d%d%d%d/cpucore=1&cpuspeed=8000&memory=%d&localstorage=%d"%(l,i,j,k,memory,localstorage) - h.url = "http://Sim/%d%d%d%d"%(l,i,j,k) - c.hosts.append(h) - - '''add 2 primary storages''' - for m in range(2): - primary = primaryStorage() - size=1*1024*1024*1024*1024 - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) - #primary.url = "nfs://localhost/path%s/size=%d"%(str(l) + str(i) + str(j) + str(m), size) - primary.url = "nfs://localhost/path%s"%(str(l) + str(i) + str(j) + str(m)) - c.primaryStorages.append(primary) - - p.clusters.append(c) - - z.pods.append(p) - - '''add two secondary''' - for i in range(5): - secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) - z.secondaryStorages.append(secondary) - - zs.zones.append(z) - - '''Add one mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = "localhost" - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = "localhost" - - zs.dbSvr = db - - '''add global configuration''' - global_settings = {'expunge.delay': '60', - 'expunge.interval': '60', - 'expunge.workers': '3', - } - for k,v in global_settings.iteritems(): - cfg = configuration() - cfg.name = k - cfg.value = v - zs.globalConfig.append(cfg) - - ''''add loggers''' - testClientLogger = logger() - testClientLogger.name = "TestClient" - testClientLogger.file = "/tmp/testclient.log" - - testCaseLogger = logger() - testCaseLogger.name = "TestCase" - testCaseLogger.file = "/tmp/testcase.log" - - zs.logger.append(testClientLogger) - zs.logger.append(testCaseLogger) - - return zs - -'''sample code to generate setup configuration file''' -def describe_setup_in_advanced_mode(): - zs = cloudstackConfiguration() - - for l in range(1): - z = zone() - z.dns1 = "8.8.8.8" - z.dns2 = "4.4.4.4" - z.internaldns1 = "192.168.110.254" - z.internaldns2 = "192.168.110.253" - z.name = "test"+str(l) - z.networktype = 'Advanced' - z.guestcidraddress = "10.1.1.0/24" - z.vlan = "100-2000" - - '''create 10 pods''' - for i in range(2): - p = pod() - p.name = "test" +str(l) + str(i) - p.gateway = "192.168.%d.1"%i - p.netmask = "255.255.255.0" - p.startip = "192.168.%d.200"%i - p.endip = "192.168.%d.220"%i - - '''add 10 clusters''' - for j in range(2): - c = cluster() - c.clustername = "test"+str(l)+str(i) + str(j) - c.clustertype = "CloudManaged" - c.hypervisor = "Simulator" - - '''add 10 hosts''' - for k in range(2): - h = host() - h.username = "root" - h.password = "password" - memory = 8*1024*1024*1024 - localstorage=1*1024*1024*1024*1024 - #h.url = "http://Sim/%d%d%d%d/cpucore=1&cpuspeed=8000&memory=%d&localstorage=%d"%(l,i,j,k,memory,localstorage) - h.url = "http://Sim/%d%d%d%d"%(l,i,j,k) - c.hosts.append(h) - - '''add 2 primary storages''' - for m in range(2): - primary = primaryStorage() - size=1*1024*1024*1024*1024 - primary.name = "primary"+str(l) + str(i) + str(j) + str(m) - #primary.url = "nfs://localhost/path%s/size=%d"%(str(l) + str(i) + str(j) + str(m), size) - primary.url = "nfs://localhost/path%s"%(str(l) + str(i) + str(j) + str(m)) - c.primaryStorages.append(primary) - - p.clusters.append(c) - - z.pods.append(p) - - '''add two secondary''' - for i in range(5): - secondary = secondaryStorage() - secondary.url = "nfs://localhost/path"+str(l) + str(i) - z.secondaryStorages.append(secondary) - - '''add default public network''' - ips = iprange() - ips.vlan = "26" - ips.startip = "172.16.26.2" - ips.endip = "172.16.26.100" - ips.gateway = "172.16.26.1" - ips.netmask = "255.255.255.0" - z.ipranges.append(ips) - - - zs.zones.append(z) - - '''Add one mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = "localhost" - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = "localhost" - - zs.dbSvr = db - - '''add global configuration''' - global_settings = {'expunge.delay': '60', - 'expunge.interval': '60', - 'expunge.workers': '3', - } - for k,v in global_settings.iteritems(): - cfg = configuration() - cfg.name = k - cfg.value = v - zs.globalConfig.append(cfg) - - ''''add loggers''' - testClientLogger = logger() - testClientLogger.name = "TestClient" - testClientLogger.file = "/tmp/testclient.log" - - testCaseLogger = logger() - testCaseLogger.name = "TestCase" - testCaseLogger.file = "/tmp/testcase.log" - - zs.logger.append(testClientLogger) - zs.logger.append(testCaseLogger) - - return zs - -def generate_setup_config(config, file=None): - describe = config - if file is None: - return json.dumps(jsonHelper.jsonDump.dump(describe)) - else: - fp = open(file, 'w') - json.dump(jsonHelper.jsonDump.dump(describe), fp, indent=4) - fp.close() - - -def get_setup_config(file): - if not os.path.exists(file): - return None - config = cloudstackConfiguration() - fp = open(file, 'r') - config = json.load(fp) - return jsonHelper.jsonLoader(config) - -if __name__ == "__main__": - parser = OptionParser() - - parser.add_option("-o", "--output", action="store", default="./datacenterCfg", dest="output", help="the path where the json config file generated, by default is ./datacenterCfg") - - (options, args) = parser.parse_args() - config = describe_setup_in_basic_mode() - generate_setup_config(config, options.output) diff --git a/tools/testClient/dbConnection.py b/tools/testClient/dbConnection.py deleted file mode 100644 index afe5be58695..00000000000 --- a/tools/testClient/dbConnection.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import pymysql -import cloudstackException -import sys -import os -import traceback -class dbConnection(object): - def __init__(self, host="localhost", port=3306, user='cloud', passwd='cloud', db='cloud'): - self.host = host - self.port = port - self.user = user - self.passwd = passwd - self.database = db - - try: - self.db = pymysql.Connect(host=host, port=port, user=user, passwd=passwd, db=db) - except: - traceback.print_exc() - raise cloudstackException.InvalidParameterException(sys.exc_info()) - - def __copy__(self): - return dbConnection(self.host, self.port, self.user, self.passwd, self.database) - - def close(self): - try: - self.db.close() - except: - pass - - def execute(self, sql=None): - if sql is None: - return None - - resultRow = [] - cursor = None - try: - # commit to restart the transaction, else we don't get fresh data - self.db.commit() - cursor = self.db.cursor() - cursor.execute(sql) - - result = cursor.fetchall() - if result is not None: - for r in result: - resultRow.append(r) - return resultRow - except pymysql.MySQLError, e: - raise cloudstackException.dbException("db Exception:%s"%e) - except: - raise cloudstackException.internalError(sys.exc_info()) - finally: - if cursor is not None: - cursor.close() - - def executeSqlFromFile(self, fileName=None): - if fileName is None: - raise cloudstackException.InvalidParameterException("file can't not none") - - if not os.path.exists(fileName): - raise cloudstackException.InvalidParameterException("%s not exists"%fileName) - - sqls = open(fileName, "r").read() - return self.execute(sqls) - -if __name__ == "__main__": - db = dbConnection() - ''' - try: - - result = db.executeSqlFromFile("/tmp/server-setup.sql") - if result is not None: - for r in result: - print r[0], r[1] - except cloudstackException.dbException, e: - print e - ''' - print db.execute("update vm_template set name='fjkd' where id=200") - for i in range(10): - result = db.execute("select job_status, created, last_updated from async_job where id=%d"%i) - print result - diff --git a/tools/testClient/deployAndRun.py b/tools/testClient/deployAndRun.py deleted file mode 100644 index b91453c22a9..00000000000 --- a/tools/testClient/deployAndRun.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import deployDataCenter -import TestCaseExecuteEngine -from optparse import OptionParser -import os -if __name__ == "__main__": - parser = OptionParser() - - parser.add_option("-c", "--config", action="store", default="./datacenterCfg", dest="config", help="the path where the json config file generated, by default is ./datacenterCfg") - parser.add_option("-d", "--directory", dest="testCaseFolder", help="the test case directory") - parser.add_option("-r", "--result", dest="result", help="test result log file") - parser.add_option("-t", dest="testcaselog", help="test case log file") - parser.add_option("-l", "--load", dest="load", action="store_true", help="only load config, do not deploy, it will only run testcase") - (options, args) = parser.parse_args() - if options.testCaseFolder is None: - parser.print_usage() - exit(1) - - testResultLogFile = None - if options.result is not None: - testResultLogFile = options.result - - testCaseLogFile = None - if options.testcaselog is not None: - testCaseLogFile = options.testcaselog - deploy = deployDataCenter.deployDataCenters(options.config) - if options.load: - deploy.loadCfg() - else: - deploy.deploy() - - testcaseEngine = TestCaseExecuteEngine.TestCaseExecuteEngine(deploy.testClient, options.testCaseFolder, testCaseLogFile, testResultLogFile) - testcaseEngine.run() \ No newline at end of file diff --git a/tools/testClient/deployDataCenter.py b/tools/testClient/deployDataCenter.py deleted file mode 100644 index aa40b00fba8..00000000000 --- a/tools/testClient/deployDataCenter.py +++ /dev/null @@ -1,395 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -"""Deploy datacenters according to a json configuration file""" -import configGenerator -import cloudstackException -import cloudstackTestClient -import sys -import logging -from cloudstackAPI import * -from optparse import OptionParser - -class deployDataCenters(): - - def __init__(self, cfgFile): - self.configFile = cfgFile - - def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): - if hosts is None: - return - for host in hosts: - hostcmd = addHost.addHostCmd() - hostcmd.clusterid = clusterId - hostcmd.cpunumber = host.cpunumer - hostcmd.cpuspeed = host.cpuspeed - hostcmd.hostmac = host.hostmac - hostcmd.hosttags = host.hosttags - hostcmd.hypervisor = host.hypervisor - hostcmd.memory = host.memory - hostcmd.password = host.password - hostcmd.podid = podId - hostcmd.url = host.url - hostcmd.username = host.username - hostcmd.zoneid = zoneId - hostcmd.hypervisor = hypervisor - self.apiClient.addHost(hostcmd) - - def createClusters(self, clusters, zoneId, podId): - if clusters is None: - return - - for cluster in clusters: - clustercmd = addCluster.addClusterCmd() - clustercmd.clustername = cluster.clustername - clustercmd.clustertype = cluster.clustertype - clustercmd.hypervisor = cluster.hypervisor - clustercmd.password = cluster.password - clustercmd.podid = podId - clustercmd.url = cluster.url - clustercmd.username = cluster.username - clustercmd.zoneid = zoneId - clusterresponse = self.apiClient.addCluster(clustercmd) - clusterId = clusterresponse[0].id - - self.addHosts(cluster.hosts, zoneId, podId, clusterId,\ - cluster.hypervisor) - self.createPrimaryStorages(cluster.primaryStorages, zoneId, podId,\ - clusterId) - - def createPrimaryStorages(self, primaryStorages, zoneId, podId, clusterId): - if primaryStorages is None: - return - for primary in primaryStorages: - primarycmd = createStoragePool.createStoragePoolCmd() - primarycmd.details = primary.details - primarycmd.name = primary.name - primarycmd.podid = podId - primarycmd.tags = primary.tags - primarycmd.url = primary.url - primarycmd.zoneid = zoneId - primarycmd.clusterid = clusterId - self.apiClient.createStoragePool(primarycmd) - - def createpods(self, pods, zone, zoneId): - if pods is None: - return - for pod in pods: - createpod = createPod.createPodCmd() - createpod.name = pod.name - createpod.gateway = pod.gateway - createpod.netmask = pod.netmask - createpod.startip = pod.startip - createpod.endip = pod.endip - createpod.zoneid = zoneId - createpodResponse = self.apiClient.createPod(createpod) - podId = createpodResponse.id - - if pod.guestIpRanges is not None: - self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId,\ - podId) - - self.createClusters(pod.clusters, zoneId, podId) - - def createVlanIpRanges(self, mode, ipranges, zoneId, podId=None,\ - networkId=None): - if ipranges is None: - return - for iprange in ipranges: - vlanipcmd = createVlanIpRange.createVlanIpRangeCmd() - vlanipcmd.account = iprange.account - vlanipcmd.domainid = iprange.domainid - vlanipcmd.endip = iprange.endip - vlanipcmd.gateway = iprange.gateway - vlanipcmd.netmask = iprange.netmask - vlanipcmd.networkid = networkId - vlanipcmd.podid = podId - vlanipcmd.startip = iprange.startip - vlanipcmd.zoneid = zoneId - vlanipcmd.vlan = iprange.vlan - if mode == "Basic": - vlanipcmd.forvirtualnetwork = "false" - else: - vlanipcmd.forvirtualnetwork = "true" - - self.apiClient.createVlanIpRange(vlanipcmd) - - def createSecondaryStorages(self, secondaryStorages, zoneId): - if secondaryStorages is None: - return - for secondary in secondaryStorages: - secondarycmd = addSecondaryStorage.addSecondaryStorageCmd() - secondarycmd.url = secondary.url - secondarycmd.zoneid = zoneId - self.apiClient.addSecondaryStorage(secondarycmd) - - def createnetworks(self, networks, zoneId, mode): - if networks is None: - return - for network in networks: - networkcmd = createNetwork.createNetworkCmd() - networkcmd.displaytext = network.displaytext - networkcmd.name = network.name - networkcmd.networkofferingid = network.networkofferingid - networkcmd.zoneid = zoneId - - ipranges = network.ipranges - if ipranges: - iprange = ipranges.pop() - networkcmd.startip = iprange.startip - networkcmd.endip = iprange.endip - networkcmd.gateway = iprange.gateway - networkcmd.netmask = iprange.netmask - - networkcmdresponse = self.apiClient.createNetwork(networkcmd) - networkId = networkcmdresponse.id - - self.createVlanIpRanges(mode, ipranges, zoneId, networkId) - - def createPhysicalNetwork(self, name, zoneid, vlan=None): - phynet = createPhysicalNetwork.createPhysicalNetworkCmd() - phynet.zoneid = zoneid - phynet.name = name - if vlan: - phynet.vlan = vlan - return self.apiClient.createPhysicalNetwork(phynet) - - def updatePhysicalNetwork(self, networkid, state="Enabled", vlan=None): - upnet = updatePhysicalNetwork.updatePhysicalNetworkCmd() - upnet.id = networkid - upnet.state = state - if vlan: - upnet.vlan = vlan - return self.apiClient.updatePhysicalNetwork(upnet) - - def configureProviders(self, phynetwrk, zone): - pnetprov = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - pnetprov.physicalnetworkid = phynetwrk.id - pnetprov.state = "Disabled" - pnetprov.name = "VirtualRouter" - pnetprovres = self.apiClient.listNetworkServiceProviders(pnetprov) - - vrprov = listVirtualRouterElements.listVirtualRouterElementsCmd() - vrprov.nspid = pnetprovres[0].id - vrprovresponse = self.apiClient.listVirtualRouterElements(vrprov) - vrprovid = vrprovresponse[0].id - - vrconfig = \ - configureVirtualRouterElement.configureVirtualRouterElementCmd() - vrconfig.enabled = "true" - vrconfig.id = vrprovid - vrconfigresponse = \ - self.apiClient.configureVirtualRouterElement(vrconfig) - - if zone.networktype == "Basic" and zone.securitygroupenabled: - sgprovider = configGenerator.provider() - sgprovider.name = "SecurityGroupProvider" - zone.providers.append(sgprovider) - - for prov in zone.providers: - pnetprov = \ - listNetworkServiceProviders.listNetworkServiceProvidersCmd() - pnetprov.physicalnetworkid = phynetwrk.id - pnetprov.name = prov.name - pnetprov.state = "Disabled" - pnetprovs = self.apiClient.listNetworkServiceProviders(pnetprov) - - upnetprov = \ - updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - upnetprov.id = pnetprovs[0].id - upnetprov.state = "Enabled" - upnetprovresponse = \ - self.apiClient.updateNetworkServiceProvider(upnetprov) - - def addTrafficTypes(self, physical_network_id, traffictypes=None, \ - network_labels=None): - [self.addTrafficType(physical_network_id, traffictype) for \ - traffictype in traffictypes] - - def addTrafficType(self, physical_network_id, traffictype, \ - network_label=None): - traffic_type = addTrafficType.addTrafficTypeCmd() - traffic_type.physicalnetworkid = physical_network_id - traffic_type.traffictype = traffictype - return self.apiClient.addTrafficType(traffic_type) - - def enableZone(self, zoneid, allocation_state="Enabled"): - zoneCmd = updateZone.updateZoneCmd() - zoneCmd.id = zoneid - zoneCmd.allocationstate = allocation_state - return self.apiClient.updateZone(zoneCmd) - - def createZones(self, zones): - for zone in zones: - createzone = createZone.createZoneCmd() - createzone.dns1 = zone.dns1 - createzone.dns2 = zone.dns2 - createzone.internaldns1 = zone.internaldns1 - createzone.internaldns2 = zone.internaldns2 - createzone.name = zone.name - createzone.securitygroupenabled = zone.securitygroupenabled - createzone.networktype = zone.networktype - createzone.guestcidraddress = zone.guestcidraddress - - zoneresponse = self.apiClient.createZone(createzone) - zoneId = zoneresponse.id - - phynetwrk = self.createPhysicalNetwork(zone.name + "-pnet", \ - zoneId) - - self.addTrafficTypes(phynetwrk.id, ["Guest", "Public", \ - "Management"]) - - self.configureProviders(phynetwrk, zone) - self.updatePhysicalNetwork(phynetwrk.id, "Enabled", vlan=zone.vlan) - - if zone.networktype == "Basic": - listnetworkoffering = \ - listNetworkOfferings.listNetworkOfferingsCmd() - - listnetworkoffering.name = \ - "DefaultSharedNetworkOfferingWithSGService" - - listnetworkofferingresponse = \ - self.apiClient.listNetworkOfferings(listnetworkoffering) - - guestntwrk = configGenerator.network() - guestntwrk.displaytext = "guestNetworkForBasicZone" - guestntwrk.name = "guestNetworkForBasicZone" - guestntwrk.zoneid = zoneId - guestntwrk.networkofferingid = \ - listnetworkofferingresponse[0].id - self.createnetworks([guestntwrk], zoneId, zone.networktype) - - self.createpods(zone.pods, zone, zoneId) - - if zone.networktype == "Advanced": - self.createVlanIpRanges(zone.networktype, zone.ipranges, \ - zoneId) - - self.createSecondaryStorages(zone.secondaryStorages, zoneId) - self.enableZone(zoneId, "Enabled") - return - - def registerApiKey(self): - listuser = listUsers.listUsersCmd() - listuser.account = "admin" - listuserRes = self.testClient.getApiClient().listUsers(listuser) - userId = listuserRes[0].id - apiKey = listuserRes[0].apikey - securityKey = listuserRes[0].secretkey - if apiKey is None: - registerUser = registerUserKeys.registerUserKeysCmd() - registerUser.id = userId - registerUserRes = \ - self.testClient.getApiClient().registerUserKeys(registerUser) - - apiKey = registerUserRes.apikey - securityKey = registerUserRes.secretkey - - self.config.mgtSvr[0].port = 8080 - self.config.mgtSvr[0].apiKey = apiKey - self.config.mgtSvr[0].securityKey = securityKey - return apiKey, securityKey - - def loadCfg(self): - try: - self.config = configGenerator.get_setup_config(self.configFile) - except: - raise cloudstackException.InvalidParameterException( \ - "Failed to load config %s" %sys.exc_info()) - - mgt = self.config.mgtSvr[0] - - loggers = self.config.logger - testClientLogFile = None - self.testCaseLogFile = None - self.testResultLogFile = None - if loggers is not None and len(loggers) > 0: - for log in loggers: - if log.name == "TestClient": - testClientLogFile = log.file - elif log.name == "TestCase": - self.testCaseLogFile = log.file - elif log.name == "TestResult": - self.testResultLogFile = log.file - - testClientLogger = None - if testClientLogFile is not None: - testClientLogger = logging.getLogger("testclient.testengine.run") - fh = logging.FileHandler(testClientLogFile) - fh.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")) - testClientLogger.addHandler(fh) - testClientLogger.setLevel(logging.INFO) - self.testClientLogger = testClientLogger - - self.testClient = \ - cloudstackTestClient.cloudstackTestClient(mgt.mgtSvrIp, mgt.port, \ - mgt.apiKey, \ - mgt.securityKey, \ - logging=self.testClientLogger) - if mgt.apiKey is None: - apiKey, securityKey = self.registerApiKey() - self.testClient.close() - self.testClient = \ - cloudstackTestClient.cloudstackTestClient(mgt.mgtSvrIp, 8080, \ - apiKey, securityKey, \ - logging=self.testClientLogger) - - """config database""" - dbSvr = self.config.dbSvr - self.testClient.dbConfigure(dbSvr.dbSvr, dbSvr.port, dbSvr.user, \ - dbSvr.passwd, dbSvr.db) - self.apiClient = self.testClient.getApiClient() - - def updateConfiguration(self, globalCfg): - if globalCfg is None: - return None - - for config in globalCfg: - updateCfg = updateConfiguration.updateConfigurationCmd() - updateCfg.name = config.name - updateCfg.value = config.value - self.apiClient.updateConfiguration(updateCfg) - - def deploy(self): - self.loadCfg() - self.createZones(self.config.zones) - self.updateConfiguration(self.config.globalConfig) - - -if __name__ == "__main__": - - parser = OptionParser() - - parser.add_option("-i", "--intput", action="store", \ - default="./datacenterCfg", dest="input", help="the path \ - where the json config file generated, by default is \ - ./datacenterCfg") - - (options, args) = parser.parse_args() - - deploy = deployDataCenters(options.input) - deploy.deploy() - - """ - create = createStoragePool.createStoragePoolCmd() - create.clusterid = 1 - create.podid = 2 - create.name = "fdffdf" - create.url = "nfs://jfkdjf/fdkjfkd" - create.zoneid = 2 - - deploy = deployDataCenters("./datacenterCfg") - deploy.loadCfg() - deploy.apiClient.createStoragePool(create) - """ diff --git a/tools/testClient/jsonHelper.py b/tools/testClient/jsonHelper.py deleted file mode 100644 index aa817b7883b..00000000000 --- a/tools/testClient/jsonHelper.py +++ /dev/null @@ -1,192 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import cloudstackException -import json -import inspect -from cloudstackAPI import * -import pdb - -class jsonLoader: - '''The recursive class for building and representing objects with.''' - def __init__(self, obj): - for k in obj: - v = obj[k] - if isinstance(v, dict): - setattr(self, k, jsonLoader(v)) - elif isinstance(v, (list, tuple)): - if len(v) > 0 and isinstance(v[0], dict): - setattr(self, k, [jsonLoader(elem) for elem in v]) - else: - setattr(self, k, v) - else: - setattr(self,k,v) - def __getattr__(self, val): - if val in self.__dict__: - return self.__dict__[val] - else: - return None - def __repr__(self): - return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) - def __str__(self): - return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems())) - - -class jsonDump: - @staticmethod - def __serialize(obj): - """Recursively walk object's hierarchy.""" - if isinstance(obj, (bool, int, long, float, basestring)): - return obj - elif isinstance(obj, dict): - obj = obj.copy() - newobj = {} - for key in obj: - if obj[key] is not None: - if (isinstance(obj[key], list) and len(obj[key]) == 0): - continue - newobj[key] = jsonDump.__serialize(obj[key]) - - return newobj - elif isinstance(obj, list): - return [jsonDump.__serialize(item) for item in obj] - elif isinstance(obj, tuple): - return tuple(jsonDump.__serialize([item for item in obj])) - elif hasattr(obj, '__dict__'): - return jsonDump.__serialize(obj.__dict__) - else: - return repr(obj) # Don't know how to handle, convert to string - - @staticmethod - def dump(obj): - return jsonDump.__serialize(obj) - -def getclassFromName(cmd, name): - module = inspect.getmodule(cmd) - return getattr(module, name)() - -def finalizeResultObj(result, responseName, responsecls): - if responsecls is None and responseName.endswith("response") and responseName != "queryasyncjobresultresponse": - '''infer the response class from the name''' - moduleName = responseName.replace("response", "") - try: - responsecls = getclassFromName(moduleName, responseName) - except: - pass - - if responseName is not None and responseName == "queryasyncjobresultresponse" and responsecls is not None and result.jobresult is not None: - result.jobresult = finalizeResultObj(result.jobresult, None, responsecls) - return result - elif responsecls is not None: - for k,v in result.__dict__.iteritems(): - if k in responsecls.__dict__: - return result - - attr = result.__dict__.keys()[0] - - value = getattr(result, attr) - if not isinstance(value, jsonLoader): - return result - - findObj = False - for k,v in value.__dict__.iteritems(): - if k in responsecls.__dict__: - findObj = True - break - if findObj: - return value - else: - return result - else: - return result - - - -def getResultObj(returnObj, responsecls=None): - returnObj = json.loads(returnObj) - - if len(returnObj) == 0: - return None - responseName = returnObj.keys()[0] - - response = returnObj[responseName] - if len(response) == 0: - return None - - result = jsonLoader(response) - if result.errorcode is not None: - errMsg = "errorCode: %s, errorText:%s"%(result.errorcode, result.errortext) - raise cloudstackException.cloudstackAPIException(responseName.replace("response", ""), errMsg) - - if result.count is not None: - for key in result.__dict__.iterkeys(): - if key == "count": - continue - else: - return getattr(result, key) - else: - return finalizeResultObj(result, responseName, responsecls) - -if __name__ == "__main__": - - result = '{ "listnetworkserviceprovidersresponse" : { "count":1 ,"networkserviceprovider" : [ {"name":"VirtualRouter","physicalnetworkid":"ad2948fc-1054-46c7-b1c7-61d990b86710","destinationphysicalnetworkid":"0","state":"Disabled","id":"d827cae4-4998-4037-95a2-55b92b6318b1","servicelist":["Vpn","Dhcp","Dns","Gateway","Firewall","Lb","SourceNat","StaticNat","PortForwarding","UserData"]} ] } }' - nsp = getResultObj(result) - print nsp[0].id - - result = '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"4.4.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"5e818a11-6b00-3429-9a07-e27511d3169a","dhcpprovider":"DhcpServer"} ] } }' - zones = getResultObj(result) - print zones[0].id - res = authorizeSecurityGroupIngress.authorizeSecurityGroupIngressResponse() - result = '{ "queryasyncjobresultresponse" : {"jobid":10,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"securitygroup":{"id":1,"name":"default","description":"Default Security Group","account":"admin","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":1,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"default","account":"a"},{"ruleid":2,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"default","account":"b"}]}}} }' - asynJob = getResultObj(result, res) - print asynJob.jobid, repr(asynJob.jobresult) - print asynJob.jobresult.ingressrule[0].account - - result = '{ "queryasyncjobresultresponse" : {"errorcode" : 431, "errortext" : "Unable to execute API command queryasyncjobresultresponse due to missing parameter jobid"} }' - try: - asynJob = getResultObj(result) - except cloudstackException.cloudstackAPIException, e: - print e - - result = '{ "queryasyncjobresultresponse" : {} }' - asynJob = getResultObj(result) - print asynJob - - result = '{}' - asynJob = getResultObj(result) - print asynJob - - result = '{ "createzoneresponse" : { "zone" : {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"4.4.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"3442f287-e932-3111-960b-514d1f9c4610","dhcpprovider":"DhcpServer"} } }' - res = createZone.createZoneResponse() - zone = getResultObj(result, res) - print zone.id - - result = '{ "attachvolumeresponse" : {"jobid":24} }' - res = attachVolume.attachVolumeResponse() - res = getResultObj(result, res) - print res - - result = '{ "listtemplatesresponse" : { } }' - print getResultObj(result, listTemplates.listTemplatesResponse()) - - result = '{ "queryasyncjobresultresponse" : {"jobid":34,"jobstatus":2,"jobprocstatus":0,"jobresultcode":530,"jobresulttype":"object","jobresult":{"errorcode":431,"errortext":"Please provide either a volume id, or a tuple(device id, instance id)"}} }' - print getResultObj(result, listTemplates.listTemplatesResponse()) - result = '{ "queryasyncjobresultresponse" : {"jobid":41,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"virtualmachine":{"id":37,"name":"i-2-37-TEST","displayname":"i-2-37-TEST","account":"admin","domainid":1,"domain":"ROOT","created":"2011-08-25T11:13:42-0700","state":"Running","haenable":false,"zoneid":1,"zonename":"test0","hostid":5,"hostname":"SimulatedAgent.1e629060-f547-40dd-b792-57cdc4b7d611","templateid":10,"templatename":"CentOS 5.3(64-bit) no GUI (Simulator)","templatedisplaytext":"CentOS 5.3(64-bit) no GUI (Simulator)","passwordenabled":false,"serviceofferingid":7,"serviceofferingname":"Small Instance","cpunumber":1,"cpuspeed":500,"memory":512,"guestosid":11,"rootdeviceid":0,"rootdevicetype":"NetworkFilesystem","securitygroup":[{"id":1,"name":"default","description":"Default Security Group"}],"nic":[{"id":43,"networkid":204,"netmask":"255.255.255.0","gateway":"192.168.1.1","ipaddress":"192.168.1.27","isolationuri":"ec2://untagged","broadcasturi":"vlan://untagged","traffictype":"Guest","type":"Direct","isdefault":true,"macaddress":"06:56:b8:00:00:53"}],"hypervisor":"Simulator"}}} }' - - result='{ "queryasyncjobresultresponse" : {"accountid":"30910093-22e4-4d3c-a464-8b36b60c8001","userid":"cb0aeca3-42ee-47c4-838a-2cd9053441f2","cmd":"com.cloud.api.commands.DeployVMCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"virtualmachine":{"id":"d2e4d724-e089-4e59-be8e-647674059016","name":"i-2-14-TEST","displayname":"i-2-14-TEST","account":"admin","domainid":"8cfafe79-81eb-445e-8608-c5b7c31fc3a5","domain":"ROOT","created":"2012-01-15T18:30:11+0530","state":"Running","haenable":false,"zoneid":"30a397e2-1c85-40c0-8463-70278952b046","zonename":"Sandbox-simulator","hostid":"cc0105aa-a2a9-427a-8ad7-4d835483b8a9","hostname":"SimulatedAgent.9fee20cc-95ca-48b1-8268-5513d6e83a1b","templateid":"d92570fa-bf40-44db-9dff-45cc7042604d","templatename":"CentOS 5.3(64-bit) no GUI (Simulator)","templatedisplaytext":"CentOS 5.3(64-bit) no GUI (Simulator)","passwordenabled":false,"serviceofferingid":"3734d632-797b-4f1d-ac62-33f9cf70d005","serviceofferingname":"Sample SO","cpunumber":1,"cpuspeed":100,"memory":128,"guestosid":"1e36f523-23e5-4e90-869b-a1b5e9ba674d","rootdeviceid":0,"rootdevicetype":"NetworkFilesystem","nic":[{"id":"4d3ab903-f511-4dab-8a6d-c2a3b51de7e0","networkid":"faeb7f24-a4b9-447d-bec6-c4956c4ab0f6","netmask":"255.255.240.0","gateway":"10.6.240.1","ipaddress":"10.6.253.89","isolationuri":"vlan://211","broadcasturi":"vlan://211","traffictype":"Guest","type":"Isolated","isdefault":true,"macaddress":"02:00:04:74:00:09"}],"hypervisor":"Simulator"}},"created":"2012-01-15T18:30:11+0530","jobid":"f4a13f28-fcd6-4d7f-b9cd-ba7eb5a5701f"} }' - vm = getResultObj(result, deployVirtualMachine.deployVirtualMachineResponse()) - print vm.jobresult.id - - cmd = deployVirtualMachine.deployVirtualMachineCmd() - responsename = cmd.__class__.__name__.replace("Cmd", "Response") - response = getclassFromName(cmd, responsename) - print response.id diff --git a/tools/testClient/pymysql/__init__.py b/tools/testClient/pymysql/__init__.py deleted file mode 100644 index c423a3d7e95..00000000000 --- a/tools/testClient/pymysql/__init__.py +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -''' -PyMySQL: A pure-Python drop-in replacement for MySQLdb. - -Copyright (c) 2010 PyMySQL contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -''' - -VERSION = (0, 4, None) - -from constants import FIELD_TYPE -from converters import escape_dict, escape_sequence, escape_string -from err import Warning, Error, InterfaceError, DataError, \ - DatabaseError, OperationalError, IntegrityError, InternalError, \ - NotSupportedError, ProgrammingError, MySQLError -from times import Date, Time, Timestamp, \ - DateFromTicks, TimeFromTicks, TimestampFromTicks - -import sys - -try: - frozenset -except NameError: - from sets import ImmutableSet as frozenset - try: - from sets import BaseSet as set - except ImportError: - from sets import Set as set - -threadsafety = 1 -apilevel = "2.0" -paramstyle = "format" - -class DBAPISet(frozenset): - - - def __ne__(self, other): - if isinstance(other, set): - return super(DBAPISet, self).__ne__(self, other) - else: - return other not in self - - def __eq__(self, other): - if isinstance(other, frozenset): - return frozenset.__eq__(self, other) - else: - return other in self - - def __hash__(self): - return frozenset.__hash__(self) - - -STRING = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING, - FIELD_TYPE.VAR_STRING]) -BINARY = DBAPISet([FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB, - FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.TINY_BLOB]) -NUMBER = DBAPISet([FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT, - FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG, - FIELD_TYPE.TINY, FIELD_TYPE.YEAR]) -DATE = DBAPISet([FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE]) -TIME = DBAPISet([FIELD_TYPE.TIME]) -TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME]) -DATETIME = TIMESTAMP -ROWID = DBAPISet() - -def Binary(x): - """Return x as a binary type.""" - return str(x) - -def Connect(*args, **kwargs): - """ - Connect to the database; see connections.Connection.__init__() for - more information. - """ - from connections import Connection - return Connection(*args, **kwargs) - -def get_client_info(): # for MySQLdb compatibility - return '%s.%s.%s' % VERSION - -connect = Connection = Connect - -# we include a doctored version_info here for MySQLdb compatibility -version_info = (1,2,2,"final",0) - -NULL = "NULL" - -__version__ = get_client_info() - -def thread_safe(): - return True # match MySQLdb.thread_safe() - -def install_as_MySQLdb(): - """ - After this function is called, any application that imports MySQLdb or - _mysql will unwittingly actually use - """ - sys.modules["MySQLdb"] = sys.modules["_mysql"] = sys.modules["pymysql"] - -__all__ = [ - 'BINARY', 'Binary', 'Connect', 'Connection', 'DATE', 'Date', - 'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks', 'TimestampFromTicks', - 'DataError', 'DatabaseError', 'Error', 'FIELD_TYPE', 'IntegrityError', - 'InterfaceError', 'InternalError', 'MySQLError', 'NULL', 'NUMBER', - 'NotSupportedError', 'DBAPISet', 'OperationalError', 'ProgrammingError', - 'ROWID', 'STRING', 'TIME', 'TIMESTAMP', 'Warning', 'apilevel', 'connect', - 'connections', 'constants', 'converters', 'cursors', - 'escape_dict', 'escape_sequence', 'escape_string', 'get_client_info', - 'paramstyle', 'threadsafety', 'version_info', - - "install_as_MySQLdb", - - "NULL","__version__", - ] diff --git a/tools/testClient/pymysql/charset.py b/tools/testClient/pymysql/charset.py deleted file mode 100644 index 87f00986b5c..00000000000 --- a/tools/testClient/pymysql/charset.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -MBLENGTH = { - 8:1, - 33:3, - 88:2, - 91:2 - } - -class Charset: - def __init__(self, id, name, collation, is_default): - self.id, self.name, self.collation = id, name, collation - self.is_default = is_default == 'Yes' - -class Charsets: - def __init__(self): - self._by_id = {} - - def add(self, c): - self._by_id[c.id] = c - - def by_id(self, id): - return self._by_id[id] - - def by_name(self, name): - for c in self._by_id.values(): - if c.name == name and c.is_default: - return c - -_charsets = Charsets() -""" -Generated with: - -mysql -N -s -e "select id, character_set_name, collation_name, is_default -from information_schema.collations order by id;" | python -c "import sys -for l in sys.stdin.readlines(): - id, name, collation, is_default = l.split(chr(9)) - print '_charsets.add(Charset(%s, \'%s\', \'%s\', \'%s\'))' \ - % (id, name, collation, is_default.strip()) -" - -""" -_charsets.add(Charset(1, 'big5', 'big5_chinese_ci', 'Yes')) -_charsets.add(Charset(2, 'latin2', 'latin2_czech_cs', '')) -_charsets.add(Charset(3, 'dec8', 'dec8_swedish_ci', 'Yes')) -_charsets.add(Charset(4, 'cp850', 'cp850_general_ci', 'Yes')) -_charsets.add(Charset(5, 'latin1', 'latin1_german1_ci', '')) -_charsets.add(Charset(6, 'hp8', 'hp8_english_ci', 'Yes')) -_charsets.add(Charset(7, 'koi8r', 'koi8r_general_ci', 'Yes')) -_charsets.add(Charset(8, 'latin1', 'latin1_swedish_ci', 'Yes')) -_charsets.add(Charset(9, 'latin2', 'latin2_general_ci', 'Yes')) -_charsets.add(Charset(10, 'swe7', 'swe7_swedish_ci', 'Yes')) -_charsets.add(Charset(11, 'ascii', 'ascii_general_ci', 'Yes')) -_charsets.add(Charset(12, 'ujis', 'ujis_japanese_ci', 'Yes')) -_charsets.add(Charset(13, 'sjis', 'sjis_japanese_ci', 'Yes')) -_charsets.add(Charset(14, 'cp1251', 'cp1251_bulgarian_ci', '')) -_charsets.add(Charset(15, 'latin1', 'latin1_danish_ci', '')) -_charsets.add(Charset(16, 'hebrew', 'hebrew_general_ci', 'Yes')) -_charsets.add(Charset(18, 'tis620', 'tis620_thai_ci', 'Yes')) -_charsets.add(Charset(19, 'euckr', 'euckr_korean_ci', 'Yes')) -_charsets.add(Charset(20, 'latin7', 'latin7_estonian_cs', '')) -_charsets.add(Charset(21, 'latin2', 'latin2_hungarian_ci', '')) -_charsets.add(Charset(22, 'koi8u', 'koi8u_general_ci', 'Yes')) -_charsets.add(Charset(23, 'cp1251', 'cp1251_ukrainian_ci', '')) -_charsets.add(Charset(24, 'gb2312', 'gb2312_chinese_ci', 'Yes')) -_charsets.add(Charset(25, 'greek', 'greek_general_ci', 'Yes')) -_charsets.add(Charset(26, 'cp1250', 'cp1250_general_ci', 'Yes')) -_charsets.add(Charset(27, 'latin2', 'latin2_croatian_ci', '')) -_charsets.add(Charset(28, 'gbk', 'gbk_chinese_ci', 'Yes')) -_charsets.add(Charset(29, 'cp1257', 'cp1257_lithuanian_ci', '')) -_charsets.add(Charset(30, 'latin5', 'latin5_turkish_ci', 'Yes')) -_charsets.add(Charset(31, 'latin1', 'latin1_german2_ci', '')) -_charsets.add(Charset(32, 'armscii8', 'armscii8_general_ci', 'Yes')) -_charsets.add(Charset(33, 'utf8', 'utf8_general_ci', 'Yes')) -_charsets.add(Charset(34, 'cp1250', 'cp1250_czech_cs', '')) -_charsets.add(Charset(35, 'ucs2', 'ucs2_general_ci', 'Yes')) -_charsets.add(Charset(36, 'cp866', 'cp866_general_ci', 'Yes')) -_charsets.add(Charset(37, 'keybcs2', 'keybcs2_general_ci', 'Yes')) -_charsets.add(Charset(38, 'macce', 'macce_general_ci', 'Yes')) -_charsets.add(Charset(39, 'macroman', 'macroman_general_ci', 'Yes')) -_charsets.add(Charset(40, 'cp852', 'cp852_general_ci', 'Yes')) -_charsets.add(Charset(41, 'latin7', 'latin7_general_ci', 'Yes')) -_charsets.add(Charset(42, 'latin7', 'latin7_general_cs', '')) -_charsets.add(Charset(43, 'macce', 'macce_bin', '')) -_charsets.add(Charset(44, 'cp1250', 'cp1250_croatian_ci', '')) -_charsets.add(Charset(47, 'latin1', 'latin1_bin', '')) -_charsets.add(Charset(48, 'latin1', 'latin1_general_ci', '')) -_charsets.add(Charset(49, 'latin1', 'latin1_general_cs', '')) -_charsets.add(Charset(50, 'cp1251', 'cp1251_bin', '')) -_charsets.add(Charset(51, 'cp1251', 'cp1251_general_ci', 'Yes')) -_charsets.add(Charset(52, 'cp1251', 'cp1251_general_cs', '')) -_charsets.add(Charset(53, 'macroman', 'macroman_bin', '')) -_charsets.add(Charset(57, 'cp1256', 'cp1256_general_ci', 'Yes')) -_charsets.add(Charset(58, 'cp1257', 'cp1257_bin', '')) -_charsets.add(Charset(59, 'cp1257', 'cp1257_general_ci', 'Yes')) -_charsets.add(Charset(63, 'binary', 'binary', 'Yes')) -_charsets.add(Charset(64, 'armscii8', 'armscii8_bin', '')) -_charsets.add(Charset(65, 'ascii', 'ascii_bin', '')) -_charsets.add(Charset(66, 'cp1250', 'cp1250_bin', '')) -_charsets.add(Charset(67, 'cp1256', 'cp1256_bin', '')) -_charsets.add(Charset(68, 'cp866', 'cp866_bin', '')) -_charsets.add(Charset(69, 'dec8', 'dec8_bin', '')) -_charsets.add(Charset(70, 'greek', 'greek_bin', '')) -_charsets.add(Charset(71, 'hebrew', 'hebrew_bin', '')) -_charsets.add(Charset(72, 'hp8', 'hp8_bin', '')) -_charsets.add(Charset(73, 'keybcs2', 'keybcs2_bin', '')) -_charsets.add(Charset(74, 'koi8r', 'koi8r_bin', '')) -_charsets.add(Charset(75, 'koi8u', 'koi8u_bin', '')) -_charsets.add(Charset(77, 'latin2', 'latin2_bin', '')) -_charsets.add(Charset(78, 'latin5', 'latin5_bin', '')) -_charsets.add(Charset(79, 'latin7', 'latin7_bin', '')) -_charsets.add(Charset(80, 'cp850', 'cp850_bin', '')) -_charsets.add(Charset(81, 'cp852', 'cp852_bin', '')) -_charsets.add(Charset(82, 'swe7', 'swe7_bin', '')) -_charsets.add(Charset(83, 'utf8', 'utf8_bin', '')) -_charsets.add(Charset(84, 'big5', 'big5_bin', '')) -_charsets.add(Charset(85, 'euckr', 'euckr_bin', '')) -_charsets.add(Charset(86, 'gb2312', 'gb2312_bin', '')) -_charsets.add(Charset(87, 'gbk', 'gbk_bin', '')) -_charsets.add(Charset(88, 'sjis', 'sjis_bin', '')) -_charsets.add(Charset(89, 'tis620', 'tis620_bin', '')) -_charsets.add(Charset(90, 'ucs2', 'ucs2_bin', '')) -_charsets.add(Charset(91, 'ujis', 'ujis_bin', '')) -_charsets.add(Charset(92, 'geostd8', 'geostd8_general_ci', 'Yes')) -_charsets.add(Charset(93, 'geostd8', 'geostd8_bin', '')) -_charsets.add(Charset(94, 'latin1', 'latin1_spanish_ci', '')) -_charsets.add(Charset(95, 'cp932', 'cp932_japanese_ci', 'Yes')) -_charsets.add(Charset(96, 'cp932', 'cp932_bin', '')) -_charsets.add(Charset(97, 'eucjpms', 'eucjpms_japanese_ci', 'Yes')) -_charsets.add(Charset(98, 'eucjpms', 'eucjpms_bin', '')) -_charsets.add(Charset(99, 'cp1250', 'cp1250_polish_ci', '')) -_charsets.add(Charset(128, 'ucs2', 'ucs2_unicode_ci', '')) -_charsets.add(Charset(129, 'ucs2', 'ucs2_icelandic_ci', '')) -_charsets.add(Charset(130, 'ucs2', 'ucs2_latvian_ci', '')) -_charsets.add(Charset(131, 'ucs2', 'ucs2_romanian_ci', '')) -_charsets.add(Charset(132, 'ucs2', 'ucs2_slovenian_ci', '')) -_charsets.add(Charset(133, 'ucs2', 'ucs2_polish_ci', '')) -_charsets.add(Charset(134, 'ucs2', 'ucs2_estonian_ci', '')) -_charsets.add(Charset(135, 'ucs2', 'ucs2_spanish_ci', '')) -_charsets.add(Charset(136, 'ucs2', 'ucs2_swedish_ci', '')) -_charsets.add(Charset(137, 'ucs2', 'ucs2_turkish_ci', '')) -_charsets.add(Charset(138, 'ucs2', 'ucs2_czech_ci', '')) -_charsets.add(Charset(139, 'ucs2', 'ucs2_danish_ci', '')) -_charsets.add(Charset(140, 'ucs2', 'ucs2_lithuanian_ci', '')) -_charsets.add(Charset(141, 'ucs2', 'ucs2_slovak_ci', '')) -_charsets.add(Charset(142, 'ucs2', 'ucs2_spanish2_ci', '')) -_charsets.add(Charset(143, 'ucs2', 'ucs2_roman_ci', '')) -_charsets.add(Charset(144, 'ucs2', 'ucs2_persian_ci', '')) -_charsets.add(Charset(145, 'ucs2', 'ucs2_esperanto_ci', '')) -_charsets.add(Charset(146, 'ucs2', 'ucs2_hungarian_ci', '')) -_charsets.add(Charset(192, 'utf8', 'utf8_unicode_ci', '')) -_charsets.add(Charset(193, 'utf8', 'utf8_icelandic_ci', '')) -_charsets.add(Charset(194, 'utf8', 'utf8_latvian_ci', '')) -_charsets.add(Charset(195, 'utf8', 'utf8_romanian_ci', '')) -_charsets.add(Charset(196, 'utf8', 'utf8_slovenian_ci', '')) -_charsets.add(Charset(197, 'utf8', 'utf8_polish_ci', '')) -_charsets.add(Charset(198, 'utf8', 'utf8_estonian_ci', '')) -_charsets.add(Charset(199, 'utf8', 'utf8_spanish_ci', '')) -_charsets.add(Charset(200, 'utf8', 'utf8_swedish_ci', '')) -_charsets.add(Charset(201, 'utf8', 'utf8_turkish_ci', '')) -_charsets.add(Charset(202, 'utf8', 'utf8_czech_ci', '')) -_charsets.add(Charset(203, 'utf8', 'utf8_danish_ci', '')) -_charsets.add(Charset(204, 'utf8', 'utf8_lithuanian_ci', '')) -_charsets.add(Charset(205, 'utf8', 'utf8_slovak_ci', '')) -_charsets.add(Charset(206, 'utf8', 'utf8_spanish2_ci', '')) -_charsets.add(Charset(207, 'utf8', 'utf8_roman_ci', '')) -_charsets.add(Charset(208, 'utf8', 'utf8_persian_ci', '')) -_charsets.add(Charset(209, 'utf8', 'utf8_esperanto_ci', '')) -_charsets.add(Charset(210, 'utf8', 'utf8_hungarian_ci', '')) - -def charset_by_name(name): - return _charsets.by_name(name) - -def charset_by_id(id): - return _charsets.by_id(id) - diff --git a/tools/testClient/pymysql/connections.py b/tools/testClient/pymysql/connections.py deleted file mode 100644 index bb37143bc78..00000000000 --- a/tools/testClient/pymysql/connections.py +++ /dev/null @@ -1,940 +0,0 @@ -# Python implementation of the MySQL client-server protocol -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -# http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol - -try: - import hashlib - sha_new = lambda *args, **kwargs: hashlib.new("sha1", *args, **kwargs) -except ImportError: - import sha - sha_new = sha.new - -import socket -try: - import ssl - SSL_ENABLED = True -except ImportError: - SSL_ENABLED = False - -import struct -import sys -import os -import ConfigParser - -try: - import cStringIO as StringIO -except ImportError: - import StringIO - -from charset import MBLENGTH, charset_by_name, charset_by_id -from cursors import Cursor -from constants import FIELD_TYPE, FLAG -from constants import SERVER_STATUS -from constants.CLIENT import * -from constants.COMMAND import * -from util import join_bytes, byte2int, int2byte -from converters import escape_item, encoders, decoders -from err import raise_mysql_exception, Warning, Error, \ - InterfaceError, DataError, DatabaseError, OperationalError, \ - IntegrityError, InternalError, NotSupportedError, ProgrammingError - -DEBUG = False - -NULL_COLUMN = 251 -UNSIGNED_CHAR_COLUMN = 251 -UNSIGNED_SHORT_COLUMN = 252 -UNSIGNED_INT24_COLUMN = 253 -UNSIGNED_INT64_COLUMN = 254 -UNSIGNED_CHAR_LENGTH = 1 -UNSIGNED_SHORT_LENGTH = 2 -UNSIGNED_INT24_LENGTH = 3 -UNSIGNED_INT64_LENGTH = 8 - -DEFAULT_CHARSET = 'latin1' - - -def dump_packet(data): - - def is_ascii(data): - if byte2int(data) >= 65 and byte2int(data) <= 122: #data.isalnum(): - return data - return '.' - print "packet length %d" % len(data) - print "method call[1]: %s" % sys._getframe(1).f_code.co_name - print "method call[2]: %s" % sys._getframe(2).f_code.co_name - print "method call[3]: %s" % sys._getframe(3).f_code.co_name - print "method call[4]: %s" % sys._getframe(4).f_code.co_name - print "method call[5]: %s" % sys._getframe(5).f_code.co_name - print "-" * 88 - dump_data = [data[i:i+16] for i in xrange(len(data)) if i%16 == 0] - for d in dump_data: - print ' '.join(map(lambda x:"%02X" % byte2int(x), d)) + \ - ' ' * (16 - len(d)) + ' ' * 2 + \ - ' '.join(map(lambda x:"%s" % is_ascii(x), d)) - print "-" * 88 - print "" - -def _scramble(password, message): - if password == None or len(password) == 0: - return int2byte(0) - if DEBUG: print 'password=' + password - stage1 = sha_new(password).digest() - stage2 = sha_new(stage1).digest() - s = sha_new() - s.update(message) - s.update(stage2) - result = s.digest() - return _my_crypt(result, stage1) - -def _my_crypt(message1, message2): - length = len(message1) - result = struct.pack('B', length) - for i in xrange(length): - x = (struct.unpack('B', message1[i:i+1])[0] ^ \ - struct.unpack('B', message2[i:i+1])[0]) - result += struct.pack('B', x) - return result - -# old_passwords support ported from libmysql/password.c -SCRAMBLE_LENGTH_323 = 8 - -class RandStruct_323(object): - def __init__(self, seed1, seed2): - self.max_value = 0x3FFFFFFFL - self.seed1 = seed1 % self.max_value - self.seed2 = seed2 % self.max_value - - def my_rnd(self): - self.seed1 = (self.seed1 * 3L + self.seed2) % self.max_value - self.seed2 = (self.seed1 + self.seed2 + 33L) % self.max_value - return float(self.seed1) / float(self.max_value) - -def _scramble_323(password, message): - hash_pass = _hash_password_323(password) - hash_message = _hash_password_323(message[:SCRAMBLE_LENGTH_323]) - hash_pass_n = struct.unpack(">LL", hash_pass) - hash_message_n = struct.unpack(">LL", hash_message) - - rand_st = RandStruct_323(hash_pass_n[0] ^ hash_message_n[0], - hash_pass_n[1] ^ hash_message_n[1]) - outbuf = StringIO.StringIO() - for _ in xrange(min(SCRAMBLE_LENGTH_323, len(message))): - outbuf.write(int2byte(int(rand_st.my_rnd() * 31) + 64)) - extra = int2byte(int(rand_st.my_rnd() * 31)) - out = outbuf.getvalue() - outbuf = StringIO.StringIO() - for c in out: - outbuf.write(int2byte(byte2int(c) ^ byte2int(extra))) - return outbuf.getvalue() - -def _hash_password_323(password): - nr = 1345345333L - add = 7L - nr2 = 0x12345671L - - for c in [byte2int(x) for x in password if x not in (' ', '\t')]: - nr^= (((nr & 63)+add)*c)+ (nr << 8) & 0xFFFFFFFF - nr2= (nr2 + ((nr2 << 8) ^ nr)) & 0xFFFFFFFF - add= (add + c) & 0xFFFFFFFF - - r1 = nr & ((1L << 31) - 1L) # kill sign bits - r2 = nr2 & ((1L << 31) - 1L) - - # pack - return struct.pack(">LL", r1, r2) - -def pack_int24(n): - return struct.pack('BBB', n&0xFF, (n>>8)&0xFF, (n>>16)&0xFF) - -def unpack_uint16(n): - return struct.unpack(' len(self.__data): - raise Exception('Invalid advance amount (%s) for cursor. ' - 'Position=%s' % (length, new_position)) - self.__position = new_position - - def rewind(self, position=0): - """Set the position of the data buffer cursor to 'position'.""" - if position < 0 or position > len(self.__data): - raise Exception("Invalid position to rewind cursor to: %s." % position) - self.__position = position - - def peek(self, size): - """Look at the first 'size' bytes in packet without moving cursor.""" - result = self.__data[self.__position:(self.__position+size)] - if len(result) != size: - error = ('Result length not requested length:\n' - 'Expected=%s. Actual=%s. Position: %s. Data Length: %s' - % (size, len(result), self.__position, len(self.__data))) - if DEBUG: - print error - self.dump() - raise AssertionError(error) - return result - - def get_bytes(self, position, length=1): - """Get 'length' bytes starting at 'position'. - - Position is start of payload (first four packet header bytes are not - included) starting at index '0'. - - No error checking is done. If requesting outside end of buffer - an empty string (or string shorter than 'length') may be returned! - """ - return self.__data[position:(position+length)] - - def read_length_coded_binary(self): - """Read a 'Length Coded Binary' number from the data buffer. - - Length coded numbers can be anywhere from 1 to 9 bytes depending - on the value of the first byte. - """ - c = byte2int(self.read(1)) - if c == NULL_COLUMN: - return None - if c < UNSIGNED_CHAR_COLUMN: - return c - elif c == UNSIGNED_SHORT_COLUMN: - return unpack_uint16(self.read(UNSIGNED_SHORT_LENGTH)) - elif c == UNSIGNED_INT24_COLUMN: - return unpack_int24(self.read(UNSIGNED_INT24_LENGTH)) - elif c == UNSIGNED_INT64_COLUMN: - # TODO: what was 'longlong'? confirm it wasn't used? - return unpack_int64(self.read(UNSIGNED_INT64_LENGTH)) - - def read_length_coded_string(self): - """Read a 'Length Coded String' from the data buffer. - - A 'Length Coded String' consists first of a length coded - (unsigned, positive) integer represented in 1-9 bytes followed by - that many bytes of binary data. (For example "cat" would be "3cat".) - """ - length = self.read_length_coded_binary() - if length is None: - return None - return self.read(length) - - def is_ok_packet(self): - return byte2int(self.get_bytes(0)) == 0 - - def is_eof_packet(self): - return byte2int(self.get_bytes(0)) == 254 # 'fe' - - def is_resultset_packet(self): - field_count = byte2int(self.get_bytes(0)) - return field_count >= 1 and field_count <= 250 - - def is_error_packet(self): - return byte2int(self.get_bytes(0)) == 255 - - def check_error(self): - if self.is_error_packet(): - self.rewind() - self.advance(1) # field_count == error (we already know that) - errno = unpack_uint16(self.read(2)) - if DEBUG: print "errno = %d" % errno - raise_mysql_exception(self.__data) - - def dump(self): - dump_packet(self.__data) - - -class FieldDescriptorPacket(MysqlPacket): - """A MysqlPacket that represents a specific column's metadata in the result. - - Parsing is automatically done and the results are exported via public - attributes on the class such as: db, table_name, name, length, type_code. - """ - - def __init__(self, *args): - MysqlPacket.__init__(self, *args) - self.__parse_field_descriptor() - - def __parse_field_descriptor(self): - """Parse the 'Field Descriptor' (Metadata) packet. - - This is compatible with MySQL 4.1+ (not compatible with MySQL 4.0). - """ - self.catalog = self.read_length_coded_string() - self.db = self.read_length_coded_string() - self.table_name = self.read_length_coded_string() - self.org_table = self.read_length_coded_string() - self.name = self.read_length_coded_string().decode(self.connection.charset) - self.org_name = self.read_length_coded_string() - self.advance(1) # non-null filler - self.charsetnr = struct.unpack(' 2: - use_unicode = True - - if compress or named_pipe: - raise NotImplementedError, "compress and named_pipe arguments are not supported" - - if ssl and (ssl.has_key('capath') or ssl.has_key('cipher')): - raise NotImplementedError, 'ssl options capath and cipher are not supported' - - self.ssl = False - if ssl: - if not SSL_ENABLED: - raise NotImplementedError, "ssl module not found" - self.ssl = True - client_flag |= SSL - for k in ('key', 'cert', 'ca'): - v = None - if ssl.has_key(k): - v = ssl[k] - setattr(self, k, v) - - if read_default_group and not read_default_file: - if sys.platform.startswith("win"): - read_default_file = "c:\\my.ini" - else: - read_default_file = "/etc/my.cnf" - - if read_default_file: - if not read_default_group: - read_default_group = "client" - - cfg = ConfigParser.RawConfigParser() - cfg.read(os.path.expanduser(read_default_file)) - - def _config(key, default): - try: - return cfg.get(read_default_group,key) - except: - return default - - user = _config("user",user) - passwd = _config("password",passwd) - host = _config("host", host) - db = _config("db",db) - unix_socket = _config("socket",unix_socket) - port = _config("port", port) - charset = _config("default-character-set", charset) - - self.host = host - self.port = port - self.user = user - self.password = passwd - self.db = db - self.unix_socket = unix_socket - if charset: - self.charset = charset - self.use_unicode = True - else: - self.charset = DEFAULT_CHARSET - self.use_unicode = False - - if use_unicode is not None: - self.use_unicode = use_unicode - - client_flag |= CAPABILITIES - client_flag |= MULTI_STATEMENTS - if self.db: - client_flag |= CONNECT_WITH_DB - self.client_flag = client_flag - - self.cursorclass = cursorclass - self.connect_timeout = connect_timeout - - self._connect() - - self.messages = [] - self.set_charset(charset) - self.encoders = encoders - self.decoders = conv - - self._result = None - self._affected_rows = 0 - self.host_info = "Not connected" - - self.autocommit(False) - - if sql_mode is not None: - c = self.cursor() - c.execute("SET sql_mode=%s", (sql_mode,)) - - self.commit() - - if init_command is not None: - c = self.cursor() - c.execute(init_command) - - self.commit() - - - def close(self): - ''' Send the quit message and close the socket ''' - if self.socket is None: - raise Error("Already closed") - send_data = struct.pack('= i + 1: - i += 1 - - self.server_capabilities = struct.unpack('= i+12-1: - rest_salt = data[i:i+12] - self.salt += rest_salt - - def get_server_info(self): - return self.server_version - - Warning = Warning - Error = Error - InterfaceError = InterfaceError - DatabaseError = DatabaseError - DataError = DataError - OperationalError = OperationalError - IntegrityError = IntegrityError - InternalError = InternalError - ProgrammingError = ProgrammingError - NotSupportedError = NotSupportedError - -# TODO: move OK and EOF packet parsing/logic into a proper subclass -# of MysqlPacket like has been done with FieldDescriptorPacket. -class MySQLResult(object): - - def __init__(self, connection): - from weakref import proxy - self.connection = proxy(connection) - self.affected_rows = None - self.insert_id = None - self.server_status = 0 - self.warning_count = 0 - self.message = None - self.field_count = 0 - self.description = None - self.rows = None - self.has_next = None - - def read(self): - self.first_packet = self.connection.read_packet() - - # TODO: use classes for different packet types? - if self.first_packet.is_ok_packet(): - self._read_ok_packet() - else: - self._read_result_packet() - - def _read_ok_packet(self): - self.first_packet.advance(1) # field_count (always '0') - self.affected_rows = self.first_packet.read_length_coded_binary() - self.insert_id = self.first_packet.read_length_coded_binary() - self.server_status = struct.unpack(' 2 - -try: - set -except NameError: - try: - from sets import BaseSet as set - except ImportError: - from sets import Set as set - -ESCAPE_REGEX = re.compile(r"[\0\n\r\032\'\"\\]") -ESCAPE_MAP = {'\0': '\\0', '\n': '\\n', '\r': '\\r', '\032': '\\Z', - '\'': '\\\'', '"': '\\"', '\\': '\\\\'} - -def escape_item(val, charset): - if type(val) in [tuple, list, set]: - return escape_sequence(val, charset) - if type(val) is dict: - return escape_dict(val, charset) - if PYTHON3 and hasattr(val, "decode") and not isinstance(val, unicode): - # deal with py3k bytes - val = val.decode(charset) - encoder = encoders[type(val)] - val = encoder(val) - if type(val) is str: - return val - val = val.encode(charset) - return val - -def escape_dict(val, charset): - n = {} - for k, v in val.items(): - quoted = escape_item(v, charset) - n[k] = quoted - return n - -def escape_sequence(val, charset): - n = [] - for item in val: - quoted = escape_item(item, charset) - n.append(quoted) - return "(" + ",".join(n) + ")" - -def escape_set(val, charset): - val = map(lambda x: escape_item(x, charset), val) - return ','.join(val) - -def escape_bool(value): - return str(int(value)) - -def escape_object(value): - return str(value) - -escape_int = escape_long = escape_object - -def escape_float(value): - return ('%.15g' % value) - -def escape_string(value): - return ("'%s'" % ESCAPE_REGEX.sub( - lambda match: ESCAPE_MAP.get(match.group(0)), value)) - -def escape_unicode(value): - return escape_string(value) - -def escape_None(value): - return 'NULL' - -def escape_timedelta(obj): - seconds = int(obj.seconds) % 60 - minutes = int(obj.seconds // 60) % 60 - hours = int(obj.seconds // 3600) % 24 + int(obj.days) * 24 - return escape_string('%02d:%02d:%02d' % (hours, minutes, seconds)) - -def escape_time(obj): - s = "%02d:%02d:%02d" % (int(obj.hour), int(obj.minute), - int(obj.second)) - if obj.microsecond: - s += ".%f" % obj.microsecond - - return escape_string(s) - -def escape_datetime(obj): - return escape_string(obj.strftime("%Y-%m-%d %H:%M:%S")) - -def escape_date(obj): - return escape_string(obj.strftime("%Y-%m-%d")) - -def escape_struct_time(obj): - return escape_datetime(datetime.datetime(*obj[:6])) - -def convert_datetime(connection, field, obj): - """Returns a DATETIME or TIMESTAMP column value as a datetime object: - - >>> datetime_or_None('2007-02-25 23:06:20') - datetime.datetime(2007, 2, 25, 23, 6, 20) - >>> datetime_or_None('2007-02-25T23:06:20') - datetime.datetime(2007, 2, 25, 23, 6, 20) - - Illegal values are returned as None: - - >>> datetime_or_None('2007-02-31T23:06:20') is None - True - >>> datetime_or_None('0000-00-00 00:00:00') is None - True - - """ - if not isinstance(obj, unicode): - obj = obj.decode(connection.charset) - if ' ' in obj: - sep = ' ' - elif 'T' in obj: - sep = 'T' - else: - return convert_date(connection, field, obj) - - try: - ymd, hms = obj.split(sep, 1) - return datetime.datetime(*[ int(x) for x in ymd.split('-')+hms.split(':') ]) - except ValueError: - return convert_date(connection, field, obj) - -def convert_timedelta(connection, field, obj): - """Returns a TIME column as a timedelta object: - - >>> timedelta_or_None('25:06:17') - datetime.timedelta(1, 3977) - >>> timedelta_or_None('-25:06:17') - datetime.timedelta(-2, 83177) - - Illegal values are returned as None: - - >>> timedelta_or_None('random crap') is None - True - - Note that MySQL always returns TIME columns as (+|-)HH:MM:SS, but - can accept values as (+|-)DD HH:MM:SS. The latter format will not - be parsed correctly by this function. - """ - from math import modf - try: - if not isinstance(obj, unicode): - obj = obj.decode(connection.charset) - hours, minutes, seconds = tuple([int(x) for x in obj.split(':')]) - tdelta = datetime.timedelta( - hours = int(hours), - minutes = int(minutes), - seconds = int(seconds), - microseconds = int(modf(float(seconds))[0]*1000000), - ) - return tdelta - except ValueError: - return None - -def convert_time(connection, field, obj): - """Returns a TIME column as a time object: - - >>> time_or_None('15:06:17') - datetime.time(15, 6, 17) - - Illegal values are returned as None: - - >>> time_or_None('-25:06:17') is None - True - >>> time_or_None('random crap') is None - True - - Note that MySQL always returns TIME columns as (+|-)HH:MM:SS, but - can accept values as (+|-)DD HH:MM:SS. The latter format will not - be parsed correctly by this function. - - Also note that MySQL's TIME column corresponds more closely to - Python's timedelta and not time. However if you want TIME columns - to be treated as time-of-day and not a time offset, then you can - use set this function as the converter for FIELD_TYPE.TIME. - """ - from math import modf - try: - hour, minute, second = obj.split(':') - return datetime.time(hour=int(hour), minute=int(minute), - second=int(second), - microsecond=int(modf(float(second))[0]*1000000)) - except ValueError: - return None - -def convert_date(connection, field, obj): - """Returns a DATE column as a date object: - - >>> date_or_None('2007-02-26') - datetime.date(2007, 2, 26) - - Illegal values are returned as None: - - >>> date_or_None('2007-02-31') is None - True - >>> date_or_None('0000-00-00') is None - True - - """ - try: - if not isinstance(obj, unicode): - obj = obj.decode(connection.charset) - return datetime.date(*[ int(x) for x in obj.split('-', 2) ]) - except ValueError: - return None - -def convert_mysql_timestamp(connection, field, timestamp): - """Convert a MySQL TIMESTAMP to a Timestamp object. - - MySQL >= 4.1 returns TIMESTAMP in the same format as DATETIME: - - >>> mysql_timestamp_converter('2007-02-25 22:32:17') - datetime.datetime(2007, 2, 25, 22, 32, 17) - - MySQL < 4.1 uses a big string of numbers: - - >>> mysql_timestamp_converter('20070225223217') - datetime.datetime(2007, 2, 25, 22, 32, 17) - - Illegal values are returned as None: - - >>> mysql_timestamp_converter('2007-02-31 22:32:17') is None - True - >>> mysql_timestamp_converter('00000000000000') is None - True - - """ - if not isinstance(timestamp, unicode): - timestamp = timestamp.decode(connection.charset) - - if timestamp[4] == '-': - return convert_datetime(connection, field, timestamp) - timestamp += "0"*(14-len(timestamp)) # padding - year, month, day, hour, minute, second = \ - int(timestamp[:4]), int(timestamp[4:6]), int(timestamp[6:8]), \ - int(timestamp[8:10]), int(timestamp[10:12]), int(timestamp[12:14]) - try: - return datetime.datetime(year, month, day, hour, minute, second) - except ValueError: - return None - -def convert_set(s): - return set(s.split(",")) - -def convert_bit(connection, field, b): - #b = "\x00" * (8 - len(b)) + b # pad w/ zeroes - #return struct.unpack(">Q", b)[0] - # - # the snippet above is right, but MySQLdb doesn't process bits, - # so we shouldn't either - return b - -def convert_characters(connection, field, data): - field_charset = charset_by_id(field.charsetnr).name - if field.flags & FLAG.SET: - return convert_set(data.decode(field_charset)) - if field.flags & FLAG.BINARY: - return data - - if connection.use_unicode: - data = data.decode(field_charset) - elif connection.charset != field_charset: - data = data.decode(field_charset) - data = data.encode(connection.charset) - return data - -def convert_int(connection, field, data): - return int(data) - -def convert_long(connection, field, data): - return long(data) - -def convert_float(connection, field, data): - return float(data) - -encoders = { - bool: escape_bool, - int: escape_int, - long: escape_long, - float: escape_float, - str: escape_string, - unicode: escape_unicode, - tuple: escape_sequence, - list:escape_sequence, - set:escape_sequence, - dict:escape_dict, - type(None):escape_None, - datetime.date: escape_date, - datetime.datetime : escape_datetime, - datetime.timedelta : escape_timedelta, - datetime.time : escape_time, - time.struct_time : escape_struct_time, - } - -decoders = { - FIELD_TYPE.BIT: convert_bit, - FIELD_TYPE.TINY: convert_int, - FIELD_TYPE.SHORT: convert_int, - FIELD_TYPE.LONG: convert_long, - FIELD_TYPE.FLOAT: convert_float, - FIELD_TYPE.DOUBLE: convert_float, - FIELD_TYPE.DECIMAL: convert_float, - FIELD_TYPE.NEWDECIMAL: convert_float, - FIELD_TYPE.LONGLONG: convert_long, - FIELD_TYPE.INT24: convert_int, - FIELD_TYPE.YEAR: convert_int, - FIELD_TYPE.TIMESTAMP: convert_mysql_timestamp, - FIELD_TYPE.DATETIME: convert_datetime, - FIELD_TYPE.TIME: convert_timedelta, - FIELD_TYPE.DATE: convert_date, - FIELD_TYPE.SET: convert_set, - FIELD_TYPE.BLOB: convert_characters, - FIELD_TYPE.TINY_BLOB: convert_characters, - FIELD_TYPE.MEDIUM_BLOB: convert_characters, - FIELD_TYPE.LONG_BLOB: convert_characters, - FIELD_TYPE.STRING: convert_characters, - FIELD_TYPE.VAR_STRING: convert_characters, - FIELD_TYPE.VARCHAR: convert_characters, - #FIELD_TYPE.BLOB: str, - #FIELD_TYPE.STRING: str, - #FIELD_TYPE.VAR_STRING: str, - #FIELD_TYPE.VARCHAR: str - } -conversions = decoders # for MySQLdb compatibility - -try: - # python version > 2.3 - from decimal import Decimal - def convert_decimal(connection, field, data): - data = data.decode(connection.charset) - return Decimal(data) - decoders[FIELD_TYPE.DECIMAL] = convert_decimal - decoders[FIELD_TYPE.NEWDECIMAL] = convert_decimal - - def escape_decimal(obj): - return unicode(obj) - encoders[Decimal] = escape_decimal - -except ImportError: - pass diff --git a/tools/testClient/pymysql/cursors.py b/tools/testClient/pymysql/cursors.py deleted file mode 100644 index 591f92b9c44..00000000000 --- a/tools/testClient/pymysql/cursors.py +++ /dev/null @@ -1,309 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import struct -import re - -try: - import cStringIO as StringIO -except ImportError: - import StringIO - -from err import Warning, Error, InterfaceError, DataError, \ - DatabaseError, OperationalError, IntegrityError, InternalError, \ - NotSupportedError, ProgrammingError - -insert_values = re.compile(r'\svalues\s*(\(.+\))', re.IGNORECASE) - -class Cursor(object): - ''' - This is the object you use to interact with the database. - ''' - def __init__(self, connection): - ''' - Do not create an instance of a Cursor yourself. Call - connections.Connection.cursor(). - ''' - from weakref import proxy - self.connection = proxy(connection) - self.description = None - self.rownumber = 0 - self.rowcount = -1 - self.arraysize = 1 - self._executed = None - self.messages = [] - self.errorhandler = connection.errorhandler - self._has_next = None - self._rows = () - - def __del__(self): - ''' - When this gets GC'd close it. - ''' - self.close() - - def close(self): - ''' - Closing a cursor just exhausts all remaining data. - ''' - if not self.connection: - return - try: - while self.nextset(): - pass - except: - pass - - self.connection = None - - def _get_db(self): - if not self.connection: - self.errorhandler(self, ProgrammingError, "cursor closed") - return self.connection - - def _check_executed(self): - if not self._executed: - self.errorhandler(self, ProgrammingError, "execute() first") - - def setinputsizes(self, *args): - """Does nothing, required by DB API.""" - - def setoutputsizes(self, *args): - """Does nothing, required by DB API.""" - - def nextset(self): - ''' Get the next query set ''' - if self._executed: - self.fetchall() - del self.messages[:] - - if not self._has_next: - return None - connection = self._get_db() - connection.next_result() - self._do_get_result() - return True - - def execute(self, query, args=None): - ''' Execute a query ''' - from sys import exc_info - - conn = self._get_db() - charset = conn.charset - del self.messages[:] - - # TODO: make sure that conn.escape is correct - - if args is not None: - if isinstance(args, tuple) or isinstance(args, list): - escaped_args = tuple(conn.escape(arg) for arg in args) - elif isinstance(args, dict): - escaped_args = dict((key, conn.escape(val)) for (key, val) in args.items()) - else: - #If it's not a dictionary let's try escaping it anyways. - #Worst case it will throw a Value error - escaped_args = conn.escape(args) - - query = query % escaped_args - - if isinstance(query, unicode): - query = query.encode(charset) - - result = 0 - try: - result = self._query(query) - except: - exc, value, tb = exc_info() - del tb - self.messages.append((exc,value)) - self.errorhandler(self, exc, value) - - self._executed = query - return result - - def executemany(self, query, args): - ''' Run several data against one query ''' - del self.messages[:] - #conn = self._get_db() - if not args: - return - #charset = conn.charset - #if isinstance(query, unicode): - # query = query.encode(charset) - - self.rowcount = sum([ self.execute(query, arg) for arg in args ]) - return self.rowcount - - - def callproc(self, procname, args=()): - """Execute stored procedure procname with args - - procname -- string, name of procedure to execute on server - - args -- Sequence of parameters to use with procedure - - Returns the original args. - - Compatibility warning: PEP-249 specifies that any modified - parameters must be returned. This is currently impossible - as they are only available by storing them in a server - variable and then retrieved by a query. Since stored - procedures return zero or more result sets, there is no - reliable way to get at OUT or INOUT parameters via callproc. - The server variables are named @_procname_n, where procname - is the parameter above and n is the position of the parameter - (from zero). Once all result sets generated by the procedure - have been fetched, you can issue a SELECT @_procname_0, ... - query using .execute() to get any OUT or INOUT values. - - Compatibility warning: The act of calling a stored procedure - itself creates an empty result set. This appears after any - result sets generated by the procedure. This is non-standard - behavior with respect to the DB-API. Be sure to use nextset() - to advance through all result sets; otherwise you may get - disconnected. - """ - conn = self._get_db() - for index, arg in enumerate(args): - q = "SET @_%s_%d=%s" % (procname, index, conn.escape(arg)) - if isinstance(q, unicode): - q = q.encode(conn.charset) - self._query(q) - self.nextset() - - q = "CALL %s(%s)" % (procname, - ','.join(['@_%s_%d' % (procname, i) - for i in range(len(args))])) - if isinstance(q, unicode): - q = q.encode(conn.charset) - self._query(q) - self._executed = q - - return args - - def fetchone(self): - ''' Fetch the next row ''' - self._check_executed() - if self._rows is None or self.rownumber >= len(self._rows): - return None - result = self._rows[self.rownumber] - self.rownumber += 1 - return result - - def fetchmany(self, size=None): - ''' Fetch several rows ''' - self._check_executed() - end = self.rownumber + (size or self.arraysize) - result = self._rows[self.rownumber:end] - if self._rows is None: - return None - self.rownumber = min(end, len(self._rows)) - return result - - def fetchall(self): - ''' Fetch all the rows ''' - self._check_executed() - if self._rows is None: - return None - if self.rownumber: - result = self._rows[self.rownumber:] - else: - result = self._rows - self.rownumber = len(self._rows) - return result - - def scroll(self, value, mode='relative'): - self._check_executed() - if mode == 'relative': - r = self.rownumber + value - elif mode == 'absolute': - r = value - else: - self.errorhandler(self, ProgrammingError, - "unknown scroll mode %s" % mode) - - if r < 0 or r >= len(self._rows): - self.errorhandler(self, IndexError, "out of range") - self.rownumber = r - - def _query(self, q): - conn = self._get_db() - self._last_executed = q - conn.query(q) - self._do_get_result() - return self.rowcount - - def _do_get_result(self): - conn = self._get_db() - self.rowcount = conn._result.affected_rows - - self.rownumber = 0 - self.description = conn._result.description - self.lastrowid = conn._result.insert_id - self._rows = conn._result.rows - self._has_next = conn._result.has_next - - def __iter__(self): - return iter(self.fetchone, None) - - Warning = Warning - Error = Error - InterfaceError = InterfaceError - DatabaseError = DatabaseError - DataError = DataError - OperationalError = OperationalError - IntegrityError = IntegrityError - InternalError = InternalError - ProgrammingError = ProgrammingError - NotSupportedError = NotSupportedError - -class DictCursor(Cursor): - """A cursor which returns results as a dictionary""" - - def execute(self, query, args=None): - result = super(DictCursor, self).execute(query, args) - if self.description: - self._fields = [ field[0] for field in self.description ] - return result - - def fetchone(self): - ''' Fetch the next row ''' - self._check_executed() - if self._rows is None or self.rownumber >= len(self._rows): - return None - result = dict(zip(self._fields, self._rows[self.rownumber])) - self.rownumber += 1 - return result - - def fetchmany(self, size=None): - ''' Fetch several rows ''' - self._check_executed() - if self._rows is None: - return None - end = self.rownumber + (size or self.arraysize) - result = [ dict(zip(self._fields, r)) for r in self._rows[self.rownumber:end] ] - self.rownumber = min(end, len(self._rows)) - return tuple(result) - - def fetchall(self): - ''' Fetch all the rows ''' - self._check_executed() - if self._rows is None: - return None - if self.rownumber: - result = [ dict(zip(self._fields, r)) for r in self._rows[self.rownumber:] ] - else: - result = [ dict(zip(self._fields, r)) for r in self._rows ] - self.rownumber = len(self._rows) - return tuple(result) - diff --git a/tools/testClient/pymysql/err.py b/tools/testClient/pymysql/err.py deleted file mode 100644 index df666a9e9fa..00000000000 --- a/tools/testClient/pymysql/err.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import struct - - -try: - StandardError, Warning -except ImportError: - try: - from exceptions import StandardError, Warning - except ImportError: - import sys - e = sys.modules['exceptions'] - StandardError = e.StandardError - Warning = e.Warning - -from constants import ER -import sys - -class MySQLError(StandardError): - - """Exception related to operation with MySQL.""" - - -class Warning(Warning, MySQLError): - - """Exception raised for important warnings like data truncations - while inserting, etc.""" - -class Error(MySQLError): - - """Exception that is the base class of all other error exceptions - (not Warning).""" - - -class InterfaceError(Error): - - """Exception raised for errors that are related to the database - interface rather than the database itself.""" - - -class DatabaseError(Error): - - """Exception raised for errors that are related to the - database.""" - - -class DataError(DatabaseError): - - """Exception raised for errors that are due to problems with the - processed data like division by zero, numeric value out of range, - etc.""" - - -class OperationalError(DatabaseError): - - """Exception raised for errors that are related to the database's - operation and not necessarily under the control of the programmer, - e.g. an unexpected disconnect occurs, the data source name is not - found, a transaction could not be processed, a memory allocation - error occurred during processing, etc.""" - - -class IntegrityError(DatabaseError): - - """Exception raised when the relational integrity of the database - is affected, e.g. a foreign key check fails, duplicate key, - etc.""" - - -class InternalError(DatabaseError): - - """Exception raised when the database encounters an internal - error, e.g. the cursor is not valid anymore, the transaction is - out of sync, etc.""" - - -class ProgrammingError(DatabaseError): - - """Exception raised for programming errors, e.g. table not found - or already exists, syntax error in the SQL statement, wrong number - of parameters specified, etc.""" - - -class NotSupportedError(DatabaseError): - - """Exception raised in case a method or database API was used - which is not supported by the database, e.g. requesting a - .rollback() on a connection that does not support transaction or - has transactions turned off.""" - - -error_map = {} - -def _map_error(exc, *errors): - for error in errors: - error_map[error] = exc - -_map_error(ProgrammingError, ER.DB_CREATE_EXISTS, ER.SYNTAX_ERROR, - ER.PARSE_ERROR, ER.NO_SUCH_TABLE, ER.WRONG_DB_NAME, - ER.WRONG_TABLE_NAME, ER.FIELD_SPECIFIED_TWICE, - ER.INVALID_GROUP_FUNC_USE, ER.UNSUPPORTED_EXTENSION, - ER.TABLE_MUST_HAVE_COLUMNS, ER.CANT_DO_THIS_DURING_AN_TRANSACTION) -_map_error(DataError, ER.WARN_DATA_TRUNCATED, ER.WARN_NULL_TO_NOTNULL, - ER.WARN_DATA_OUT_OF_RANGE, ER.NO_DEFAULT, ER.PRIMARY_CANT_HAVE_NULL, - ER.DATA_TOO_LONG, ER.DATETIME_FUNCTION_OVERFLOW) -_map_error(IntegrityError, ER.DUP_ENTRY, ER.NO_REFERENCED_ROW, - ER.NO_REFERENCED_ROW_2, ER.ROW_IS_REFERENCED, ER.ROW_IS_REFERENCED_2, - ER.CANNOT_ADD_FOREIGN) -_map_error(NotSupportedError, ER.WARNING_NOT_COMPLETE_ROLLBACK, - ER.NOT_SUPPORTED_YET, ER.FEATURE_DISABLED, ER.UNKNOWN_STORAGE_ENGINE) -_map_error(OperationalError, ER.DBACCESS_DENIED_ERROR, ER.ACCESS_DENIED_ERROR, - ER.TABLEACCESS_DENIED_ERROR, ER.COLUMNACCESS_DENIED_ERROR) - -del _map_error, ER - - -def _get_error_info(data): - errno = struct.unpack(' tuple) - c.execute("SELECT * from dictcursor where name='bob'") - r = c.fetchall() - self.assertEqual((bob,),r,"fetch a 1 row result via fetchall failed via DictCursor") - # same test again but iterate over the - c.execute("SELECT * from dictcursor where name='bob'") - for r in c: - self.assertEqual(bob, r,"fetch a 1 row result via iteration failed via DictCursor") - # get all 3 row via fetchall - c.execute("SELECT * from dictcursor") - r = c.fetchall() - self.assertEqual((bob,jim,fred), r, "fetchall failed via DictCursor") - #same test again but do a list comprehension - c.execute("SELECT * from dictcursor") - r = [x for x in c] - self.assertEqual([bob,jim,fred], r, "list comprehension failed via DictCursor") - # get all 2 row via fetchmany - c.execute("SELECT * from dictcursor") - r = c.fetchmany(2) - self.assertEqual((bob,jim), r, "fetchmany failed via DictCursor") - finally: - c.execute("drop table dictcursor") - -__all__ = ["TestDictCursor"] - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/test_basic.py b/tools/testClient/pymysql/tests/test_basic.py deleted file mode 100644 index 79908b219a3..00000000000 --- a/tools/testClient/pymysql/tests/test_basic.py +++ /dev/null @@ -1,205 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from pymysql.tests import base -from pymysql import util - -import time -import datetime - -class TestConversion(base.PyMySQLTestCase): - def test_datatypes(self): - """ test every data type """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_datatypes (b bit, i int, l bigint, f real, s varchar(32), u varchar(32), bb blob, d date, dt datetime, ts timestamp, td time, t time, st datetime)") - try: - # insert values - v = (True, -3, 123456789012, 5.7, "hello'\" world", u"Espa\xc3\xb1ol", "binary\x00data".encode(conn.charset), datetime.date(1988,2,2), datetime.datetime.now(), datetime.timedelta(5,6), datetime.time(16,32), time.localtime()) - c.execute("insert into test_datatypes (b,i,l,f,s,u,bb,d,dt,td,t,st) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", v) - c.execute("select b,i,l,f,s,u,bb,d,dt,td,t,st from test_datatypes") - r = c.fetchone() - self.assertEqual(util.int2byte(1), r[0]) - self.assertEqual(v[1:8], r[1:8]) - # mysql throws away microseconds so we need to check datetimes - # specially. additionally times are turned into timedeltas. - self.assertEqual(datetime.datetime(*v[8].timetuple()[:6]), r[8]) - self.assertEqual(v[9], r[9]) # just timedeltas - self.assertEqual(datetime.timedelta(0, 60 * (v[10].hour * 60 + v[10].minute)), r[10]) - self.assertEqual(datetime.datetime(*v[-1][:6]), r[-1]) - - c.execute("delete from test_datatypes") - - # check nulls - c.execute("insert into test_datatypes (b,i,l,f,s,u,bb,d,dt,td,t,st) values (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", [None] * 12) - c.execute("select b,i,l,f,s,u,bb,d,dt,td,t,st from test_datatypes") - r = c.fetchone() - self.assertEqual(tuple([None] * 12), r) - - c.execute("delete from test_datatypes") - - # check sequence type - c.execute("insert into test_datatypes (i, l) values (2,4), (6,8), (10,12)") - c.execute("select l from test_datatypes where i in %s order by i", ((2,6),)) - r = c.fetchall() - self.assertEqual(((4,),(8,)), r) - finally: - c.execute("drop table test_datatypes") - - def test_dict(self): - """ test dict escaping """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_dict (a integer, b integer, c integer)") - try: - c.execute("insert into test_dict (a,b,c) values (%(a)s, %(b)s, %(c)s)", {"a":1,"b":2,"c":3}) - c.execute("select a,b,c from test_dict") - self.assertEqual((1,2,3), c.fetchone()) - finally: - c.execute("drop table test_dict") - - def test_string(self): - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_dict (a text)") - test_value = "I am a test string" - try: - c.execute("insert into test_dict (a) values (%s)", test_value) - c.execute("select a from test_dict") - self.assertEqual((test_value,), c.fetchone()) - finally: - c.execute("drop table test_dict") - - def test_integer(self): - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_dict (a integer)") - test_value = 12345 - try: - c.execute("insert into test_dict (a) values (%s)", test_value) - c.execute("select a from test_dict") - self.assertEqual((test_value,), c.fetchone()) - finally: - c.execute("drop table test_dict") - - - def test_big_blob(self): - """ test tons of data """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_big_blob (b blob)") - try: - data = "pymysql" * 1024 - c.execute("insert into test_big_blob (b) values (%s)", (data,)) - c.execute("select b from test_big_blob") - self.assertEqual(data.encode(conn.charset), c.fetchone()[0]) - finally: - c.execute("drop table test_big_blob") - -class TestCursor(base.PyMySQLTestCase): - # this test case does not work quite right yet, however, - # we substitute in None for the erroneous field which is - # compatible with the DB-API 2.0 spec and has not broken - # any unit tests for anything we've tried. - - #def test_description(self): - # """ test description attribute """ - # # result is from MySQLdb module - # r = (('Host', 254, 11, 60, 60, 0, 0), - # ('User', 254, 16, 16, 16, 0, 0), - # ('Password', 254, 41, 41, 41, 0, 0), - # ('Select_priv', 254, 1, 1, 1, 0, 0), - # ('Insert_priv', 254, 1, 1, 1, 0, 0), - # ('Update_priv', 254, 1, 1, 1, 0, 0), - # ('Delete_priv', 254, 1, 1, 1, 0, 0), - # ('Create_priv', 254, 1, 1, 1, 0, 0), - # ('Drop_priv', 254, 1, 1, 1, 0, 0), - # ('Reload_priv', 254, 1, 1, 1, 0, 0), - # ('Shutdown_priv', 254, 1, 1, 1, 0, 0), - # ('Process_priv', 254, 1, 1, 1, 0, 0), - # ('File_priv', 254, 1, 1, 1, 0, 0), - # ('Grant_priv', 254, 1, 1, 1, 0, 0), - # ('References_priv', 254, 1, 1, 1, 0, 0), - # ('Index_priv', 254, 1, 1, 1, 0, 0), - # ('Alter_priv', 254, 1, 1, 1, 0, 0), - # ('Show_db_priv', 254, 1, 1, 1, 0, 0), - # ('Super_priv', 254, 1, 1, 1, 0, 0), - # ('Create_tmp_table_priv', 254, 1, 1, 1, 0, 0), - # ('Lock_tables_priv', 254, 1, 1, 1, 0, 0), - # ('Execute_priv', 254, 1, 1, 1, 0, 0), - # ('Repl_slave_priv', 254, 1, 1, 1, 0, 0), - # ('Repl_client_priv', 254, 1, 1, 1, 0, 0), - # ('Create_view_priv', 254, 1, 1, 1, 0, 0), - # ('Show_view_priv', 254, 1, 1, 1, 0, 0), - # ('Create_routine_priv', 254, 1, 1, 1, 0, 0), - # ('Alter_routine_priv', 254, 1, 1, 1, 0, 0), - # ('Create_user_priv', 254, 1, 1, 1, 0, 0), - # ('Event_priv', 254, 1, 1, 1, 0, 0), - # ('Trigger_priv', 254, 1, 1, 1, 0, 0), - # ('ssl_type', 254, 0, 9, 9, 0, 0), - # ('ssl_cipher', 252, 0, 65535, 65535, 0, 0), - # ('x509_issuer', 252, 0, 65535, 65535, 0, 0), - # ('x509_subject', 252, 0, 65535, 65535, 0, 0), - # ('max_questions', 3, 1, 11, 11, 0, 0), - # ('max_updates', 3, 1, 11, 11, 0, 0), - # ('max_connections', 3, 1, 11, 11, 0, 0), - # ('max_user_connections', 3, 1, 11, 11, 0, 0)) - # conn = self.connections[0] - # c = conn.cursor() - # c.execute("select * from mysql.user") - # - # self.assertEqual(r, c.description) - - def test_fetch_no_result(self): - """ test a fetchone() with no rows """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table test_nr (b varchar(32))") - try: - data = "pymysql" - c.execute("insert into test_nr (b) values (%s)", (data,)) - self.assertEqual(None, c.fetchone()) - finally: - c.execute("drop table test_nr") - - def test_aggregates(self): - """ test aggregate functions """ - conn = self.connections[0] - c = conn.cursor() - try: - c.execute('create table test_aggregates (i integer)') - for i in xrange(0, 10): - c.execute('insert into test_aggregates (i) values (%s)', (i,)) - c.execute('select sum(i) from test_aggregates') - r, = c.fetchone() - self.assertEqual(sum(range(0,10)), r) - finally: - c.execute('drop table test_aggregates') - - def test_single_tuple(self): - """ test a single tuple """ - conn = self.connections[0] - c = conn.cursor() - try: - c.execute("create table mystuff (id integer primary key)") - c.execute("insert into mystuff (id) values (1)") - c.execute("insert into mystuff (id) values (2)") - c.execute("select id from mystuff where id in %s", ((1,),)) - self.assertEqual([(1,)], list(c.fetchall())) - finally: - c.execute("drop table mystuff") - -__all__ = ["TestConversion","TestCursor"] - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/test_example.py b/tools/testClient/pymysql/tests/test_example.py deleted file mode 100644 index 0929f2665c6..00000000000 --- a/tools/testClient/pymysql/tests/test_example.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import pymysql -from pymysql.tests import base - -class TestExample(base.PyMySQLTestCase): - def test_example(self): - conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='mysql') - - - cur = conn.cursor() - - cur.execute("SELECT Host,User FROM user") - - # print cur.description - - # r = cur.fetchall() - # print r - # ...or... - u = False - - for r in cur.fetchall(): - u = u or conn.user in r - - self.assertTrue(u) - - cur.close() - conn.close() - -__all__ = ["TestExample"] - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/test_issues.py b/tools/testClient/pymysql/tests/test_issues.py deleted file mode 100644 index 57026978599..00000000000 --- a/tools/testClient/pymysql/tests/test_issues.py +++ /dev/null @@ -1,280 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import pymysql -from pymysql.tests import base - -import sys - -try: - import imp - reload = imp.reload -except AttributeError: - pass - -import datetime - -class TestOldIssues(base.PyMySQLTestCase): - def test_issue_3(self): - """ undefined methods datetime_or_None, date_or_None """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table issue3 (d date, t time, dt datetime, ts timestamp)") - try: - c.execute("insert into issue3 (d, t, dt, ts) values (%s,%s,%s,%s)", (None, None, None, None)) - c.execute("select d from issue3") - self.assertEqual(None, c.fetchone()[0]) - c.execute("select t from issue3") - self.assertEqual(None, c.fetchone()[0]) - c.execute("select dt from issue3") - self.assertEqual(None, c.fetchone()[0]) - c.execute("select ts from issue3") - self.assertTrue(isinstance(c.fetchone()[0], datetime.datetime)) - finally: - c.execute("drop table issue3") - - def test_issue_4(self): - """ can't retrieve TIMESTAMP fields """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table issue4 (ts timestamp)") - try: - c.execute("insert into issue4 (ts) values (now())") - c.execute("select ts from issue4") - self.assertTrue(isinstance(c.fetchone()[0], datetime.datetime)) - finally: - c.execute("drop table issue4") - - def test_issue_5(self): - """ query on information_schema.tables fails """ - con = self.connections[0] - cur = con.cursor() - cur.execute("select * from information_schema.tables") - - def test_issue_6(self): - """ exception: TypeError: ord() expected a character, but string of length 0 found """ - conn = pymysql.connect(host="localhost",user="root",passwd="",db="mysql") - c = conn.cursor() - c.execute("select * from user") - conn.close() - - def test_issue_8(self): - """ Primary Key and Index error when selecting data """ - conn = self.connections[0] - c = conn.cursor() - c.execute("""CREATE TABLE `test` (`station` int(10) NOT NULL DEFAULT '0', `dh` -datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `echeance` int(1) NOT NULL -DEFAULT '0', `me` double DEFAULT NULL, `mo` double DEFAULT NULL, PRIMARY -KEY (`station`,`dh`,`echeance`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;""") - try: - self.assertEqual(0, c.execute("SELECT * FROM test")) - c.execute("ALTER TABLE `test` ADD INDEX `idx_station` (`station`)") - self.assertEqual(0, c.execute("SELECT * FROM test")) - finally: - c.execute("drop table test") - - def test_issue_9(self): - """ sets DeprecationWarning in Python 2.6 """ - try: - reload(pymysql) - except DeprecationWarning: - self.fail() - - def test_issue_10(self): - """ Allocate a variable to return when the exception handler is permissive """ - conn = self.connections[0] - conn.errorhandler = lambda cursor, errorclass, errorvalue: None - cur = conn.cursor() - cur.execute( "create table t( n int )" ) - cur.execute( "create table t( n int )" ) - - def test_issue_13(self): - """ can't handle large result fields """ - conn = self.connections[0] - cur = conn.cursor() - try: - cur.execute("create table issue13 (t text)") - # ticket says 18k - size = 18*1024 - cur.execute("insert into issue13 (t) values (%s)", ("x" * size,)) - cur.execute("select t from issue13") - # use assert_ so that obscenely huge error messages don't print - r = cur.fetchone()[0] - self.assert_("x" * size == r) - finally: - cur.execute("drop table issue13") - - def test_issue_14(self): - """ typo in converters.py """ - self.assertEqual('1', pymysql.converters.escape_item(1, "utf8")) - self.assertEqual('1', pymysql.converters.escape_item(1L, "utf8")) - - self.assertEqual('1', pymysql.converters.escape_object(1)) - self.assertEqual('1', pymysql.converters.escape_object(1L)) - - def test_issue_15(self): - """ query should be expanded before perform character encoding """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table issue15 (t varchar(32))") - try: - c.execute("insert into issue15 (t) values (%s)", (u'\xe4\xf6\xfc',)) - c.execute("select t from issue15") - self.assertEqual(u'\xe4\xf6\xfc', c.fetchone()[0]) - finally: - c.execute("drop table issue15") - - def test_issue_16(self): - """ Patch for string and tuple escaping """ - conn = self.connections[0] - c = conn.cursor() - c.execute("create table issue16 (name varchar(32) primary key, email varchar(32))") - try: - c.execute("insert into issue16 (name, email) values ('pete', 'floydophone')") - c.execute("select email from issue16 where name=%s", ("pete",)) - self.assertEqual("floydophone", c.fetchone()[0]) - finally: - c.execute("drop table issue16") - - def test_issue_17(self): - """ could not connect mysql use passwod """ - conn = self.connections[0] - host = self.databases[0]["host"] - db = self.databases[0]["db"] - c = conn.cursor() - # grant access to a table to a user with a password - try: - c.execute("create table issue17 (x varchar(32) primary key)") - c.execute("insert into issue17 (x) values ('hello, world!')") - c.execute("grant all privileges on %s.issue17 to 'issue17user'@'%%' identified by '1234'" % db) - conn.commit() - - conn2 = pymysql.connect(host=host, user="issue17user", passwd="1234", db=db) - c2 = conn2.cursor() - c2.execute("select x from issue17") - self.assertEqual("hello, world!", c2.fetchone()[0]) - finally: - c.execute("drop table issue17") - -def _uni(s, e): - # hack for py3 - if sys.version_info[0] > 2: - return unicode(bytes(s, sys.getdefaultencoding()), e) - else: - return unicode(s, e) - -class TestNewIssues(base.PyMySQLTestCase): - def test_issue_34(self): - try: - pymysql.connect(host="localhost", port=1237, user="root") - self.fail() - except pymysql.OperationalError, e: - self.assertEqual(2003, e.args[0]) - except: - self.fail() - - def test_issue_33(self): - conn = pymysql.connect(host="localhost", user="root", db=self.databases[0]["db"], charset="utf8") - c = conn.cursor() - try: - c.execute(_uni("create table hei\xc3\x9fe (name varchar(32))", "utf8")) - c.execute(_uni("insert into hei\xc3\x9fe (name) values ('Pi\xc3\xb1ata')", "utf8")) - c.execute(_uni("select name from hei\xc3\x9fe", "utf8")) - self.assertEqual(_uni("Pi\xc3\xb1ata","utf8"), c.fetchone()[0]) - finally: - c.execute(_uni("drop table hei\xc3\x9fe", "utf8")) - - # Will fail without manual intervention: - #def test_issue_35(self): - # - # conn = self.connections[0] - # c = conn.cursor() - # print "sudo killall -9 mysqld within the next 10 seconds" - # try: - # c.execute("select sleep(10)") - # self.fail() - # except pymysql.OperationalError, e: - # self.assertEqual(2013, e.args[0]) - - def test_issue_36(self): - conn = self.connections[0] - c = conn.cursor() - # kill connections[0] - original_count = c.execute("show processlist") - kill_id = None - for id,user,host,db,command,time,state,info in c.fetchall(): - if info == "show processlist": - kill_id = id - break - # now nuke the connection - conn.kill(kill_id) - # make sure this connection has broken - try: - c.execute("show tables") - self.fail() - except: - pass - # check the process list from the other connection - self.assertEqual(original_count - 1, self.connections[1].cursor().execute("show processlist")) - del self.connections[0] - - def test_issue_37(self): - conn = self.connections[0] - c = conn.cursor() - self.assertEqual(1, c.execute("SELECT @foo")) - self.assertEqual((None,), c.fetchone()) - self.assertEqual(0, c.execute("SET @foo = 'bar'")) - c.execute("set @foo = 'bar'") - - def test_issue_38(self): - conn = self.connections[0] - c = conn.cursor() - datum = "a" * 1024 * 1023 # reduced size for most default mysql installs - - try: - c.execute("create table issue38 (id integer, data mediumblob)") - c.execute("insert into issue38 values (1, %s)", (datum,)) - finally: - c.execute("drop table issue38") - - def disabled_test_issue_54(self): - conn = self.connections[0] - c = conn.cursor() - big_sql = "select * from issue54 where " - big_sql += " and ".join("%d=%d" % (i,i) for i in xrange(0, 100000)) - - try: - c.execute("create table issue54 (id integer primary key)") - c.execute("insert into issue54 (id) values (7)") - c.execute(big_sql) - self.assertEquals(7, c.fetchone()[0]) - finally: - c.execute("drop table issue54") - -class TestGitHubIssues(base.PyMySQLTestCase): - def test_issue_66(self): - conn = self.connections[0] - c = conn.cursor() - self.assertEquals(0, conn.insert_id()) - try: - c.execute("create table issue66 (id integer primary key auto_increment, x integer)") - c.execute("insert into issue66 (x) values (1)") - c.execute("insert into issue66 (x) values (1)") - self.assertEquals(2, conn.insert_id()) - finally: - c.execute("drop table issue66") - -__all__ = ["TestOldIssues", "TestNewIssues", "TestGitHubIssues"] - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/thirdparty/__init__.py b/tools/testClient/pymysql/tests/thirdparty/__init__.py deleted file mode 100644 index 7f108fa3c82..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from test_MySQLdb import * - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/__init__.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/__init__.py deleted file mode 100644 index 18c638c5d12..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from test_MySQLdb_capabilities import test_MySQLdb as test_capabilities -from test_MySQLdb_nonstandard import * -from test_MySQLdb_dbapi20 import test_MySQLdb as test_dbapi2 - -if __name__ == "__main__": - import unittest - unittest.main() diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/capabilities.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/capabilities.py deleted file mode 100644 index 5f1ae84880e..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/capabilities.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python -O -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" Script to test database capabilities and the DB-API interface - for functionality and memory leaks. - - Adapted from a script by M-A Lemburg. - -""" -from time import time -import array -import unittest - - -class DatabaseTest(unittest.TestCase): - - db_module = None - connect_args = () - connect_kwargs = dict(use_unicode=True, charset="utf8") - create_table_extra = "ENGINE=INNODB CHARACTER SET UTF8" - rows = 10 - debug = False - - def setUp(self): - import gc - db = self.db_module.connect(*self.connect_args, **self.connect_kwargs) - self.connection = db - self.cursor = db.cursor() - self.BLOBText = ''.join([chr(i) for i in range(256)] * 100); - self.BLOBUText = u''.join([unichr(i) for i in range(16834)]) - self.BLOBBinary = self.db_module.Binary(''.join([chr(i) for i in range(256)] * 16)) - - leak_test = True - - def tearDown(self): - if self.leak_test: - import gc - del self.cursor - orphans = gc.collect() - self.assertFalse(orphans, "%d orphaned objects found after deleting cursor" % orphans) - - del self.connection - orphans = gc.collect() - self.assertFalse(orphans, "%d orphaned objects found after deleting connection" % orphans) - - def table_exists(self, name): - try: - self.cursor.execute('select * from %s where 1=0' % name) - except: - return False - else: - return True - - def quote_identifier(self, ident): - return '"%s"' % ident - - def new_table_name(self): - i = id(self.cursor) - while True: - name = self.quote_identifier('tb%08x' % i) - if not self.table_exists(name): - return name - i = i + 1 - - def create_table(self, columndefs): - - """ Create a table using a list of column definitions given in - columndefs. - - generator must be a function taking arguments (row_number, - col_number) returning a suitable data object for insertion - into the table. - - """ - self.table = self.new_table_name() - self.cursor.execute('CREATE TABLE %s (%s) %s' % - (self.table, - ',\n'.join(columndefs), - self.create_table_extra)) - - def check_data_integrity(self, columndefs, generator): - # insert - self.create_table(columndefs) - insert_statement = ('INSERT INTO %s VALUES (%s)' % - (self.table, - ','.join(['%s'] * len(columndefs)))) - data = [ [ generator(i,j) for j in range(len(columndefs)) ] - for i in range(self.rows) ] - if self.debug: - print data - self.cursor.executemany(insert_statement, data) - self.connection.commit() - # verify - self.cursor.execute('select * from %s' % self.table) - l = self.cursor.fetchall() - if self.debug: - print l - self.assertEquals(len(l), self.rows) - try: - for i in range(self.rows): - for j in range(len(columndefs)): - self.assertEquals(l[i][j], generator(i,j)) - finally: - if not self.debug: - self.cursor.execute('drop table %s' % (self.table)) - - def test_transactions(self): - columndefs = ( 'col1 INT', 'col2 VARCHAR(255)') - def generator(row, col): - if col == 0: return row - else: return ('%i' % (row%10))*255 - self.create_table(columndefs) - insert_statement = ('INSERT INTO %s VALUES (%s)' % - (self.table, - ','.join(['%s'] * len(columndefs)))) - data = [ [ generator(i,j) for j in range(len(columndefs)) ] - for i in range(self.rows) ] - self.cursor.executemany(insert_statement, data) - # verify - self.connection.commit() - self.cursor.execute('select * from %s' % self.table) - l = self.cursor.fetchall() - self.assertEquals(len(l), self.rows) - for i in range(self.rows): - for j in range(len(columndefs)): - self.assertEquals(l[i][j], generator(i,j)) - delete_statement = 'delete from %s where col1=%%s' % self.table - self.cursor.execute(delete_statement, (0,)) - self.cursor.execute('select col1 from %s where col1=%s' % \ - (self.table, 0)) - l = self.cursor.fetchall() - self.assertFalse(l, "DELETE didn't work") - self.connection.rollback() - self.cursor.execute('select col1 from %s where col1=%s' % \ - (self.table, 0)) - l = self.cursor.fetchall() - self.assertTrue(len(l) == 1, "ROLLBACK didn't work") - self.cursor.execute('drop table %s' % (self.table)) - - def test_truncation(self): - columndefs = ( 'col1 INT', 'col2 VARCHAR(255)') - def generator(row, col): - if col == 0: return row - else: return ('%i' % (row%10))*((255-self.rows/2)+row) - self.create_table(columndefs) - insert_statement = ('INSERT INTO %s VALUES (%s)' % - (self.table, - ','.join(['%s'] * len(columndefs)))) - - try: - self.cursor.execute(insert_statement, (0, '0'*256)) - except Warning: - if self.debug: print self.cursor.messages - except self.connection.DataError: - pass - else: - self.fail("Over-long column did not generate warnings/exception with single insert") - - self.connection.rollback() - - try: - for i in range(self.rows): - data = [] - for j in range(len(columndefs)): - data.append(generator(i,j)) - self.cursor.execute(insert_statement,tuple(data)) - except Warning: - if self.debug: print self.cursor.messages - except self.connection.DataError: - pass - else: - self.fail("Over-long columns did not generate warnings/exception with execute()") - - self.connection.rollback() - - try: - data = [ [ generator(i,j) for j in range(len(columndefs)) ] - for i in range(self.rows) ] - self.cursor.executemany(insert_statement, data) - except Warning: - if self.debug: print self.cursor.messages - except self.connection.DataError: - pass - else: - self.fail("Over-long columns did not generate warnings/exception with executemany()") - - self.connection.rollback() - self.cursor.execute('drop table %s' % (self.table)) - - def test_CHAR(self): - # Character data - def generator(row,col): - return ('%i' % ((row+col) % 10)) * 255 - self.check_data_integrity( - ('col1 char(255)','col2 char(255)'), - generator) - - def test_INT(self): - # Number data - def generator(row,col): - return row*row - self.check_data_integrity( - ('col1 INT',), - generator) - - def test_DECIMAL(self): - # DECIMAL - def generator(row,col): - from decimal import Decimal - return Decimal("%d.%02d" % (row, col)) - self.check_data_integrity( - ('col1 DECIMAL(5,2)',), - generator) - - def test_DATE(self): - ticks = time() - def generator(row,col): - return self.db_module.DateFromTicks(ticks+row*86400-col*1313) - self.check_data_integrity( - ('col1 DATE',), - generator) - - def test_TIME(self): - ticks = time() - def generator(row,col): - return self.db_module.TimeFromTicks(ticks+row*86400-col*1313) - self.check_data_integrity( - ('col1 TIME',), - generator) - - def test_DATETIME(self): - ticks = time() - def generator(row,col): - return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313) - self.check_data_integrity( - ('col1 DATETIME',), - generator) - - def test_TIMESTAMP(self): - ticks = time() - def generator(row,col): - return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313) - self.check_data_integrity( - ('col1 TIMESTAMP',), - generator) - - def test_fractional_TIMESTAMP(self): - ticks = time() - def generator(row,col): - return self.db_module.TimestampFromTicks(ticks+row*86400-col*1313+row*0.7*col/3.0) - self.check_data_integrity( - ('col1 TIMESTAMP',), - generator) - - def test_LONG(self): - def generator(row,col): - if col == 0: - return row - else: - return self.BLOBUText # 'BLOB Text ' * 1024 - self.check_data_integrity( - ('col1 INT', 'col2 LONG'), - generator) - - def test_TEXT(self): - def generator(row,col): - if col == 0: - return row - else: - return self.BLOBUText[:5192] # 'BLOB Text ' * 1024 - self.check_data_integrity( - ('col1 INT', 'col2 TEXT'), - generator) - - def test_LONG_BYTE(self): - def generator(row,col): - if col == 0: - return row - else: - return self.BLOBBinary # 'BLOB\000Binary ' * 1024 - self.check_data_integrity( - ('col1 INT','col2 LONG BYTE'), - generator) - - def test_BLOB(self): - def generator(row,col): - if col == 0: - return row - else: - return self.BLOBBinary # 'BLOB\000Binary ' * 1024 - self.check_data_integrity( - ('col1 INT','col2 BLOB'), - generator) - diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/dbapi20.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/dbapi20.py deleted file mode 100644 index e2027fccc9e..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/dbapi20.py +++ /dev/null @@ -1,856 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -''' Python DB API 2.0 driver compliance unit test suite. - - This software is Public Domain and may be used without restrictions. - - "Now we have booze and barflies entering the discussion, plus rumours of - DBAs on drugs... and I won't tell you what flashes through my mind each - time I read the subject line with 'Anal Compliance' in it. All around - this is turning out to be a thoroughly unwholesome unit test." - - -- Ian Bicking -''' - -__rcs_id__ = '$Id$' -__version__ = '$Revision$'[11:-2] -__author__ = 'Stuart Bishop ' - -import unittest -import time - -# $Log$ -# Revision 1.1.2.1 2006/02/25 03:44:32 adustman -# Generic DB-API unit test module -# Revision 1.10 2003/10/09 03:14:14 zenzen -# Add test for DB API 2.0 optional extension, where database exceptions -# are exposed as attributes on the Connection object. -# Revision 1.9 2003/08/13 01:16:36 zenzen -# Minor tweak from Stefan Fleiter -# Revision 1.8 2003/04/10 00:13:25 zenzen -# Changes, as per suggestions by M.-A. Lemburg -# Revision 1.7 2003/02/26 23:33:37 zenzen -# Break out DDL into helper functions, as per request by David Rushby -# Revision 1.6 2003/02/21 03:04:33 zenzen -# Stuff from Henrik Ekelund: -# added test_None -# added test_nextset & hooks -# Revision 1.5 2003/02/17 22:08:43 zenzen -# defaults to 1 & generic cursor.callproc test added -# Revision 1.4 2003/02/15 00:16:33 zenzen -# Changes, as per suggestions and bug reports by M.-A. Lemburg, -# Matthew T. Kromer, Federico Di Gregorio and Daniel Dittmar -# - Class renamed -# - Now a subclass of TestCase, to avoid requiring the driver stub -# to use multiple inheritance -# - Reversed the polarity of buggy test in test_description -# - Test exception heirarchy correctly -# - self.populate is now self._populate(), so if a driver stub -# overrides self.ddl1 this change propogates -# - VARCHAR columns now have a width, which will hopefully make the -# DDL even more portible (this will be reversed if it causes more problems) -# - cursor.rowcount being checked after various execute and fetchXXX methods -# - Check for fetchall and fetchmany returning empty lists after results -# are exhausted (already checking for empty lists if select retrieved -# nothing -# - Fix bugs in test_setoutputsize_basic and test_setinputsizes -# - -class DatabaseAPI20Test(unittest.TestCase): - ''' Test a database self.driver for DB API 2.0 compatibility. - This implementation tests Gadfly, but the TestCase - is structured so that other self.drivers can subclass this - test case to ensure compiliance with the DB-API. It is - expected that this TestCase may be expanded in the future - if ambiguities or edge conditions are discovered. - - The 'Optional Extensions' are not yet being tested. - - self.drivers should subclass this test, overriding setUp, tearDown, - self.driver, connect_args and connect_kw_args. Class specification - should be as follows: - - import dbapi20 - class mytest(dbapi20.DatabaseAPI20Test): - [...] - - Don't 'import DatabaseAPI20Test from dbapi20', or you will - confuse the unit tester - just 'import dbapi20'. - ''' - - # The self.driver module. This should be the module where the 'connect' - # method is to be found - driver = None - connect_args = () # List of arguments to pass to connect - connect_kw_args = {} # Keyword arguments for connect - table_prefix = 'dbapi20test_' # If you need to specify a prefix for tables - - ddl1 = 'create table %sbooze (name varchar(20))' % table_prefix - ddl2 = 'create table %sbarflys (name varchar(20))' % table_prefix - xddl1 = 'drop table %sbooze' % table_prefix - xddl2 = 'drop table %sbarflys' % table_prefix - - lowerfunc = 'lower' # Name of stored procedure to convert string->lowercase - - # Some drivers may need to override these helpers, for example adding - # a 'commit' after the execute. - def executeDDL1(self,cursor): - cursor.execute(self.ddl1) - - def executeDDL2(self,cursor): - cursor.execute(self.ddl2) - - def setUp(self): - ''' self.drivers should override this method to perform required setup - if any is necessary, such as creating the database. - ''' - pass - - def tearDown(self): - ''' self.drivers should override this method to perform required cleanup - if any is necessary, such as deleting the test database. - The default drops the tables that may be created. - ''' - con = self._connect() - try: - cur = con.cursor() - for ddl in (self.xddl1,self.xddl2): - try: - cur.execute(ddl) - con.commit() - except self.driver.Error: - # Assume table didn't exist. Other tests will check if - # execute is busted. - pass - finally: - con.close() - - def _connect(self): - try: - return self.driver.connect( - *self.connect_args,**self.connect_kw_args - ) - except AttributeError: - self.fail("No connect method found in self.driver module") - - def test_connect(self): - con = self._connect() - con.close() - - def test_apilevel(self): - try: - # Must exist - apilevel = self.driver.apilevel - # Must equal 2.0 - self.assertEqual(apilevel,'2.0') - except AttributeError: - self.fail("Driver doesn't define apilevel") - - def test_threadsafety(self): - try: - # Must exist - threadsafety = self.driver.threadsafety - # Must be a valid value - self.assertTrue(threadsafety in (0,1,2,3)) - except AttributeError: - self.fail("Driver doesn't define threadsafety") - - def test_paramstyle(self): - try: - # Must exist - paramstyle = self.driver.paramstyle - # Must be a valid value - self.assertTrue(paramstyle in ( - 'qmark','numeric','named','format','pyformat' - )) - except AttributeError: - self.fail("Driver doesn't define paramstyle") - - def test_Exceptions(self): - # Make sure required exceptions exist, and are in the - # defined heirarchy. - self.assertTrue(issubclass(self.driver.Warning,StandardError)) - self.assertTrue(issubclass(self.driver.Error,StandardError)) - self.assertTrue( - issubclass(self.driver.InterfaceError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.DatabaseError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.OperationalError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.IntegrityError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.InternalError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.ProgrammingError,self.driver.Error) - ) - self.assertTrue( - issubclass(self.driver.NotSupportedError,self.driver.Error) - ) - - def test_ExceptionsAsConnectionAttributes(self): - # OPTIONAL EXTENSION - # Test for the optional DB API 2.0 extension, where the exceptions - # are exposed as attributes on the Connection object - # I figure this optional extension will be implemented by any - # driver author who is using this test suite, so it is enabled - # by default. - con = self._connect() - drv = self.driver - self.assertTrue(con.Warning is drv.Warning) - self.assertTrue(con.Error is drv.Error) - self.assertTrue(con.InterfaceError is drv.InterfaceError) - self.assertTrue(con.DatabaseError is drv.DatabaseError) - self.assertTrue(con.OperationalError is drv.OperationalError) - self.assertTrue(con.IntegrityError is drv.IntegrityError) - self.assertTrue(con.InternalError is drv.InternalError) - self.assertTrue(con.ProgrammingError is drv.ProgrammingError) - self.assertTrue(con.NotSupportedError is drv.NotSupportedError) - - - def test_commit(self): - con = self._connect() - try: - # Commit must work, even if it doesn't do anything - con.commit() - finally: - con.close() - - def test_rollback(self): - con = self._connect() - # If rollback is defined, it should either work or throw - # the documented exception - if hasattr(con,'rollback'): - try: - con.rollback() - except self.driver.NotSupportedError: - pass - - def test_cursor(self): - con = self._connect() - try: - cur = con.cursor() - finally: - con.close() - - def test_cursor_isolation(self): - con = self._connect() - try: - # Make sure cursors created from the same connection have - # the documented transaction isolation level - cur1 = con.cursor() - cur2 = con.cursor() - self.executeDDL1(cur1) - cur1.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) - cur2.execute("select name from %sbooze" % self.table_prefix) - booze = cur2.fetchall() - self.assertEqual(len(booze),1) - self.assertEqual(len(booze[0]),1) - self.assertEqual(booze[0][0],'Victoria Bitter') - finally: - con.close() - - def test_description(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) - self.assertEqual(cur.description,None, - 'cursor.description should be none after executing a ' - 'statement that can return no rows (such as DDL)' - ) - cur.execute('select name from %sbooze' % self.table_prefix) - self.assertEqual(len(cur.description),1, - 'cursor.description describes too many columns' - ) - self.assertEqual(len(cur.description[0]),7, - 'cursor.description[x] tuples must have 7 elements' - ) - self.assertEqual(cur.description[0][0].lower(),'name', - 'cursor.description[x][0] must return column name' - ) - self.assertEqual(cur.description[0][1],self.driver.STRING, - 'cursor.description[x][1] must return column type. Got %r' - % cur.description[0][1] - ) - - # Make sure self.description gets reset - self.executeDDL2(cur) - self.assertEqual(cur.description,None, - 'cursor.description not being set to None when executing ' - 'no-result statements (eg. DDL)' - ) - finally: - con.close() - - def test_rowcount(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) - self.assertEqual(cur.rowcount,-1, - 'cursor.rowcount should be -1 after executing no-result ' - 'statements' - ) - cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) - self.assertTrue(cur.rowcount in (-1,1), - 'cursor.rowcount should == number or rows inserted, or ' - 'set to -1 after executing an insert statement' - ) - cur.execute("select name from %sbooze" % self.table_prefix) - self.assertTrue(cur.rowcount in (-1,1), - 'cursor.rowcount should == number of rows returned, or ' - 'set to -1 after executing a select statement' - ) - self.executeDDL2(cur) - self.assertEqual(cur.rowcount,-1, - 'cursor.rowcount not being reset to -1 after executing ' - 'no-result statements' - ) - finally: - con.close() - - lower_func = 'lower' - def test_callproc(self): - con = self._connect() - try: - cur = con.cursor() - if self.lower_func and hasattr(cur,'callproc'): - r = cur.callproc(self.lower_func,('FOO',)) - self.assertEqual(len(r),1) - self.assertEqual(r[0],'FOO') - r = cur.fetchall() - self.assertEqual(len(r),1,'callproc produced no result set') - self.assertEqual(len(r[0]),1, - 'callproc produced invalid result set' - ) - self.assertEqual(r[0][0],'foo', - 'callproc produced invalid results' - ) - finally: - con.close() - - def test_close(self): - con = self._connect() - try: - cur = con.cursor() - finally: - con.close() - - # cursor.execute should raise an Error if called after connection - # closed - self.assertRaises(self.driver.Error,self.executeDDL1,cur) - - # connection.commit should raise an Error if called after connection' - # closed.' - self.assertRaises(self.driver.Error,con.commit) - - # connection.close should raise an Error if called more than once - self.assertRaises(self.driver.Error,con.close) - - def test_execute(self): - con = self._connect() - try: - cur = con.cursor() - self._paraminsert(cur) - finally: - con.close() - - def _paraminsert(self,cur): - self.executeDDL1(cur) - cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) - self.assertTrue(cur.rowcount in (-1,1)) - - if self.driver.paramstyle == 'qmark': - cur.execute( - 'insert into %sbooze values (?)' % self.table_prefix, - ("Cooper's",) - ) - elif self.driver.paramstyle == 'numeric': - cur.execute( - 'insert into %sbooze values (:1)' % self.table_prefix, - ("Cooper's",) - ) - elif self.driver.paramstyle == 'named': - cur.execute( - 'insert into %sbooze values (:beer)' % self.table_prefix, - {'beer':"Cooper's"} - ) - elif self.driver.paramstyle == 'format': - cur.execute( - 'insert into %sbooze values (%%s)' % self.table_prefix, - ("Cooper's",) - ) - elif self.driver.paramstyle == 'pyformat': - cur.execute( - 'insert into %sbooze values (%%(beer)s)' % self.table_prefix, - {'beer':"Cooper's"} - ) - else: - self.fail('Invalid paramstyle') - self.assertTrue(cur.rowcount in (-1,1)) - - cur.execute('select name from %sbooze' % self.table_prefix) - res = cur.fetchall() - self.assertEqual(len(res),2,'cursor.fetchall returned too few rows') - beers = [res[0][0],res[1][0]] - beers.sort() - self.assertEqual(beers[0],"Cooper's", - 'cursor.fetchall retrieved incorrect data, or data inserted ' - 'incorrectly' - ) - self.assertEqual(beers[1],"Victoria Bitter", - 'cursor.fetchall retrieved incorrect data, or data inserted ' - 'incorrectly' - ) - - def test_executemany(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) - largs = [ ("Cooper's",) , ("Boag's",) ] - margs = [ {'beer': "Cooper's"}, {'beer': "Boag's"} ] - if self.driver.paramstyle == 'qmark': - cur.executemany( - 'insert into %sbooze values (?)' % self.table_prefix, - largs - ) - elif self.driver.paramstyle == 'numeric': - cur.executemany( - 'insert into %sbooze values (:1)' % self.table_prefix, - largs - ) - elif self.driver.paramstyle == 'named': - cur.executemany( - 'insert into %sbooze values (:beer)' % self.table_prefix, - margs - ) - elif self.driver.paramstyle == 'format': - cur.executemany( - 'insert into %sbooze values (%%s)' % self.table_prefix, - largs - ) - elif self.driver.paramstyle == 'pyformat': - cur.executemany( - 'insert into %sbooze values (%%(beer)s)' % ( - self.table_prefix - ), - margs - ) - else: - self.fail('Unknown paramstyle') - self.assertTrue(cur.rowcount in (-1,2), - 'insert using cursor.executemany set cursor.rowcount to ' - 'incorrect value %r' % cur.rowcount - ) - cur.execute('select name from %sbooze' % self.table_prefix) - res = cur.fetchall() - self.assertEqual(len(res),2, - 'cursor.fetchall retrieved incorrect number of rows' - ) - beers = [res[0][0],res[1][0]] - beers.sort() - self.assertEqual(beers[0],"Boag's",'incorrect data retrieved') - self.assertEqual(beers[1],"Cooper's",'incorrect data retrieved') - finally: - con.close() - - def test_fetchone(self): - con = self._connect() - try: - cur = con.cursor() - - # cursor.fetchone should raise an Error if called before - # executing a select-type query - self.assertRaises(self.driver.Error,cur.fetchone) - - # cursor.fetchone should raise an Error if called after - # executing a query that cannnot return rows - self.executeDDL1(cur) - self.assertRaises(self.driver.Error,cur.fetchone) - - cur.execute('select name from %sbooze' % self.table_prefix) - self.assertEqual(cur.fetchone(),None, - 'cursor.fetchone should return None if a query retrieves ' - 'no rows' - ) - self.assertTrue(cur.rowcount in (-1,0)) - - # cursor.fetchone should raise an Error if called after - # executing a query that cannnot return rows - cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) - self.assertRaises(self.driver.Error,cur.fetchone) - - cur.execute('select name from %sbooze' % self.table_prefix) - r = cur.fetchone() - self.assertEqual(len(r),1, - 'cursor.fetchone should have retrieved a single row' - ) - self.assertEqual(r[0],'Victoria Bitter', - 'cursor.fetchone retrieved incorrect data' - ) - self.assertEqual(cur.fetchone(),None, - 'cursor.fetchone should return None if no more rows available' - ) - self.assertTrue(cur.rowcount in (-1,1)) - finally: - con.close() - - samples = [ - 'Carlton Cold', - 'Carlton Draft', - 'Mountain Goat', - 'Redback', - 'Victoria Bitter', - 'XXXX' - ] - - def _populate(self): - ''' Return a list of sql commands to setup the DB for the fetch - tests. - ''' - populate = [ - "insert into %sbooze values ('%s')" % (self.table_prefix,s) - for s in self.samples - ] - return populate - - def test_fetchmany(self): - con = self._connect() - try: - cur = con.cursor() - - # cursor.fetchmany should raise an Error if called without - #issuing a query - self.assertRaises(self.driver.Error,cur.fetchmany,4) - - self.executeDDL1(cur) - for sql in self._populate(): - cur.execute(sql) - - cur.execute('select name from %sbooze' % self.table_prefix) - r = cur.fetchmany() - self.assertEqual(len(r),1, - 'cursor.fetchmany retrieved incorrect number of rows, ' - 'default of arraysize is one.' - ) - cur.arraysize=10 - r = cur.fetchmany(3) # Should get 3 rows - self.assertEqual(len(r),3, - 'cursor.fetchmany retrieved incorrect number of rows' - ) - r = cur.fetchmany(4) # Should get 2 more - self.assertEqual(len(r),2, - 'cursor.fetchmany retrieved incorrect number of rows' - ) - r = cur.fetchmany(4) # Should be an empty sequence - self.assertEqual(len(r),0, - 'cursor.fetchmany should return an empty sequence after ' - 'results are exhausted' - ) - self.assertTrue(cur.rowcount in (-1,6)) - - # Same as above, using cursor.arraysize - cur.arraysize=4 - cur.execute('select name from %sbooze' % self.table_prefix) - r = cur.fetchmany() # Should get 4 rows - self.assertEqual(len(r),4, - 'cursor.arraysize not being honoured by fetchmany' - ) - r = cur.fetchmany() # Should get 2 more - self.assertEqual(len(r),2) - r = cur.fetchmany() # Should be an empty sequence - self.assertEqual(len(r),0) - self.assertTrue(cur.rowcount in (-1,6)) - - cur.arraysize=6 - cur.execute('select name from %sbooze' % self.table_prefix) - rows = cur.fetchmany() # Should get all rows - self.assertTrue(cur.rowcount in (-1,6)) - self.assertEqual(len(rows),6) - self.assertEqual(len(rows),6) - rows = [r[0] for r in rows] - rows.sort() - - # Make sure we get the right data back out - for i in range(0,6): - self.assertEqual(rows[i],self.samples[i], - 'incorrect data retrieved by cursor.fetchmany' - ) - - rows = cur.fetchmany() # Should return an empty list - self.assertEqual(len(rows),0, - 'cursor.fetchmany should return an empty sequence if ' - 'called after the whole result set has been fetched' - ) - self.assertTrue(cur.rowcount in (-1,6)) - - self.executeDDL2(cur) - cur.execute('select name from %sbarflys' % self.table_prefix) - r = cur.fetchmany() # Should get empty sequence - self.assertEqual(len(r),0, - 'cursor.fetchmany should return an empty sequence if ' - 'query retrieved no rows' - ) - self.assertTrue(cur.rowcount in (-1,0)) - - finally: - con.close() - - def test_fetchall(self): - con = self._connect() - try: - cur = con.cursor() - # cursor.fetchall should raise an Error if called - # without executing a query that may return rows (such - # as a select) - self.assertRaises(self.driver.Error, cur.fetchall) - - self.executeDDL1(cur) - for sql in self._populate(): - cur.execute(sql) - - # cursor.fetchall should raise an Error if called - # after executing a a statement that cannot return rows - self.assertRaises(self.driver.Error,cur.fetchall) - - cur.execute('select name from %sbooze' % self.table_prefix) - rows = cur.fetchall() - self.assertTrue(cur.rowcount in (-1,len(self.samples))) - self.assertEqual(len(rows),len(self.samples), - 'cursor.fetchall did not retrieve all rows' - ) - rows = [r[0] for r in rows] - rows.sort() - for i in range(0,len(self.samples)): - self.assertEqual(rows[i],self.samples[i], - 'cursor.fetchall retrieved incorrect rows' - ) - rows = cur.fetchall() - self.assertEqual( - len(rows),0, - 'cursor.fetchall should return an empty list if called ' - 'after the whole result set has been fetched' - ) - self.assertTrue(cur.rowcount in (-1,len(self.samples))) - - self.executeDDL2(cur) - cur.execute('select name from %sbarflys' % self.table_prefix) - rows = cur.fetchall() - self.assertTrue(cur.rowcount in (-1,0)) - self.assertEqual(len(rows),0, - 'cursor.fetchall should return an empty list if ' - 'a select query returns no rows' - ) - - finally: - con.close() - - def test_mixedfetch(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) - for sql in self._populate(): - cur.execute(sql) - - cur.execute('select name from %sbooze' % self.table_prefix) - rows1 = cur.fetchone() - rows23 = cur.fetchmany(2) - rows4 = cur.fetchone() - rows56 = cur.fetchall() - self.assertTrue(cur.rowcount in (-1,6)) - self.assertEqual(len(rows23),2, - 'fetchmany returned incorrect number of rows' - ) - self.assertEqual(len(rows56),2, - 'fetchall returned incorrect number of rows' - ) - - rows = [rows1[0]] - rows.extend([rows23[0][0],rows23[1][0]]) - rows.append(rows4[0]) - rows.extend([rows56[0][0],rows56[1][0]]) - rows.sort() - for i in range(0,len(self.samples)): - self.assertEqual(rows[i],self.samples[i], - 'incorrect data retrieved or inserted' - ) - finally: - con.close() - - def help_nextset_setUp(self,cur): - ''' Should create a procedure called deleteme - that returns two result sets, first the - number of rows in booze then "name from booze" - ''' - raise NotImplementedError,'Helper not implemented' - #sql=""" - # create procedure deleteme as - # begin - # select count(*) from booze - # select name from booze - # end - #""" - #cur.execute(sql) - - def help_nextset_tearDown(self,cur): - 'If cleaning up is needed after nextSetTest' - raise NotImplementedError,'Helper not implemented' - #cur.execute("drop procedure deleteme") - - def test_nextset(self): - con = self._connect() - try: - cur = con.cursor() - if not hasattr(cur,'nextset'): - return - - try: - self.executeDDL1(cur) - sql=self._populate() - for sql in self._populate(): - cur.execute(sql) - - self.help_nextset_setUp(cur) - - cur.callproc('deleteme') - numberofrows=cur.fetchone() - assert numberofrows[0]== len(self.samples) - assert cur.nextset() - names=cur.fetchall() - assert len(names) == len(self.samples) - s=cur.nextset() - assert s == None,'No more return sets, should return None' - finally: - self.help_nextset_tearDown(cur) - - finally: - con.close() - - def test_nextset(self): - raise NotImplementedError,'Drivers need to override this test' - - def test_arraysize(self): - # Not much here - rest of the tests for this are in test_fetchmany - con = self._connect() - try: - cur = con.cursor() - self.assertTrue(hasattr(cur,'arraysize'), - 'cursor.arraysize must be defined' - ) - finally: - con.close() - - def test_setinputsizes(self): - con = self._connect() - try: - cur = con.cursor() - cur.setinputsizes( (25,) ) - self._paraminsert(cur) # Make sure cursor still works - finally: - con.close() - - def test_setoutputsize_basic(self): - # Basic test is to make sure setoutputsize doesn't blow up - con = self._connect() - try: - cur = con.cursor() - cur.setoutputsize(1000) - cur.setoutputsize(2000,0) - self._paraminsert(cur) # Make sure the cursor still works - finally: - con.close() - - def test_setoutputsize(self): - # Real test for setoutputsize is driver dependant - raise NotImplementedError,'Driver need to override this test' - - def test_None(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) - cur.execute('insert into %sbooze values (NULL)' % self.table_prefix) - cur.execute('select name from %sbooze' % self.table_prefix) - r = cur.fetchall() - self.assertEqual(len(r),1) - self.assertEqual(len(r[0]),1) - self.assertEqual(r[0][0],None,'NULL value not returned as None') - finally: - con.close() - - def test_Date(self): - d1 = self.driver.Date(2002,12,25) - d2 = self.driver.DateFromTicks(time.mktime((2002,12,25,0,0,0,0,0,0))) - # Can we assume this? API doesn't specify, but it seems implied - # self.assertEqual(str(d1),str(d2)) - - def test_Time(self): - t1 = self.driver.Time(13,45,30) - t2 = self.driver.TimeFromTicks(time.mktime((2001,1,1,13,45,30,0,0,0))) - # Can we assume this? API doesn't specify, but it seems implied - # self.assertEqual(str(t1),str(t2)) - - def test_Timestamp(self): - t1 = self.driver.Timestamp(2002,12,25,13,45,30) - t2 = self.driver.TimestampFromTicks( - time.mktime((2002,12,25,13,45,30,0,0,0)) - ) - # Can we assume this? API doesn't specify, but it seems implied - # self.assertEqual(str(t1),str(t2)) - - def test_Binary(self): - b = self.driver.Binary('Something') - b = self.driver.Binary('') - - def test_STRING(self): - self.assertTrue(hasattr(self.driver,'STRING'), - 'module.STRING must be defined' - ) - - def test_BINARY(self): - self.assertTrue(hasattr(self.driver,'BINARY'), - 'module.BINARY must be defined.' - ) - - def test_NUMBER(self): - self.assertTrue(hasattr(self.driver,'NUMBER'), - 'module.NUMBER must be defined.' - ) - - def test_DATETIME(self): - self.assertTrue(hasattr(self.driver,'DATETIME'), - 'module.DATETIME must be defined.' - ) - - def test_ROWID(self): - self.assertTrue(hasattr(self.driver,'ROWID'), - 'module.ROWID must be defined.' - ) - diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py deleted file mode 100644 index c1423c5eea4..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import capabilities -import unittest -import pymysql -from pymysql.tests import base -import warnings - -warnings.filterwarnings('error') - -class test_MySQLdb(capabilities.DatabaseTest): - - db_module = pymysql - connect_args = () - connect_kwargs = base.PyMySQLTestCase.databases[0].copy() - connect_kwargs.update(dict(read_default_file='~/.my.cnf', - use_unicode=True, - charset='utf8', sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")) - - create_table_extra = "ENGINE=INNODB CHARACTER SET UTF8" - leak_test = False - - def quote_identifier(self, ident): - return "`%s`" % ident - - def test_TIME(self): - from datetime import timedelta - def generator(row,col): - return timedelta(0, row*8000) - self.check_data_integrity( - ('col1 TIME',), - generator) - - def test_TINYINT(self): - # Number data - def generator(row,col): - v = (row*row) % 256 - if v > 127: - v = v-256 - return v - self.check_data_integrity( - ('col1 TINYINT',), - generator) - - def test_stored_procedures(self): - db = self.connection - c = self.cursor - try: - self.create_table(('pos INT', 'tree CHAR(20)')) - c.executemany("INSERT INTO %s (pos,tree) VALUES (%%s,%%s)" % self.table, - list(enumerate('ash birch cedar larch pine'.split()))) - db.commit() - - c.execute(""" - CREATE PROCEDURE test_sp(IN t VARCHAR(255)) - BEGIN - SELECT pos FROM %s WHERE tree = t; - END - """ % self.table) - db.commit() - - c.callproc('test_sp', ('larch',)) - rows = c.fetchall() - self.assertEquals(len(rows), 1) - self.assertEquals(rows[0][0], 3) - c.nextset() - finally: - c.execute("DROP PROCEDURE IF EXISTS test_sp") - c.execute('drop table %s' % (self.table)) - - def test_small_CHAR(self): - # Character data - def generator(row,col): - i = ((row+1)*(col+1)+62)%256 - if i == 62: return '' - if i == 63: return None - return chr(i) - self.check_data_integrity( - ('col1 char(1)','col2 char(1)'), - generator) - - def test_bug_2671682(self): - from pymysql.constants import ER - try: - self.cursor.execute("describe some_non_existent_table"); - except self.connection.ProgrammingError, msg: - self.assertTrue(msg.args[0] == ER.NO_SUCH_TABLE) - - def test_insert_values(self): - from pymysql.cursors import insert_values - query = """INSERT FOO (a, b, c) VALUES (a, b, c)""" - matched = insert_values.search(query) - self.assertTrue(matched) - values = matched.group(1) - self.assertTrue(values == "(a, b, c)") - - def test_ping(self): - self.connection.ping() - - def test_literal_int(self): - self.assertTrue("2" == self.connection.literal(2)) - - def test_literal_float(self): - self.assertTrue("3.1415" == self.connection.literal(3.1415)) - - def test_literal_string(self): - self.assertTrue("'foo'" == self.connection.literal("foo")) - - -if __name__ == '__main__': - if test_MySQLdb.leak_test: - import gc - gc.enable() - gc.set_debug(gc.DEBUG_LEAK) - unittest.main() - diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py deleted file mode 100644 index 7077c7a96e1..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import dbapi20 -import unittest -import pymysql -from pymysql.tests import base - -class test_MySQLdb(dbapi20.DatabaseAPI20Test): - driver = pymysql - connect_args = () - connect_kw_args = base.PyMySQLTestCase.databases[0].copy() - connect_kw_args.update(dict(read_default_file='~/.my.cnf', - charset='utf8', - sql_mode="ANSI,STRICT_TRANS_TABLES,TRADITIONAL")) - - def test_setoutputsize(self): pass - def test_setoutputsize_basic(self): pass - def test_nextset(self): pass - - """The tests on fetchone and fetchall and rowcount bogusly - test for an exception if the statement cannot return a - result set. MySQL always returns a result set; it's just that - some things return empty result sets.""" - - def test_fetchall(self): - con = self._connect() - try: - cur = con.cursor() - # cursor.fetchall should raise an Error if called - # without executing a query that may return rows (such - # as a select) - self.assertRaises(self.driver.Error, cur.fetchall) - - self.executeDDL1(cur) - for sql in self._populate(): - cur.execute(sql) - - # cursor.fetchall should raise an Error if called - # after executing a a statement that cannot return rows -## self.assertRaises(self.driver.Error,cur.fetchall) - - cur.execute('select name from %sbooze' % self.table_prefix) - rows = cur.fetchall() - self.assertTrue(cur.rowcount in (-1,len(self.samples))) - self.assertEqual(len(rows),len(self.samples), - 'cursor.fetchall did not retrieve all rows' - ) - rows = [r[0] for r in rows] - rows.sort() - for i in range(0,len(self.samples)): - self.assertEqual(rows[i],self.samples[i], - 'cursor.fetchall retrieved incorrect rows' - ) - rows = cur.fetchall() - self.assertEqual( - len(rows),0, - 'cursor.fetchall should return an empty list if called ' - 'after the whole result set has been fetched' - ) - self.assertTrue(cur.rowcount in (-1,len(self.samples))) - - self.executeDDL2(cur) - cur.execute('select name from %sbarflys' % self.table_prefix) - rows = cur.fetchall() - self.assertTrue(cur.rowcount in (-1,0)) - self.assertEqual(len(rows),0, - 'cursor.fetchall should return an empty list if ' - 'a select query returns no rows' - ) - - finally: - con.close() - - def test_fetchone(self): - con = self._connect() - try: - cur = con.cursor() - - # cursor.fetchone should raise an Error if called before - # executing a select-type query - self.assertRaises(self.driver.Error,cur.fetchone) - - # cursor.fetchone should raise an Error if called after - # executing a query that cannnot return rows - self.executeDDL1(cur) -## self.assertRaises(self.driver.Error,cur.fetchone) - - cur.execute('select name from %sbooze' % self.table_prefix) - self.assertEqual(cur.fetchone(),None, - 'cursor.fetchone should return None if a query retrieves ' - 'no rows' - ) - self.assertTrue(cur.rowcount in (-1,0)) - - # cursor.fetchone should raise an Error if called after - # executing a query that cannnot return rows - cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) -## self.assertRaises(self.driver.Error,cur.fetchone) - - cur.execute('select name from %sbooze' % self.table_prefix) - r = cur.fetchone() - self.assertEqual(len(r),1, - 'cursor.fetchone should have retrieved a single row' - ) - self.assertEqual(r[0],'Victoria Bitter', - 'cursor.fetchone retrieved incorrect data' - ) -## self.assertEqual(cur.fetchone(),None, -## 'cursor.fetchone should return None if no more rows available' -## ) - self.assertTrue(cur.rowcount in (-1,1)) - finally: - con.close() - - # Same complaint as for fetchall and fetchone - def test_rowcount(self): - con = self._connect() - try: - cur = con.cursor() - self.executeDDL1(cur) -## self.assertEqual(cur.rowcount,-1, -## 'cursor.rowcount should be -1 after executing no-result ' -## 'statements' -## ) - cur.execute("insert into %sbooze values ('Victoria Bitter')" % ( - self.table_prefix - )) -## self.assertTrue(cur.rowcount in (-1,1), -## 'cursor.rowcount should == number or rows inserted, or ' -## 'set to -1 after executing an insert statement' -## ) - cur.execute("select name from %sbooze" % self.table_prefix) - self.assertTrue(cur.rowcount in (-1,1), - 'cursor.rowcount should == number of rows returned, or ' - 'set to -1 after executing a select statement' - ) - self.executeDDL2(cur) -## self.assertEqual(cur.rowcount,-1, -## 'cursor.rowcount not being reset to -1 after executing ' -## 'no-result statements' -## ) - finally: - con.close() - - def test_callproc(self): - pass # performed in test_MySQL_capabilities - - def help_nextset_setUp(self,cur): - ''' Should create a procedure called deleteme - that returns two result sets, first the - number of rows in booze then "name from booze" - ''' - sql=""" - create procedure deleteme() - begin - select count(*) from %(tp)sbooze; - select name from %(tp)sbooze; - end - """ % dict(tp=self.table_prefix) - cur.execute(sql) - - def help_nextset_tearDown(self,cur): - 'If cleaning up is needed after nextSetTest' - cur.execute("drop procedure deleteme") - - def test_nextset(self): - from warnings import warn - con = self._connect() - try: - cur = con.cursor() - if not hasattr(cur,'nextset'): - return - - try: - self.executeDDL1(cur) - sql=self._populate() - for sql in self._populate(): - cur.execute(sql) - - self.help_nextset_setUp(cur) - - cur.callproc('deleteme') - numberofrows=cur.fetchone() - assert numberofrows[0]== len(self.samples) - assert cur.nextset() - names=cur.fetchall() - assert len(names) == len(self.samples) - s=cur.nextset() - if s: - empty = cur.fetchall() - self.assertEquals(len(empty), 0, - "non-empty result set after other result sets") - #warn("Incompatibility: MySQL returns an empty result set for the CALL itself", - # Warning) - #assert s == None,'No more return sets, should return None' - finally: - self.help_nextset_tearDown(cur) - - finally: - con.close() - - -if __name__ == '__main__': - unittest.main() diff --git a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py b/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py deleted file mode 100644 index c5599e9017e..00000000000 --- a/tools/testClient/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import unittest - -import pymysql -_mysql = pymysql -from pymysql.constants import FIELD_TYPE -from pymysql.tests import base - - -class TestDBAPISet(unittest.TestCase): - def test_set_equality(self): - self.assertTrue(pymysql.STRING == pymysql.STRING) - - def test_set_inequality(self): - self.assertTrue(pymysql.STRING != pymysql.NUMBER) - - def test_set_equality_membership(self): - self.assertTrue(FIELD_TYPE.VAR_STRING == pymysql.STRING) - - def test_set_inequality_membership(self): - self.assertTrue(FIELD_TYPE.DATE != pymysql.STRING) - - -class CoreModule(unittest.TestCase): - """Core _mysql module features.""" - - def test_NULL(self): - """Should have a NULL constant.""" - self.assertEqual(_mysql.NULL, 'NULL') - - def test_version(self): - """Version information sanity.""" - self.assertTrue(isinstance(_mysql.__version__, str)) - - self.assertTrue(isinstance(_mysql.version_info, tuple)) - self.assertEqual(len(_mysql.version_info), 5) - - def test_client_info(self): - self.assertTrue(isinstance(_mysql.get_client_info(), str)) - - def test_thread_safe(self): - self.assertTrue(isinstance(_mysql.thread_safe(), int)) - - -class CoreAPI(unittest.TestCase): - """Test _mysql interaction internals.""" - - def setUp(self): - kwargs = base.PyMySQLTestCase.databases[0].copy() - kwargs["read_default_file"] = "~/.my.cnf" - self.conn = _mysql.connect(**kwargs) - - def tearDown(self): - self.conn.close() - - def test_thread_id(self): - tid = self.conn.thread_id() - self.assertTrue(isinstance(tid, int), - "thread_id didn't return an int.") - - self.assertRaises(TypeError, self.conn.thread_id, ('evil',), - "thread_id shouldn't accept arguments.") - - def test_affected_rows(self): - self.assertEquals(self.conn.affected_rows(), 0, - "Should return 0 before we do anything.") - - - #def test_debug(self): - ## FIXME Only actually tests if you lack SUPER - #self.assertRaises(pymysql.OperationalError, - #self.conn.dump_debug_info) - - def test_charset_name(self): - self.assertTrue(isinstance(self.conn.character_set_name(), str), - "Should return a string.") - - def test_host_info(self): - self.assertTrue(isinstance(self.conn.get_host_info(), str), - "Should return a string.") - - def test_proto_info(self): - self.assertTrue(isinstance(self.conn.get_proto_info(), int), - "Should return an int.") - - def test_server_info(self): - self.assertTrue(isinstance(self.conn.get_server_info(), basestring), - "Should return an str.") - -if __name__ == "__main__": - unittest.main() diff --git a/tools/testClient/pymysql/util.py b/tools/testClient/pymysql/util.py deleted file mode 100644 index 2c2392b234e..00000000000 --- a/tools/testClient/pymysql/util.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import struct - -def byte2int(b): - if isinstance(b, int): - return b - else: - return struct.unpack("!B", b)[0] - -def int2byte(i): - return struct.pack("!B", i) - -def join_bytes(bs): - if len(bs) == 0: - return "" - else: - rv = bs[0] - for b in bs[1:]: - rv += b - return rv diff --git a/tools/testClient/remoteSSHClient.py b/tools/testClient/remoteSSHClient.py deleted file mode 100644 index 99d298be5ae..00000000000 --- a/tools/testClient/remoteSSHClient.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import paramiko -import cloudstackException -class remoteSSHClient(object): - def __init__(self, host, port, user, passwd): - self.host = host - self.port = port - self.user = user - self.passwd = passwd - self.ssh = paramiko.SSHClient() - self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - try: - self.ssh.connect(str(host),int(port), user, passwd) - except paramiko.SSHException, sshex: - raise cloudstackException.InvalidParameterException(repr(sshex)) - - def execute(self, command): - stdin, stdout, stderr = self.ssh.exec_command(command) - output = stdout.readlines() - errors = stderr.readlines() - results = [] - if output is not None and len(output) == 0: - if errors is not None and len(errors) > 0: - for error in errors: - results.append(error.rstrip()) - - else: - for strOut in output: - results.append(strOut.rstrip()) - - return results - - -if __name__ == "__main__": - ssh = remoteSSHClient("192.168.137.2", 22, "root", "password") - print ssh.execute("ls -l") - print ssh.execute("rm x") \ No newline at end of file diff --git a/tools/testClient/resourceMgrTest/__init__.py b/tools/testClient/resourceMgrTest/__init__.py deleted file mode 100755 index 37f96cecb27..00000000000 --- a/tools/testClient/resourceMgrTest/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 diff --git a/tools/testClient/resourceMgrTest/setup.py b/tools/testClient/resourceMgrTest/setup.py deleted file mode 100755 index 87bd72cc345..00000000000 --- a/tools/testClient/resourceMgrTest/setup.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -''' -Created on Oct 18, 2011 - -@author: frank -''' -from optparse import OptionParser -from configGenerator import * - -if __name__ == '__main__': - parser = OptionParser() - parser.add_option('-o', '--output', action='store', default='./setup.conf', dest='output', help='the path where the json config file generated') - parser.add_option('-m', '--mshost', dest='mshost', help='hostname/ip of management server', action='store') - - (opts, args) = parser.parse_args() - mandatories = ['mshost'] - for m in mandatories: - if not opts.__dict__[m]: - parser.error("mandatory option - " + m +" missing") - - zs = cloudstackConfiguration() - - #Define Zone - z = zone() - z.dns1 = "8.8.8.8" - z.dns2 = "4.4.4.4" - z.internaldns1 = "192.168.110.254" - z.internaldns2 = "192.168.110.253" - z.name = "testZone" - z.networktype = 'Basic' - - #Define SecondaryStorage - ss = secondaryStorage() - ss.url ="nfs://172.16.15.32/export/share/secondary" - z.secondaryStorages.append(ss) - - p = pod() - p.name = "POD-1" - p.gateway = "10.223.64.1" - p.netmask = "255.255.254.0" - p.startip = "10.223.64.50" - p.endip = "10.223.64.60" - - ip = iprange() - ip.vlan="untagged" - ip.gateway = p.gateway - ip.netmask = p.netmask - ip.startip = "10.223.64.70" - ip.endip = "10.223.64.220" - p.guestIpRanges.append(ip) - - c = cluster() - c.clustername = "CLUSTER-1" - c.clustertype = "CloudManaged" - c.hypervisor = "Simulator" - p.clusters.append(c) - - z.pods.append(p) - zs.zones.append(z) - - '''Add one mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = opts.mshost - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = opts.mshost - db.user = "root" - db.passwd = "" - zs.dbSvr = db - - generate_setup_config(zs,opts.output) - \ No newline at end of file diff --git a/tools/testClient/resourceMgrTest/testDeploy100Host.py b/tools/testClient/resourceMgrTest/testDeploy100Host.py deleted file mode 100755 index 927fb9a1ee9..00000000000 --- a/tools/testClient/resourceMgrTest/testDeploy100Host.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -''' -Created on Oct 18, 2011 - -@author: frank -''' -from cloudstackTestCase import * -from cloudstackAPI import * -import uuid -import threading -import random -import time - -class Task(threading.Thread): - def __init__(self, func, param=None): - super(Task, self).__init__() - self.func = func - self.param = param - - def run(self): - self.func(self.param) - - def doTask(self): - self.start() - -class TestDeploy100Hosts(cloudstackTestCase): - hosts = [] - def deployHost(self, url): - apiClient = self.testClient.getApiClient() - addHostCmd = addHost.addHostCmd() - addHostCmd.hypervisor = "simulator" - addHostCmd.clusterid = 1 - addHostCmd.zoneid = 1 - addHostCmd.podid = 1 - addHostCmd.url = "http://sim/%s"%url - addHostCmd.username = "placeholder" - addHostCmd.password = "placeholder" - addHostResponce = apiClient.addHost(addHostCmd) - return addHostResponce[0].id - - def randomCancelMaintenance(self): - def run(param): - while(1): - try: - interval = random.randint(1, 2) - time.sleep(interval) - if len(self.hosts) == 0: - continue - - index = random.randint(0, len(self.hosts)-1) - hostId = self.hosts[index] - apiClient = self.testClient.getApiClient() - cMaintainCmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cMaintainCmd.id = hostId - response = apiClient.cancelHostMaintenance(cMaintainCmd) - id = response.id - print "Host %s cancelled maintenance mode" % id - except Exception, e: - print e - - t = Task(run) - t.doTask() - - def randomEnterMaintenance(self): - def run(param): - while(1): - try: - interval = random.randint(1, 2) - time.sleep(interval) - if len(self.hosts) == 0: - continue - index = random.randint(0, len(self.hosts)-1) - hostId = self.hosts[index] - apiClient = self.testClient.getApiClient() - maintainCmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - maintainCmd.id = hostId - response = apiClient.prepareHostForMaintenance(maintainCmd) - id = response.id - print "Host %s entered maintenance mode" % id - except Exception, e: - print e - - t = Task(run) - t.doTask() - - - def test_deploy100Hosts(self): - #for i in range(200): - #self.hosts.append(self.deployHost(i)) - for i in range(200): - self.hosts.append(i) - self.randomEnterMaintenance() - self.randomCancelMaintenance() - while(1): time.sleep(10000) - diff --git a/tools/testClient/sandbox/advanced/advanced_env.py b/tools/testClient/sandbox/advanced/advanced_env.py deleted file mode 100644 index ffb4de43510..00000000000 --- a/tools/testClient/sandbox/advanced/advanced_env.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -''' -# Experimental state of scripts -# * Need to be reviewed -# * Only a sandbox -''' - -from ConfigParser import SafeConfigParser -from optparse import OptionParser -from configGenerator import * -import random - - -def getGlobalSettings(config): - for k, v in dict(config.items('globals')).iteritems(): - cfg = configuration() - cfg.name = k - cfg.value = v - yield cfg - - -def describeResources(config): - zs = cloudstackConfiguration() - - z = zone() - z.dns1 = config.get('environment', 'dns') - z.internaldns1 = config.get('environment', 'dns') - z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) - z.networktype = 'Advanced' - z.guestcidraddress = '10.1.1.0/24' - - prov = provider() - prov.vlan = config.get('cloudstack','guest.vlan') - z.providers.append(prov) - - p = pod() - p.name = 'POD0' - p.gateway = config.get('cloudstack', 'private.gateway') - p.startip = config.get('cloudstack', 'private.pod.startip') - p.endip = config.get('cloudstack', 'private.pod.endip') - p.netmask = '255.255.255.0' - - v = iprange() - v.gateway = config.get('cloudstack', 'public.gateway') - v.startip = config.get('cloudstack', 'public.vlan.startip') - v.endip = config.get('cloudstack', 'public.vlan.endip') - v.netmask = '255.255.255.0' - v.vlan = config.get('cloudstack', 'public.vlan') - z.ipranges.append(v) - - c = cluster() - c.clustername = 'C0' - c.hypervisor = config.get('environment', 'hypervisor') - c.clustertype = 'CloudManaged' - - h = host() - h.username = 'root' - h.password = 'password' - h.url = 'http://%s'%(config.get('cloudstack', 'host')) - c.hosts.append(h) - - ps = primaryStorage() - ps.name = 'PS0' - ps.url = config.get('cloudstack', 'pool') - c.primaryStorages.append(ps) - - p.clusters.append(c) - z.pods.append(p) - - secondary = secondaryStorage() - secondary.url = config.get('cloudstack', 'secondary') - z.secondaryStorages.append(secondary) - - '''Add zone''' - zs.zones.append(z) - - '''Add mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = config.get('environment', 'mshost') - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = config.get('environment', 'database') - zs.dbSvr = db - - '''Add some configuration''' - [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)] - - ''''add loggers''' - testClientLogger = logger() - testClientLogger.name = 'TestClient' - testClientLogger.file = '/var/log/testclient.log' - - testCaseLogger = logger() - testCaseLogger.name = 'TestCase' - testCaseLogger.file = '/var/log/testcase.log' - - zs.logger.append(testClientLogger) - zs.logger.append(testCaseLogger) - return zs - - -if __name__ == '__main__': - parser = OptionParser() - parser.add_option('-i', '--input', action='store', default='setup.properties', \ - dest='input', help='file containing environment setup information') - parser.add_option('-o', '--output', action='store', default='./sandbox.cfg', \ - dest='output', help='path where environment json will be generated') - - - (opts, args) = parser.parse_args() - - cfg_parser = SafeConfigParser() - cfg_parser.read(opts.input) - - cfg = describeResources(cfg_parser) - generate_setup_config(cfg, opts.output) diff --git a/tools/testClient/sandbox/advanced/kvm.properties b/tools/testClient/sandbox/advanced/kvm.properties deleted file mode 100644 index a34da935760..00000000000 --- a/tools/testClient/sandbox/advanced/kvm.properties +++ /dev/null @@ -1,37 +0,0 @@ -[globals] -expunge.delay=60 -expunge.interval=60 -storage.cleanup.interval=300 -account.cleanup.interval=600 -expunge.workers=3 -workers=10 -use.user.concentrated.pod.allocation=false -vm.allocation.algorithm=random -vm.op.wait.interval=5 -guest.domain.suffix=sandbox.kvm -instance.name=QA -direct.agent.load.size=1000 -default.page.size=10000 -check.pod.cidrs=true -secstorage.allowed.internal.sites=10.147.28.0/24 -[environment] -dns=10.147.28.6 -mshost=10.147.29.111 -database=10.147.29.111 -hypervisor=kvm -[cloudstack] -zone.vlan=675-679 -#pod configuration -private.gateway=10.147.29.1 -private.pod.startip=10.147.29.150 -private.pod.endip=10.147.29.159 -#public vlan range -public.gateway=10.147.31.1 -public.vlan=31 -public.vlan.startip=10.147.31.150 -public.vlan.endip=10.147.31.159 -#hosts -host=10.147.29.58 -#pools -pool=nfs://10.147.28.6:/export/home/prasanna/kamakura -secondary=nfs://10.147.28.6:/export/home/prasanna/sstor diff --git a/tools/testClient/sandbox/advanced/tests/test_scenarios.py b/tools/testClient/sandbox/advanced/tests/test_scenarios.py deleted file mode 100644 index a332a09ed03..00000000000 --- a/tools/testClient/sandbox/advanced/tests/test_scenarios.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -try: - import unittest2 as unittest -except ImportError: - import unittest - -import random -import hashlib -from cloudstackTestCase import * -import remoteSSHClient - -class SampleScenarios(cloudstackTestCase): - ''' - ''' - def setUp(self): - pass - - - def tearDown(self): - pass - - - def test_1_createAccounts(self, numberOfAccounts=2): - ''' - Create a bunch of user accounts - ''' - mdf = hashlib.md5() - mdf.update('password') - mdf_pass = mdf.hexdigest() - api = self.testClient.getApiClient() - for i in range(1, numberOfAccounts + 1): - acct = createAccount.createAccountCmd() - acct.accounttype = 0 - acct.firstname = 'user' + str(i) - acct.lastname = 'user' + str(i) - acct.password = mdf_pass - acct.username = 'user' + str(i) - acct.email = 'user@example.com' - acct.account = 'user' + str(i) - acct.domainid = 1 - acctResponse = api.createAccount(acct) - self.debug("successfully created account: %s, user: %s, id: %s"%(acctResponse.account, acctResponse.username, acctResponse.id)) - - - def test_2_createServiceOffering(self): - apiClient = self.testClient.getApiClient() - createSOcmd=createServiceOffering.createServiceOfferingCmd() - createSOcmd.name='Sample SO' - createSOcmd.displaytext='Sample SO' - createSOcmd.storagetype='shared' - createSOcmd.cpunumber=1 - createSOcmd.cpuspeed=100 - createSOcmd.memory=128 - createSOcmd.offerha='false' - createSOresponse = apiClient.createServiceOffering(createSOcmd) - return createSOresponse.id - - def deployCmd(self, account, service): - deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd() - deployVmCmd.zoneid = 1 - deployVmCmd.account=account - deployVmCmd.domainid=1 - deployVmCmd.templateid=2 - deployVmCmd.serviceofferingid=service - return deployVmCmd - - def listVmsInAccountCmd(self, acct): - api = self.testClient.getApiClient() - listVmCmd = listVirtualMachines.listVirtualMachinesCmd() - listVmCmd.account = acct - listVmCmd.zoneid = 1 - listVmCmd.domainid = 1 - listVmResponse = api.listVirtualMachines(listVmCmd) - return listVmResponse - - - def destroyVmCmd(self, key): - api = self.testClient.getApiClient() - destroyVmCmd = destroyVirtualMachine.destroyVirtualMachineCmd() - destroyVmCmd.id = key - api.destroyVirtualMachine(destroyVmCmd) - - - def test_3_stressDeploy(self): - ''' - Deploy 5 Vms in each account - ''' - service_id = self.test_2_createServiceOffering() - api = self.testClient.getApiClient() - for acct in range(1, 5): - [api.deployVirtualMachine(self.deployCmd('user'+str(acct), service_id)) for x in range(0,5)] - - @unittest.skip("skipping destroys") - def test_4_stressDestroy(self): - ''' - Cleanup all Vms in every account - ''' - api = self.testClient.getApiClient() - for acct in range(1, 6): - for vm in self.listVmsInAccountCmd('user'+str(acct)): - if vm is not None: - self.destroyVmCmd(vm.id) - - @unittest.skip("skipping destroys") - def test_5_combineStress(self): - for i in range(0, 5): - self.test_3_stressDeploy() - self.test_4_stressDestroy() - - def deployN(self,nargs=300,batchsize=0): - ''' - Deploy Nargs number of VMs concurrently in batches of size {batchsize}. - When batchsize is 0 all Vms are deployed in one batch - VMs will be deployed in 5:2:6 ratio - ''' - cmds = [] - - if batchsize == 0: - self.testClient.submitCmdsAndWait(cmds) - else: - while len(z) > 0: - try: - newbatch = [cmds.pop() for b in range(batchsize)] #pop batchsize items - self.testClient.submitCmdsAndWait(newbatch) - except IndexError: - break diff --git a/tools/testClient/sandbox/advanced/xen.properties b/tools/testClient/sandbox/advanced/xen.properties deleted file mode 100644 index 90c2f710fe3..00000000000 --- a/tools/testClient/sandbox/advanced/xen.properties +++ /dev/null @@ -1,36 +0,0 @@ -[globals] -expunge.delay=60 -expunge.interval=60 -storage.cleanup.interval=300 -account.cleanup.interval=600 -expunge.workers=3 -workers=10 -vm.allocation.algorithm=userdispersing -vm.op.wait.interval=5 -guest.domain.suffix=sandbox.xen -instance.name=QA -direct.agent.load.size=1000 -default.page.size=10000 -check.pod.cidrs=true -secstorage.allowed.internal.sites=10.147.28.0/24 -[environment] -dns=10.147.28.6 -mshost=10.147.29.110 -database=localhost -hypervisor=XenServer -[cloudstack] -guest.vlan=670-674 -#pod configuration -private.gateway=10.147.29.1 -private.pod.startip=10.147.29.140 -private.pod.endip=10.147.29.149 -#public vlan range -public.gateway=10.147.31.1 -public.vlan=31 -public.vlan.startip=10.147.31.140 -public.vlan.endip=10.147.31.149 -#hosts -host=10.147.29.56 -#pools -pool=nfs://10.147.28.6:/export/home/prasanna/taxila -secondary=nfs://10.147.28.6:/export/home/prasanna/secondary diff --git a/tools/testClient/sandbox/basic/basic_env.py b/tools/testClient/sandbox/basic/basic_env.py deleted file mode 100644 index 6e5ef80180f..00000000000 --- a/tools/testClient/sandbox/basic/basic_env.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -''' -# Experimental state of scripts -# * Need to be reviewed -# * Only a sandbox -''' - -from ConfigParser import SafeConfigParser -from optparse import OptionParser -from configGenerator import * -import random - - -def getGlobalSettings(config): - for k, v in dict(config.items('globals')).iteritems(): - cfg = configuration() - cfg.name = k - cfg.value = v - yield cfg - - -def describeResources(config): - zs = cloudstackConfiguration() - - z = zone() - z.dns1 = config.get('environment', 'dns') - z.internaldns1 = config.get('environment', 'dns') - z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) - z.networktype = 'Basic' - z.domain = 'cloud.basic' - - sgprov = provider() #SecurityGroup Provider - sgprov.name = 'SecurityGroupProvider' - z.providers.append(sgprov) - - p = pod() - p.name = 'POD0' - p.gateway = config.get('cloudstack', 'private.gateway') - p.startip = config.get('cloudstack', 'private.pod.startip') - p.endip = config.get('cloudstack', 'private.pod.endip') - p.netmask = '255.255.255.0' - - v = iprange() - v.gateway = config.get('cloudstack', 'guest.gateway') - v.startip = config.get('cloudstack', 'guest.startip') - v.endip = config.get('cloudstack', 'guest.endip') - v.netmask = '255.255.255.0' - p.guestIpRanges.append(v) - - c = cluster() - c.clustername = 'C0' - c.hypervisor = config.get('environment', 'hypervisor') - c.clustertype = 'CloudManaged' - - h = host() - h.username = 'root' - h.password = 'password' - h.url = 'http://%s'%(config.get('cloudstack', 'host')) - c.hosts.append(h) - - ps = primaryStorage() - ps.name = 'PS0' - ps.url = config.get('cloudstack', 'pool') - c.primaryStorages.append(ps) - - p.clusters.append(c) - z.pods.append(p) - - secondary = secondaryStorage() - secondary.url = config.get('cloudstack', 'secondary') - z.secondaryStorages.append(secondary) - - '''Add zone''' - zs.zones.append(z) - - '''Add mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = config.get('environment', 'mshost') - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = config.get('environment', 'database') - zs.dbSvr = db - - '''Add some configuration''' - [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)] - - ''''add loggers''' - testClientLogger = logger() - testClientLogger.name = 'TestClient' - testClientLogger.file = '/var/log/testclient.log' - - testCaseLogger = logger() - testCaseLogger.name = 'TestCase' - testCaseLogger.file = '/var/log/testcase.log' - - zs.logger.append(testClientLogger) - zs.logger.append(testCaseLogger) - return zs - - -if __name__ == '__main__': - parser = OptionParser() - parser.add_option('-i', '--input', action='store', default='setup.properties', \ - dest='input', help='file containing environment setup information') - parser.add_option('-o', '--output', action='store', default='./sandbox.cfg', \ - dest='output', help='path where environment json will be generated') - - - (opts, args) = parser.parse_args() - - cfg_parser = SafeConfigParser() - cfg_parser.read(opts.input) - - cfg = describeResources(cfg_parser) - generate_setup_config(cfg, opts.output) diff --git a/tools/testClient/sandbox/basic/setup.properties b/tools/testClient/sandbox/basic/setup.properties deleted file mode 100644 index 11d20de9f53..00000000000 --- a/tools/testClient/sandbox/basic/setup.properties +++ /dev/null @@ -1,34 +0,0 @@ -[globals] -expunge.delay=60 -expunge.interval=60 -storage.cleanup.interval=300 -account.cleanup.interval=600 -expunge.workers=3 -workers=10 -vm.allocation.algorithm=userdispersing -vm.op.wait.interval=5 -guest.domain.suffix=sandbox.xen -instance.name=QA -direct.agent.load.size=1000 -default.page.size=10000 -check.pod.cidrs=true -secstorage.allowed.internal.sites=10.147.28.0/24 -[environment] -dns=10.147.28.6 -mshost=10.147.29.110 -database=10.147.29.110 -hypervisor=XenServer -[cloudstack] -#pod configuration -private.gateway=10.147.29.1 -private.pod.startip=10.147.29.150 -private.pod.endip=10.147.29.153 -#public/guest ip range -guest.gateway=10.147.29.1 -guest.startip=10.147.29.154 -guest.endip=10.147.29.159 -#hosts -host=10.147.29.56 -#pools -pool=nfs://10.147.28.6:/export/home/prasanna/taxila -secondary=nfs://10.147.28.6:/export/home/prasanna/secondary diff --git a/tools/testClient/sandbox/simulator/setup.py b/tools/testClient/sandbox/simulator/setup.py deleted file mode 100644 index c0b8c742441..00000000000 --- a/tools/testClient/sandbox/simulator/setup.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -''' -# Experimental state of scripts -# * Need to be reviewed -# * Only a sandbox -''' - -from ConfigParser import SafeConfigParser -from optparse import OptionParser -from configGenerator import * -import random - - -def getGlobalSettings(config): - for k, v in dict(config.items('globals')).iteritems(): - cfg = configuration() - cfg.name = k - cfg.value = v - yield cfg - - -def describeResources(config): - zs = cloudstackConfiguration() - - z = zone() - z.dns1 = config.get('environment', 'dns') - z.internaldns1 = config.get('environment', 'dns') - z.name = 'Sandbox-%s'%(config.get('environment', 'hypervisor')) - z.networktype = 'Advanced' - z.guestcidraddress = '10.1.1.0/24' - z.vlan = config.get('cloudstack','guest.vlan') - - p = pod() - p.name = 'POD0' - p.gateway = config.get('cloudstack', 'private.gateway') - p.startip = config.get('cloudstack', 'private.pod.startip') - p.endip = config.get('cloudstack', 'private.pod.endip') - p.netmask = '255.255.255.0' - - v = iprange() - v.gateway = config.get('cloudstack', 'public.gateway') - v.startip = config.get('cloudstack', 'public.vlan.startip') - v.endip = config.get('cloudstack', 'public.vlan.endip') - v.netmask = '255.255.255.0' - v.vlan = config.get('cloudstack', 'public.vlan') - z.ipranges.append(v) - - c = cluster() - c.clustername = 'C0' - c.hypervisor = config.get('environment', 'hypervisor') - c.clustertype = 'CloudManaged' - - h = host() - h.username = 'root' - h.password = 'password' - h.url = 'http://%s'%(config.get('cloudstack', 'host')) - c.hosts.append(h) - - ps = primaryStorage() - ps.name = 'PS0' - ps.url = config.get('cloudstack', 'pool') - c.primaryStorages.append(ps) - - p.clusters.append(c) - z.pods.append(p) - - secondary = secondaryStorage() - secondary.url = config.get('cloudstack', 'secondary') - z.secondaryStorages.append(secondary) - - '''Add zone''' - zs.zones.append(z) - - '''Add mgt server''' - mgt = managementServer() - mgt.mgtSvrIp = config.get('environment', 'mshost') - zs.mgtSvr.append(mgt) - - '''Add a database''' - db = dbServer() - db.dbSvr = config.get('environment', 'database') - zs.dbSvr = db - - '''Add some configuration''' - [zs.globalConfig.append(cfg) for cfg in getGlobalSettings(config)] - - ''''add loggers''' - testClientLogger = logger() - testClientLogger.name = 'TestClient' - testClientLogger.file = '/var/log/testclient.log' - - testCaseLogger = logger() - testCaseLogger.name = 'TestCase' - testCaseLogger.file = '/var/log/testcase.log' - - zs.logger.append(testClientLogger) - zs.logger.append(testCaseLogger) - return zs - - -if __name__ == '__main__': - parser = OptionParser() - parser.add_option('-i', '--input', action='store', default='setup.properties', \ - dest='input', help='file containing environment setup information') - parser.add_option('-o', '--output', action='store', default='./sandbox.cfg', \ - dest='output', help='path where environment json will be generated') - - - (opts, args) = parser.parse_args() - - cfg_parser = SafeConfigParser() - cfg_parser.read(opts.input) - - cfg = describeResources(cfg_parser) - generate_setup_config(cfg, opts.output) diff --git a/tools/testClient/sandbox/simulator/simulator.properties b/tools/testClient/sandbox/simulator/simulator.properties deleted file mode 100644 index c5c9bc50d82..00000000000 --- a/tools/testClient/sandbox/simulator/simulator.properties +++ /dev/null @@ -1,35 +0,0 @@ -[globals] -expunge.delay=60 -expunge.interval=60 -storage.cleanup.interval=300 -account.cleanup.interval=600 -expunge.workers=3 -workers=10 -vm.allocation.algorithm=userdispersing -vm.op.wait.interval=5 -guest.domain.suffix=sandbox.simulator -instance.name=QA -direct.agent.load.size=1000 -default.page.size=10000 -check.pod.cidrs=true -[environment] -dns=10.147.28.6 -mshost=localhost -database=localhost -hypervisor=simulator -[cloudstack] -guest.vlan=100-500 -#pod configuration -private.gateway=172.1.2.1 -private.pod.startip=172.1.2.2 -private.pod.endip=172.1.2.252 -#public vlan range -public.gateway=172.2.1.1 -public.vlan=30 -public.vlan.startip=172.2.1.2 -public.vlan.endip=172.2.1.252 -#hosts -host=sim -#pools -pool=nfs://172.2.2.6:/export/home/primary -secondary=nfs://172.2.2.6:/export/home/secondary diff --git a/tools/testClient/sandbox/simulator/tests/testProvision.py b/tools/testClient/sandbox/simulator/tests/testProvision.py deleted file mode 100644 index e90da34d0eb..00000000000 --- a/tools/testClient/sandbox/simulator/tests/testProvision.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import random -import hashlib -from cloudstackTestCase import * - -class Provision(cloudstackTestCase): - ''' - ''' - def setUp(self): - pass - - - def tearDown(self): - pass - - - def test_1_createAccounts(self, numberOfAccounts=5): - ''' - Create a bunch of user accounts - ''' - mdf = hashlib.md5() - mdf.update('password') - mdf_pass = mdf.hexdigest() - api = self.testClient.getApiClient() - for i in range(1, numberOfAccounts + 1): - acct = createAccount.createAccountCmd() - acct.accounttype = 0 - acct.firstname = 'user' + str(i) - acct.lastname = 'user' + str(i) - acct.password = mdf_pass - acct.username = 'user' + str(i) - acct.email = 'user@example.com' - acct.account = 'user' + str(i) - acct.domainid = 1 - acctResponse = api.createAccount(acct) - self.debug("successfully created account: %s, user: %s, id: %s"%(acctResponse.account, acctResponse.username, acctResponse.id)) - - - def test_2_createServiceOffering(self): - apiClient = self.testClient.getApiClient() - createSOcmd=createServiceOffering.createServiceOfferingCmd() - createSOcmd.name='Sample SO' - createSOcmd.displaytext='Sample SO' - createSOcmd.storagetype='shared' - createSOcmd.cpunumber=1 - createSOcmd.cpuspeed=100 - createSOcmd.memory=128 - createSOcmd.offerha='false' - createSOresponse = apiClient.createServiceOffering(createSOcmd) - return createSOresponse.id - - def deployCmd(self, account, service): - deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd() - deployVmCmd.zoneid = 1 - deployVmCmd.hypervisor='Simulator' - deployVmCmd.account=account - deployVmCmd.domainid=1 - deployVmCmd.templateid=10 - deployVmCmd.serviceofferingid=service - return deployVmCmd - - def listVmsInAccountCmd(self, acct): - api = self.testClient.getApiClient() - listVmCmd = listVirtualMachines.listVirtualMachinesCmd() - listVmCmd.account = acct - listVmCmd.zoneid = 1 - listVmCmd.domainid = 1 - listVmResponse = api.listVirtualMachines(listVmCmd) - return listVmResponse - - - def destroyVmCmd(self, key): - api = self.testClient.getApiClient() - destroyVmCmd = destroyVirtualMachine.destroyVirtualMachineCmd() - destroyVmCmd.id = key - api.destroyVirtualMachine(destroyVmCmd) - - - def test_3_stressDeploy(self): - ''' - Deploy 20 Vms in each account - ''' - service_id = self.test_2_createServiceOffering() - api = self.testClient.getApiClient() - for acct in range(1, 5): - [api.deployVirtualMachine(self.deployCmd('user'+str(acct), service_id)) for x in range(0,20)] - - def test_4_stressDestroy(self): - ''' - Cleanup all Vms in every account - ''' - api = self.testClient.getApiClient() - for acct in range(1, 6): - for vm in self.listVmsInAccountCmd('user'+str(acct)): - if vm is not None: - self.destroyVmCmd(vm.id) - - def test_5_combineStress(self): - for i in range(0, 5): - self.test_3_stressDeploy() - self.test_4_stressDestroy() - - def deployN(self,nargs=300,batchsize=0): - ''' - Deploy Nargs number of VMs concurrently in batches of size {batchsize}. - When batchsize is 0 all Vms are deployed in one batch - VMs will be deployed in 5:2:6 ratio - ''' - cmds = [] - - if batchsize == 0: - self.testClient.submitCmdsAndWait(cmds) - else: - while len(z) > 0: - try: - newbatch = [cmds.pop() for b in range(batchsize)] #pop batchsize items - self.testClient.submitCmdsAndWait(newbatch) - except IndexError: - break diff --git a/tools/testClient/testcase/BVT-tests/test_hosts.py b/tools/testClient/testcase/BVT-tests/test_hosts.py deleted file mode 100644 index 17ca71ec38d..00000000000 --- a/tools/testClient/testcase/BVT-tests/test_hosts.py +++ /dev/null @@ -1,223 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" BVT tests for Hosts and Clusters -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time - -class Services: - """Test Hosts & Clusters Services - """ - - def __init__(self): - self.services = { - "clusters": { - 0: { - "clustername": "Xen Cluster", - "clustertype": "CloudManaged", - # CloudManaged or ExternalManaged" - "hypervisor": "XenServer", - # Hypervisor type - }, - 1: { - "clustername": "KVM Cluster", - "clustertype": "CloudManaged", - # CloudManaged or ExternalManaged" - "hypervisor": "KVM", - # Hypervisor type - }, - 2: { - "hypervisor": 'VMware', - # Hypervisor type - "clustertype": 'ExternalManaged', - # CloudManaged or ExternalManaged" - "username": 'administrator', - "password": 'fr3sca', - "url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1', - # Format:http://vCenter Host/Datacenter/Cluster - "clustername": 'VMWare Cluster', - }, - }, - "hosts": { - "xenserver": { - # Must be name of corresponding Hypervisor type - # in cluster in small letters - "hypervisor": 'XenServer', - # Hypervisor type - "clustertype": 'CloudManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.211', - "username": "root", - "password": "fr3sca", - }, - "kvm": { - "hypervisor": 'KVM', - # Hypervisor type - "clustertype": 'CloudManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.212', - "username": "root", - "password": "fr3sca", - }, - "vmware": { - "hypervisor": 'VMware', - # Hypervisor type - "clustertype": 'ExternalManaged', - # CloudManaged or ExternalManaged" - "url": 'http://192.168.100.203', - "username": "administrator", - "password": "fr3sca", - }, - }, - } - -class TestHosts(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.services = Services().services - self.zone = get_zone(self.apiclient, self.services) - self.pod = get_pod(self.apiclient, self.zone.id, self.services) - self.cleanup = [] - - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_clusters(self): - """Test Add clusters & hosts - XEN, KVM, VWARE - """ - - # Validate the following: - # 1. Verify hypervisortype returned by API is Xen/KVM/VWare - # 2. Verify that the cluster is in 'Enabled' allocation state - # 3. Verify that the host is added successfully and in Up state - # with listHosts API response - - #Create clusters with Hypervisor type XEN/KVM/VWare - for k, v in self.services["clusters"].items(): - cluster = Cluster.create( - self.apiclient, - v, - zoneid=self.zone.id, - podid=self.pod.id - ) - self.debug( - "Created Cluster for hypervisor type %s & ID: %s" %( - v["hypervisor"], - cluster.id - )) - self.assertEqual( - cluster.hypervisortype, - v["hypervisor"], - "Check hypervisor type is " + v["hypervisor"] + " or not" - ) - self.assertEqual( - cluster.allocationstate, - 'Enabled', - "Check whether allocation state of cluster is enabled" - ) - - #If host is externally managed host is already added with cluster - response = list_hosts( - self.apiclient, - clusterid=cluster.id - ) - - if not response: - hypervisor_type = str(cluster.hypervisortype.lower()) - host = Host.create( - self.apiclient, - cluster, - self.services["hosts"][hypervisor_type], - zoneid=self.zone.id, - podid=self.pod.id - ) - self.debug( - "Created host (ID: %s) in cluster ID %s" %( - host.id, - cluster.id - )) - - #Cleanup Host & Cluster - self.cleanup.append(host) - self.cleanup.append(cluster) - - list_hosts_response = list_hosts( - self.apiclient, - clusterid=cluster.id - ) - self.assertEqual( - isinstance(list_hosts_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_hosts_response), - 0, - "Check list Hosts response" - ) - - host_response = list_hosts_response[0] - #Check if host is Up and running - self.assertEqual( - host_response.state, - 'Up', - "Check if state of host is Up or not" - ) - #Verify List Cluster Response has newly added cluster - list_cluster_response = list_clusters( - self.apiclient, - id=cluster.id - ) - self.assertEqual( - isinstance(list_cluster_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_cluster_response), - 0, - "Check list Hosts response" - ) - - cluster_response = list_cluster_response[0] - self.assertEqual( - cluster_response.id, - cluster.id, - "Check cluster ID with list clusters response" - ) - self.assertEqual( - cluster_response.hypervisortype, - cluster.hypervisortype, - "Check hypervisor type with is " + v["hypervisor"] + " or not" - ) - return \ No newline at end of file diff --git a/tools/testClient/testcase/BVT-tests/test_iso.py b/tools/testClient/testcase/BVT-tests/test_iso.py deleted file mode 100644 index b758e78af1b..00000000000 --- a/tools/testClient/testcase/BVT-tests/test_iso.py +++ /dev/null @@ -1,499 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" BVT tests for Templates ISO -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import urllib -from random import random -#Import System modules -import time - - -class Services: - """Test ISO Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "fr3sca", - }, - "iso_1": - { - "displaytext": "Test ISO 1", - "name": "ISO 1", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - }, - "iso_2": - { - "displaytext": "Test ISO 2", - "name": "ISO 2", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "mode": 'HTTP_DOWNLOAD', - # Used in Extract template, value must be HTTP_DOWNLOAD - }, - "destzoneid": 5, - # Copy ISO from one zone to another (Destination Zone) - "isfeatured": True, - "ispublic": True, - "isextractable": True, - "bootable": True, # For edit template - "passwordenabled": True, - "sleep": 60, - "timeout": 10, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - # CentOS 5.3 (64 bit) - "mode": 'advanced' - # Networking mode: Basic or Advanced - } - - -class TestCreateIso(cloudstackTestCase): - - def setUp(self): - self.services = Services().services - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) - self.services["domainid"] = self.domain.id - self.services["iso_2"]["zoneid"] = self.zone.id - - self.account = Account.create( - self.apiclient, - self.services["account"], - domainid=self.domain.id - ) - - self.cleanup = [self.account] - return - - def tearDown(self): - try: - - self.dbclient.close() - #Clean up, terminate the created ISOs - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_create_iso(self): - """Test create public & private ISO - """ - - # Validate the following: - # 1. database (vm_template table) should be - # updated with newly created ISO - # 2. UI should show the newly added ISO - # 3. listIsos API should show the newly added ISO - - iso = Iso.create( - self.apiclient, - self.services["iso_2"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("ISO created with ID: %s" % iso.id) - - try: - iso.download(self.apiclient) - except Exception as e: - self.fail("Exception while downloading ISO %s: %s"\ - % (iso.id, e)) - - list_iso_response = list_isos( - self.apiclient, - id=iso.id - ) - self.assertEqual( - isinstance(list_iso_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_iso_response), - 0, - "Check template available in List ISOs" - ) - iso_response = list_iso_response[0] - - self.assertEqual( - iso_response.displaytext, - self.services["iso_2"]["displaytext"], - "Check display text of newly created ISO" - ) - self.assertEqual( - iso_response.name, - self.services["iso_2"]["name"], - "Check name of newly created ISO" - ) - self.assertEqual( - iso_response.zoneid, - self.services["iso_2"]["zoneid"], - "Check zone ID of newly created ISO" - ) - return - - -class TestISO(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - cls.services["domainid"] = cls.domain.id - cls.services["iso_1"]["zoneid"] = cls.zone.id - cls.services["iso_2"]["zoneid"] = cls.zone.id - cls.services["sourcezoneid"] = cls.zone.id - - #Create an account, ISOs etc. - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls.iso_1 = Iso.create( - cls.api_client, - cls.services["iso_1"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - try: - cls.iso_1.download(cls.api_client) - except Exception as e: - raise Exception("Exception while downloading ISO %s: %s"\ - % (cls.iso_1.id, e)) - - cls.iso_2 = Iso.create( - cls.api_client, - cls.services["iso_2"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - try: - cls.iso_2.download(cls.api_client) - except Exception as e: - raise Exception("Exception while downloading ISO %s: %s"\ - % (cls.iso_2.id, e)) - - cls._cleanup = [cls.account] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient() - #Clean up, terminate the created templates - 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 = [] - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created ISOs, VMs - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_02_edit_iso(self): - """Test Edit ISO - """ - - # Validate the following: - # 1. UI should show the edited values for ISO - # 2. database (vm_template table) should have updated values - - #Generate random values for updating ISO name and Display text - new_displayText = random_gen() - new_name = random_gen() - - self.debug("Updating ISO permissions for ISO: %s" % self.iso_1.id) - - cmd = updateIso.updateIsoCmd() - #Assign new values to attributes - cmd.id = self.iso_1.id - cmd.displaytext = new_displayText - cmd.name = new_name - cmd.bootable = self.services["bootable"] - cmd.passwordenabled = self.services["passwordenabled"] - - self.apiclient.updateIso(cmd) - - #Check whether attributes are updated in ISO using listIsos - list_iso_response = list_isos( - self.apiclient, - id=self.iso_1.id - ) - self.assertEqual( - isinstance(list_iso_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_iso_response), - 0, - "Check template available in List ISOs" - ) - - iso_response = list_iso_response[0] - self.assertEqual( - iso_response.displaytext, - new_displayText, - "Check display text of updated ISO" - ) - self.assertEqual( - iso_response.name, - new_name, - "Check name of updated ISO" - ) - self.assertEqual( - iso_response.bootable, - self.services["bootable"], - "Check if image is bootable of updated ISO" - ) - - self.assertEqual( - iso_response.ostypeid, - self.services["ostypeid"], - "Check OSTypeID of updated ISO" - ) - return - - def test_03_delete_iso(self): - """Test delete ISO - """ - - # Validate the following: - # 1. UI should not show the deleted ISP - # 2. database (vm_template table) should not contain deleted ISO - - self.debug("Deleting ISO with ID: %s" % self.iso_1.id) - self.iso_1.delete(self.apiclient) - - # Sleep to ensure that ISO state is reflected in other calls - time.sleep(self.services["sleep"]) - - #ListIsos to verify deleted ISO is properly deleted - list_iso_response = list_isos( - self.apiclient, - id=self.iso_1.id - ) - - self.assertEqual( - list_iso_response, - None, - "Check if ISO exists in ListIsos" - ) - return - - def test_04_extract_Iso(self): - "Test for extract ISO" - - # Validate the following - # 1. Admin should able extract and download the ISO - # 2. ListIsos should display all the public templates - # for all kind of users - # 3 .ListIsos should not display the system templates - - self.debug("Extracting ISO with ID: %s" % self.iso_2.id) - - cmd = extractIso.extractIsoCmd() - cmd.id = self.iso_2.id - cmd.mode = self.services["iso_2"]["mode"] - cmd.zoneid = self.services["iso_2"]["zoneid"] - list_extract_response = self.apiclient.extractIso(cmd) - - try: - #Format URL to ASCII to retrieve response code - formatted_url = urllib.unquote_plus(list_extract_response.url) - url_response = urllib.urlopen(formatted_url) - response_code = url_response.getcode() - except Exception: - self.fail( - "Extract ISO Failed with invalid URL %s (ISO id: %s)" \ - % (formatted_url, self.iso_2.id) - ) - - self.assertEqual( - list_extract_response.id, - self.iso_2.id, - "Check ID of the downloaded ISO" - ) - self.assertEqual( - list_extract_response.extractMode, - self.services["iso_2"]["mode"], - "Check mode of extraction" - ) - self.assertEqual( - list_extract_response.zoneid, - self.services["iso_2"]["zoneid"], - "Check zone ID of extraction" - ) - self.assertEqual( - response_code, - 200, - "Check for a valid response of download URL" - ) - return - - def test_05_iso_permissions(self): - """Update & Test for ISO permissions""" - - # validate the following - # 1. listIsos returns valid permissions set for ISO - # 2. permission changes should be reflected in vm_template - # table in database - - self.debug("Updating permissions for ISO: %s" % self.iso_2.id) - - cmd = updateIsoPermissions.updateIsoPermissionsCmd() - cmd.id = self.iso_2.id - #Update ISO permissions - cmd.isfeatured = self.services["isfeatured"] - cmd.ispublic = self.services["ispublic"] - cmd.isextractable = self.services["isextractable"] - self.apiclient.updateIsoPermissions(cmd) - - #Verify ListIsos have updated permissions for the ISO for normal user - list_iso_response = list_isos( - self.apiclient, - id=self.iso_2.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(list_iso_response, list), - True, - "Check list response returns a valid list" - ) - - iso_response = list_iso_response[0] - - self.assertEqual( - iso_response.id, - self.iso_2.id, - "Check ISO ID" - ) - self.assertEqual( - iso_response.ispublic, - self.services["ispublic"], - "Check ispublic permission of ISO" - ) - - self.assertEqual( - iso_response.isfeatured, - self.services["isfeatured"], - "Check isfeatured permission of ISO" - ) - return - - def test_06_copy_iso(self): - """Test for copy ISO from one zone to another""" - - #Validate the following - #1. copy ISO should be successful and secondary storage - # should contain new copied ISO. - - self.debug("Copy ISO from %s to %s" % ( - self.zone.id, - self.services["destzoneid"] - )) - - cmd = copyIso.copyIsoCmd() - cmd.id = self.iso_2.id - cmd.destzoneid = self.services["destzoneid"] - cmd.sourcezoneid = self.zone.id - self.apiclient.copyIso(cmd) - - #Verify ISO is copied to another zone using ListIsos - list_iso_response = list_isos( - self.apiclient, - id=self.iso_2.id, - zoneid=self.services["destzoneid"] - ) - self.assertEqual( - isinstance(list_iso_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_iso_response), - 0, - "Check template extracted in List ISO" - ) - iso_response = list_iso_response[0] - - self.assertEqual( - iso_response.id, - self.iso_2.id, - "Check ID of the downloaded ISO" - ) - self.assertEqual( - iso_response.zoneid, - self.services["destzoneid"], - "Check zone ID of the copied ISO" - ) - - self.debug("Cleanup copied ISO: %s" % iso_response.id) - # Cleanup- Delete the copied ISO - cmd = deleteIso.deleteIsoCmd() - cmd.id = iso_response.id - cmd.zoneid = self.services["destzoneid"] - self.apiclient.deleteIso(cmd) - return diff --git a/tools/testClient/testcase/BVT-tests/test_primary_storage.py b/tools/testClient/testcase/BVT-tests/test_primary_storage.py deleted file mode 100644 index 3018e3940c8..00000000000 --- a/tools/testClient/testcase/BVT-tests/test_primary_storage.py +++ /dev/null @@ -1,237 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" BVT tests for Primary Storage -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time - -class Services: - """Test Primary storage Services - """ - - def __init__(self): - self.services = { - "nfs": { - 0: { - "url": "nfs://192.168.100.131/testprimary", - # Format: File_System_Type/Location/Path - "name": "Primary XEN", - "hypervisor": 'XEN', - }, - 1: { - "url": "nfs://192.168.100.131/Primary", - "name": "Primary KVM", - "hypervisor": 'KVM', - }, - 2: { - "url": "nfs://192.168.100.131/Primary", - "name": "Primary VMWare", - "hypervisor": 'VMWare', - }, - }, - "iscsi": { - 0: { - "url": "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1", - # Format : iscsi://IP Address/IQN number/LUN# - "name": "Primary iSCSI", - "hypervisor": 'XEN', - }, - }, - } - -class TestPrimaryStorageServices(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.services = Services().services - self.cleanup = [] - # Get Zone and pod - self.zone = get_zone(self.apiclient, self.services) - self.pod = get_pod(self.apiclient, self.zone.id) - - return - - def tearDown(self): - try: - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_primary_storage(self): - """Test primary storage pools - XEN, KVM, VMWare - """ - - # Validate the following: - # 1. verify hypervisortype returned by api is Xen/KVM/VMWare - # 2. verify that the cluster is in 'Enabled' allocation state - # 3. verify that the host is added successfully and - # in Up state with listHosts api response - - #Create NFS storage pools with on XEN/KVM/VMWare clusters - for k, v in self.services["nfs"].items(): - - clusters = list_clusters( - self.apiclient, - zoneid=self.zone.id, - hypervisortype=v["hypervisor"] - ) - self.assertEqual( - isinstance(clusters, list), - True, - "Check list response returns a valid list" - ) - cluster = clusters[0] - #Host should be present before adding primary storage - list_hosts_response = list_hosts( - self.apiclient, - clusterid=cluster.id - ) - self.assertEqual( - isinstance(list_hosts_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_hosts_response), - 0, - "Check list Hosts for hypervisor: " + v["hypervisor"] - ) - - storage = StoragePool.create(self.apiclient, - v, - clusterid=cluster.id, - zoneid=self.zone.id, - podid=self.pod.id - ) - self.cleanup.append(storage) - - self.debug("Created storage pool in cluster: %s" % cluster.id) - - self.assertEqual( - storage.state, - 'Up', - "Check primary storage state for hypervisor: " + v["hypervisor"] - ) - - self.assertEqual( - storage.type, - 'NetworkFilesystem', - "Check storage pool type for hypervisor : " + v["hypervisor"] - ) - - #Verify List Storage pool Response has newly added storage pool - storage_pools_response = list_storage_pools( - self.apiclient, - id=storage.id, - ) - self.assertEqual( - isinstance(storage_pools_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(storage_pools_response), - 0, - "Check list Hosts response" - ) - - storage_response = storage_pools_response[0] - self.assertEqual( - storage_response.id, - storage.id, - "Check storage pool ID for hypervisor: " + v["hypervisor"] - ) - self.assertEqual( - storage.type, - storage_response.type, - "Check storage pool type for hypervisor: " + v["hypervisor"] - ) - # Call cleanup for reusing primary storage - cleanup_resources(self.apiclient, self.cleanup) - self.cleanup = [] - - # Create iSCSI storage pools with on XEN/KVM clusters - for k, v in self.services["iscsi"].items(): - clusters = list_clusters( - self.apiclient, - zoneid=self.zone.id, - hypervisortype=v["hypervisor"] - ) - self.assertEqual( - isinstance(clusters, list), - True, - "Check list response returns a valid list" - ) - cluster = clusters[0] - - storage = StoragePool.create(self.apiclient, - v, - clusterid=cluster.id, - zoneid=self.zone.id, - podid=self.pod.id - ) - self.cleanup.append(storage) - - self.debug("Created iSCSI storage pool in cluster: %s" % cluster.id) - - self.assertEqual( - storage.state, - 'Up', - "Check primary storage state for hypervisor: " + v["hypervisor"] - ) - - #Verify List Storage pool Response has newly added storage pool - storage_pools_response = list_storage_pools( - self.apiclient, - id=storage.id, - ) - self.assertEqual( - isinstance(storage_pools_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(storage_pools_response), - 0, - "Check Hosts response for hypervisor: " + v["hypervisor"] - ) - - storage_response = storage_pools_response[0] - self.assertEqual( - storage_response.id, - storage.id, - "Check storage pool ID for hypervisor: " + v["hypervisor"] - ) - self.assertEqual( - storage.type, - storage_response.type, - "Check storage pool type hypervisor: " + v["hypervisor"] - ) - - # Call cleanup for reusing primary storage - cleanup_resources(self.apiclient, self.cleanup) - self.cleanup = [] - return \ No newline at end of file diff --git a/tools/testClient/testcase/BVT-tests/test_secondary_storage.py b/tools/testClient/testcase/BVT-tests/test_secondary_storage.py deleted file mode 100644 index bb5ea22c1fb..00000000000 --- a/tools/testClient/testcase/BVT-tests/test_secondary_storage.py +++ /dev/null @@ -1,379 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" BVT tests for Secondary Storage -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time - -class Services: - """Test secondary storage Services - """ - - def __init__(self): - self.services = { - "storage": { - "url": "nfs://192.168.100.131/SecStorage" - # Format: File_System_Type/Location/Path - }, - "hypervisors": { - 0: { - "hypervisor": "XenServer", - "templatefilter": "self", - }, - 1: { - "hypervisor": "KVM", - "templatefilter": "self", - }, - 2: { - "hypervisor": "VMWare", - "templatefilter": "self", - }, - }, - "sleep": 60, - "timeout": 5, - } - -class TestSecStorageServices(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSecStorageServices, cls).getClsTestClient().getApiClient() - cls.services = Services().services - cls._cleanup = [] - 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.cleanup = [] - self.services = Services().services - # Get Zone and pod - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) - self.pod = get_pod(self.apiclient, self.zone.id) - return - - def tearDown(self): - try: - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_add_sec_storage(self): - """Test secondary storage - """ - - # Validate the following: - # 1. secondary storage should be added to the zone. - # 2. Verify with listHosts and type secondarystorage - - cmd = addSecondaryStorage.addSecondaryStorageCmd() - cmd.zoneid = self.zone.id - cmd.url = self.services["storage"]["url"] - sec_storage = self.apiclient.addSecondaryStorage(cmd) - - self.debug("Added secondary storage to zone: %s" % self.zone.id) - # Cleanup at the end - self._cleanup.append(sec_storage) - - self.assertEqual( - sec_storage.zoneid, - self.zone.id, - "Check zoneid where sec storage is added" - ) - - list_hosts_response = list_hosts( - self.apiclient, - type='SecondaryStorage', - id=sec_storage.id - ) - self.assertEqual( - isinstance(list_hosts_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_hosts_response), - 0, - "Check list Hosts response" - ) - - host_response = list_hosts_response[0] - #Check if host is Up and running - self.assertEqual( - host_response.id, - sec_storage.id, - "Check ID of secondary storage" - ) - self.assertEqual( - sec_storage.type, - host_response.type, - "Check type of host from list hosts response" - ) - return - - def test_02_sys_vm_start(self): - """Test system VM start - """ - - # 1. verify listHosts has all 'routing' hosts in UP state - # 2. verify listStoragePools shows all primary storage pools - # in UP state - # 3. verify that secondary storage was added successfully - - list_hosts_response = list_hosts( - self.apiclient, - type='Routing', - zoneid=self.zone.id, - podid=self.pod.id - ) - self.assertEqual( - isinstance(list_hosts_response, list), - True, - "Check list response returns a valid list" - ) - # ListHosts has all 'routing' hosts in UP state - self.assertNotEqual( - len(list_hosts_response), - 0, - "Check list host response" - ) - for host in list_hosts_response: - self.assertEqual( - host.state, - 'Up', - "Check state of routing hosts is Up or not" - ) - - # ListStoragePools shows all primary storage pools in UP state - list_storage_response = list_storage_pools( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id - ) - self.assertEqual( - isinstance(list_storage_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_storage_response), - 0, - "Check list storage pools response" - ) - - for primary_storage in list_hosts_response: - self.assertEqual( - primary_storage.state, - 'Up', - "Check state of primary storage pools is Up or not" - ) - - # Secondary storage is added successfully - timeout = self.services["timeout"] - while True: - list_hosts_response = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id, - ) - - if not isinstance(list_hosts_response, list): - # Sleep to ensure Secondary storage is Up - time.sleep(int(self.services["sleep"])) - timeout = timeout - 1 - elif timeout == 0 or isinstance(list_hosts_response, list): - break - - self.assertEqual( - isinstance(list_hosts_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_hosts_response), - 0, - "Check list Hosts response" - ) - - host_response = list_hosts_response[0] - #Check if host is Up and running - self.assertEqual( - host_response.state, - 'Up', - "Check state of secondary storage" - ) - self.debug("Checking SSVM status in zone: %s" % self.zone.id) - - timeout = self.services["timeout"] - - while True: - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - zoneid=self.zone.id, - podid=self.pod.id - ) - if not isinstance(list_ssvm_response, list): - # Sleep to ensure SSVMs are Up and Running - time.sleep(int(self.services["sleep"])) - timeout = timeout - 1 - elif timeout == 0 or isinstance(list_ssvm_response, list): - break - - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - #Verify SSVM response - self.assertNotEqual( - len(list_ssvm_response), - 0, - "Check list System VMs response" - ) - - for ssvm in list_ssvm_response: - self.assertEqual( - ssvm.state, - 'Running', - "Check whether state of SSVM is running" - ) - return - - def test_03_sys_template_ready(self): - """Test system templates are ready - """ - - # Validate the following - # If SSVM is in UP state and running - # 1. wait for listTemplates to show all builtin templates - # downloaded for all added hypervisors and in “Ready” state" - - for k, v in self.services["hypervisors"].items(): - - self.debug("Downloading BUILTIN templates in zone: %s" % - self.zone.id) - - list_template_response = list_templates( - self.apiclient, - hypervisor=v["hypervisor"], - zoneid=self.zone.id, - templatefilter=v["templatefilter"], - listall=True, - account='system', - domainid=self.domain.id - ) - - # Ensure all BUILTIN templates are downloaded - templateid = None - for template in list_template_response: - if template.templatetype == "BUILTIN": - templateid = template.id - - # Wait to start a downloading of template - time.sleep(self.services["sleep"]) - - while True and (templateid != None): - - timeout = self.services["timeout"] - while True: - template_response = list_templates( - self.apiclient, - id=templateid, - zoneid=self.zone.id, - templatefilter=v["templatefilter"], - listall=True, - account='system', - domainid=self.domain.id - ) - - if isinstance(template_response, list): - template = template_response[0] - break - - elif timeout == 0: - raise Exception("List template API call failed.") - - time.sleep(1) - timeout = timeout - 1 - - # If template is ready, - # template.status = Download Complete - # Downloading - x% Downloaded - # Error - Any other string - if template.status == 'Download Complete' : - break - elif 'Downloaded' not in template.status.split(): - raise Exception - elif 'Downloaded' in template.status.split(): - time.sleep(self.services["sleep"]) - - #Ensuring the template is in ready state - time.sleep(self.services["sleep"]) - - timeout = self.services["timeout"] - while True: - template_response = list_templates( - self.apiclient, - id=templateid, - zoneid=self.zone.id, - templatefilter=v["templatefilter"], - listall=True, - account='system', - domainid=self.domain.id - ) - - if isinstance(template_response, list): - template = template_response[0] - break - - elif timeout == 0: - raise Exception("List template API call failed.") - - time.sleep(1) - timeout = timeout - 1 - - self.assertEqual( - isinstance(template_response, list), - True, - "Check list response returns a valid list" - ) - template = template_response[0] - - self.assertEqual( - template.isready, - True, - "Check whether state of template is ready or not" - ) - return \ No newline at end of file diff --git a/tools/testClient/testcase/BVT-tests/test_templates.py b/tools/testClient/testcase/BVT-tests/test_templates.py deleted file mode 100644 index 451b13ab6e6..00000000000 --- a/tools/testClient/testcase/BVT-tests/test_templates.py +++ /dev/null @@ -1,752 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" BVT tests for Templates ISO -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import urllib -from random import random -#Import System modules -import datetime - - -class Services: - """Test Templates Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "virtual_machine": { - "displayname": "testVM", - "hypervisor": 'XenServer', - "protocol": 'TCP', - "ssh_port": 22, - "username": "root", - "password": "password", - "privateport": 22, - "publicport": 22, - }, - "volume": { - "diskname": "Test Volume", - }, - "template_1": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - }, - "template_2": { - "displaytext": "Public Template", - "name": "Public template", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "isfeatured": True, - "ispublic": True, - "isextractable": True, - "mode": "HTTP_DOWNLOAD", - }, - "templatefilter": 'self', - "destzoneid": 5, - # For Copy template (Destination zone) - "isfeatured": True, - "ispublic": True, - "isextractable": False, - "bootable": True, - "passwordenabled": True, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "mode": 'advanced', - # Networking mode: Advanced, basic - "sleep": 30, - "timeout": 10, - } - - -class TestCreateTemplate(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["diskoffering"] = cls.disk_offering.id - cls.services["volume"]["zoneid"] = cls.zone.id - cls.services["sourcezoneid"] = cls.zone.id - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: - raise Exception( - "Failed to stop VM (ID: %s) in change service offering" % - vm.id) - - timeout = timeout - 1 - - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - - cls.volume = list_volume[0] - cls._cleanup = [ - cls.account, - cls.service_offering, - cls.disk_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_create_template(self): - """Test create public & private template - """ - - # Validate the following: - # 1. database (vm_template table) should be updated - # with newly created template - # 2. UI should show the newly added template - # 3. ListTemplates API should show the newly added template - - #Create template from Virtual machine and Volume ID - template = Template.create( - self.apiclient, - self.services["template_1"], - self.volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.cleanup.append(template) - - self.debug("Created template with ID: %s" % template.id) - - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=template.id - ) - - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - #Verify template response to check whether template added successfully - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - template_response = list_template_response[0] - - self.assertEqual( - template_response.displaytext, - self.services["template_1"]["displaytext"], - "Check display text of newly created template" - ) - name = template_response.name - self.assertEqual( - name.count(self.services["template_1"]["name"]), - 1, - "Check name of newly created template" - ) - self.assertEqual( - template_response.ostypeid, - self.services["template_1"]["ostypeid"], - "Check osTypeID of newly created template" - ) - return - - -class TestTemplates(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["diskoffering"] = cls.disk_offering.id - cls.services["volume"]["zoneid"] = cls.zone.id - cls.services["template_2"]["zoneid"] = cls.zone.id - cls.services["sourcezoneid"] = cls.zone.id - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - # Poll listVM to ensure VM is stopped properly - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - - # Ensure that VM is in stopped state - list_vm_response = list_virtual_machines( - cls.api_client, - id=cls.virtual_machine.id - ) - - if isinstance(list_vm_response, list): - - vm = list_vm_response[0] - if vm.state == 'Stopped': - break - - if timeout == 0: - raise Exception( - "Failed to stop VM (ID: %s) in change service offering" % - vm.id) - - timeout = timeout - 1 - - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - try: - cls.volume = list_volume[0] - except Exception as e: - raise Exception( - "Exception: Unable to find root volume foe VM: %s" % - cls.virtual_machine.id) - - #Create templates for Edit, Delete & update permissions testcases - cls.template_1 = Template.create( - cls.api_client, - cls.services["template_1"], - cls.volume.id, - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.template_2 = Template.create( - cls.api_client, - cls.services["template_2"], - cls.volume.id, - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account, - cls.user - ] - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - #Cleanup created resources such as templates and VMs - 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: - - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_02_edit_template(self): - """Test Edit template - """ - - # Validate the following: - # 1. UI should show the edited values for template - # 2. database (vm_template table) should have updated values - - new_displayText = random_gen() - new_name = random_gen() - - cmd = updateTemplate.updateTemplateCmd() - # Update template attributes - cmd.id = self.template_1.id - cmd.displaytext = new_displayText - cmd.name = new_name - cmd.bootable = self.services["bootable"] - cmd.passwordenabled = self.services["passwordenabled"] - - self.apiclient.updateTemplate(cmd) - - self.debug("Edited template with new name: %s" % new_name) - - # Sleep to ensure update reflected across all the calls - time.sleep(self.services["sleep"]) - - timeout = self.services["timeout"] - while True: - # Verify template response for updated attributes - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=self.template_1.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - if isinstance(list_template_response, list): - break - elif timeout == 0: - raise Exception("List Template failed!") - - time.sleep(10) - timeout = timeout -1 - - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - template_response = list_template_response[0] - - self.debug("New Name: %s" % new_displayText) - self.debug("Name in Template response: %s" - % template_response.displaytext) - self.assertEqual( - template_response.displaytext, - new_displayText, - "Check display text of updated template" - ) - self.assertEqual( - template_response.name, - new_name, - "Check name of updated template" - ) - self.assertEqual( - str(template_response.passwordenabled).lower(), - str(self.services["passwordenabled"]).lower(), - "Check passwordenabled field of updated template" - ) - self.assertEqual( - template_response.ostypeid, - self.services["ostypeid"], - "Check OSTypeID of updated template" - ) - return - - def test_03_delete_template(self): - """Test delete template - """ - - # Validate the following: - # 1. UI should not show the deleted template - # 2. database (vm_template table) should not contain deleted template - - self.debug("Deleting Template ID: %s" % self.template_1.id) - - self.template_1.delete(self.apiclient) - - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=self.template_1.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Verify template is deleted properly using ListTemplates - self.assertEqual( - list_template_response, - None, - "Check if template exists in List Templates" - ) - return - - def test_04_extract_template(self): - "Test for extract template" - - # Validate the following - # 1. Admin should able extract and download the templates - # 2. ListTemplates should display all the public templates - # for all kind of users - # 3 .ListTemplates should not display the system templates - - self.debug("Extracting template with ID: %s" % self.template_2.id) - - cmd = extractTemplate.extractTemplateCmd() - cmd.id = self.template_2.id - cmd.mode = self.services["template_2"]["mode"] - cmd.zoneid = self.zone.id - list_extract_response = self.apiclient.extractTemplate(cmd) - - try: - # Format URL to ASCII to retrieve response code - formatted_url = urllib.unquote_plus(list_extract_response.url) - url_response = urllib.urlopen(formatted_url) - response_code = url_response.getcode() - - except Exception: - self.fail( - "Extract Template Failed with invalid URL %s (template id: %s)" \ - % (formatted_url, self.template_2.id) - ) - self.assertEqual( - list_extract_response.id, - self.template_2.id, - "Check ID of the extracted template" - ) - self.assertEqual( - list_extract_response.extractMode, - self.services["template_2"]["mode"], - "Check mode of extraction" - ) - self.assertEqual( - list_extract_response.zoneid, - self.services["template_2"]["zoneid"], - "Check zone ID of extraction" - ) - self.assertEqual( - response_code, - 200, - "Check for a valid response download URL" - ) - return - - def test_05_template_permissions(self): - """Update & Test for template permissions""" - - # Validate the following - # 1. listTemplatePermissions returns valid - # permissions set for template - # 2. permission changes should be reflected in vm_template - # table in database - - self.debug("Updating Template permissions ID:%s" % self.template_2.id) - - cmd = updateTemplatePermissions.updateTemplatePermissionsCmd() - # Update template permissions - cmd.id = self.template_2.id - cmd.isfeatured = self.services["isfeatured"] - cmd.ispublic = self.services["ispublic"] - cmd.isextractable = self.services["isextractable"] - self.apiclient.updateTemplatePermissions(cmd) - - list_template_response = list_templates( - self.apiclient, - templatefilter='featured', - id=self.template_2.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - # Verify template response for updated permissions for normal user - template_response = list_template_response[0] - - self.assertEqual( - template_response.id, - self.template_2.id, - "Check template ID" - ) - self.assertEqual( - template_response.ispublic, - int(True), - "Check ispublic permission of template" - ) - - self.assertNotEqual( - template_response.templatetype, - 'SYSTEM', - "ListTemplates should not list any system templates" - ) - return - - def test_06_copy_template(self): - """Test for copy template from one zone to another""" - - # Validate the following - # 1. copy template should be successful and - # secondary storage should contain new copied template. - - self.debug("Copy template from Zone: %s to %s" % ( - self.services["sourcezoneid"], - self.services["destzoneid"] - )) - cmd = copyTemplate.copyTemplateCmd() - cmd.id = self.template_2.id - cmd.destzoneid = self.services["destzoneid"] - cmd.sourcezoneid = self.services["sourcezoneid"] - self.apiclient.copyTemplate(cmd) - - # Verify template is copied to another zone using ListTemplates - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=self.template_2.id, - zoneid=self.services["destzoneid"] - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_template_response), - 0, - "Check template extracted in List Templates" - ) - - template_response = list_template_response[0] - self.assertEqual( - template_response.id, - self.template_2.id, - "Check ID of the downloaded template" - ) - self.assertEqual( - template_response.zoneid, - self.services["destzoneid"], - "Check zone ID of the copied template" - ) - - # Cleanup- Delete the copied template - cmd = deleteTemplate.deleteTemplateCmd() - cmd.id = template_response.id - cmd.zoneid = self.services["destzoneid"] - self.apiclient.deleteTemplate(cmd) - return - - def test_07_list_public_templates(self): - """Test only public templates are visible to normal user""" - - # Validate the following - # 1. ListTemplates should show only 'public' templates for normal user - - list_template_response = list_templates( - self.apiclient, - templatefilter='featured', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - #Template response should list all 'public' templates - for template in list_template_response: - self.assertEqual( - template.ispublic, - True, - "ListTemplates should list only public templates" - ) - return - - def test_08_list_system_templates(self): - """Test System templates are not visible to normal user""" - - # Validate the following - # 1. ListTemplates should not show 'SYSTEM' templates for normal user - - list_template_response = list_templates( - self.apiclient, - templatefilter='featured', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - - for template in list_template_response: - self.assertNotEqual( - template.templatetype, - 'SYSTEM', - "ListTemplates should not list any system templates" - ) - return diff --git a/tools/testClient/testcase/P1-tests/README b/tools/testClient/testcase/P1-tests/README deleted file mode 100644 index 2fd8d4be795..00000000000 --- a/tools/testClient/testcase/P1-tests/README +++ /dev/null @@ -1,41 +0,0 @@ -P1 Cases --------------------------------------- -These test cases are the core functionality tests that ensure the application is stable and can be tested thoroughly. -These P1 cases definitions are located at : https://docs.google.com/a/clogeny.com/spreadsheet/ccc?key=0Aq5M2ldK6eyedDJBa0EzM0RPNmdVNVZOWnFnOVJJcHc&hl=en_US - - -Guidelines ----------- -P1 test cases are being developed using Python's unittests2. Following are certain guidelines being followed - 1. Tests exercised for the same resource should ideally be present under a single suite or file. - - 2. Time-consuming operations that create new cloud resources like server creation, volume creation etc - should not necessarily be exercised per unit test. The resources can be shared by creating them at - the class-level using setUpClass and shared across all instances during a single run. - - 3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh resources per test. Hence a call should be - taken by the stakeholders regarding sharing resources. - - 4. Ensure that the tearDown/tearDownClass functions clean up all the resources created during the test run. - -For more information about unittests: http://docs.python.org/library/unittest.html - - -P1 Tests ----------- -The following files contain these P1 cases: - -1. test_snapshots.py - Snapshots related tests -2. test_routers.py - Router related tests -3. test_usage.py - Usage realted tests -4. test_account.py - Account related tests -5. test_resource_limits.py - Resource limits tests -6. test_security_groups.py - Security groups related tests -7. test_templates.py - templates related tests -8. test_volumes.py - Volumes related tests -9. test_blocker_bugs.py - Blocker bugs tests -10. test_project_configs.py - Project global configuration related tests -11. test_project_limits.py - Project resource limits related tests -12. test_project_resources.py - Project resource creation related tests -13. test_project_usage.py - Project usage related tests -14. test_projects - Projects functionality tests diff --git a/tools/testClient/testcase/P1-tests/__init__.py b/tools/testClient/testcase/P1-tests/__init__.py deleted file mode 100644 index d65b5e89b69..00000000000 --- a/tools/testClient/testcase/P1-tests/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 \ No newline at end of file diff --git a/tools/testClient/testcase/P1-tests/test_accounts.py b/tools/testClient/testcase/P1-tests/test_accounts.py deleted file mode 100644 index 9b1df4f8f8b..00000000000 --- a/tools/testClient/testcase/P1-tests/test_accounts.py +++ /dev/null @@ -1,1091 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Account -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - - -class Services: - """Test Account Services - """ - - 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": "fr3sca", - }, - "user": { - "email": "user@test.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "template": { - "displaytext": "Public Template", - "name": "Public template", - "ostypeid": 'aaf6e8c9-b609-441d-9ebd-b4eaa030a275', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", - "hypervisor": 'XenServer', - "format" : 'VHD', - "isfeatured": True, - "ispublic": True, - "isextractable": True, - }, - "ostypeid": 'aaf6e8c9-b609-441d-9ebd-b4eaa030a275', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode":'advanced' - } - - -class TestAccounts(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAccounts, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [cls.service_offering] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_create_account(self): - """Test Create Account and user for that account - """ - - # Validate the following - # 1. Create an Account. Verify the account is created. - # 2. Create User associated with that account. Verify the created user - - # Create an account - account = Account.create( - self.apiclient, - self.services["account"] - ) - self.debug("Created account: %s" % account.account.name) - self.cleanup.append(account) - list_accounts_response = list_accounts( - self.apiclient, - id=account.account.id - ) - self.assertEqual( - isinstance(list_accounts_response, list), - True, - "Check list accounts for valid data" - ) - self.assertNotEqual( - len(list_accounts_response), - 0, - "Check List Account response" - ) - - account_response = list_accounts_response[0] - self.assertEqual( - account.account.accounttype, - account_response.accounttype, - "Check Account Type of Created account" - ) - self.assertEqual( - account.account.name, - account_response.name, - "Check Account Name of Created account" - ) - # Create an User associated with account - user = User.create( - self.apiclient, - self.services["user"], - account=account.account.name, - domainid=account.account.domainid - ) - self.debug("Created user: %s" % user.id) - list_users_response = list_users( - self.apiclient, - id=user.id - ) - self.assertEqual( - isinstance(list_users_response, list), - True, - "Check list users for valid data" - ) - - self.assertNotEqual( - len(list_users_response), - 0, - "Check List User response" - ) - - user_response = list_users_response[0] - self.assertEqual( - user.username, - user_response.username, - "Check username of Created user" - ) - self.assertEqual( - user.state, - user_response.state, - "Check state of created user" - ) - return - - -class TestRemoveUserFromAccount(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestRemoveUserFromAccount, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - # Create an account - cls.account = Account.create( - cls.api_client, - cls.services["account"] - ) - - cls._cleanup = [ - cls.service_offering, - ] - 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, terminate the created instance, users etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_user_remove_VM_running(self): - """Test Remove one user from the account - """ - - # Validate the following - # 1. Create an account with 2 users. - # 2. Start 2 VMs; one for each user of the account - # 3. Remove one user from the account. Verify that account still exists. - # 4. Verify that VM started by the removed user are still running - - # Create an User associated with account and VMs - user_1 = User.create( - self.apiclient, - self.services["user"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created user: %s" % user_1.id) - user_2 = User.create( - self.apiclient, - self.services["user"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created user: %s" % user_2.id) - self.cleanup.append(user_2) - - vm_1 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM in account: %s, ID: %s" % ( - self.account.account.name, - vm_1.id - )) - self.cleanup.append(vm_1) - - vm_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM in account: %s, ID: %s" % ( - self.account.account.name, - vm_2.id - )) - self.cleanup.append(vm_2) - - # Remove one of the user - self.debug("Deleting user: %s" % user_1.id) - user_1.delete(self.apiclient) - - # Account should exist after deleting user - accounts_response = list_accounts( - self.apiclient, - id=self.account.account.id - ) - self.assertEqual( - isinstance(accounts_response, list), - True, - "Check for valid list accounts response" - ) - - self.assertNotEqual( - len(accounts_response), - 0, - "Check List Account response" - ) - vm_response = list_virtual_machines( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check for valid list VM response" - ) - - self.assertNotEqual( - len(vm_response), - 0, - "Check List VM response" - ) - - # VMs associated with that account should be running - for vm in vm_response: - self.assertEqual( - vm.state, - 'Running', - "Check state of VMs associated with account" - ) - return - @unittest.skip("Open Questions") - def test_02_remove_all_users(self): - """Test Remove both users from the account - """ - - # Validate the following - # 1. Remove both the users from the account. - # 2. Verify account is removed - # 3. Verify all VMs associated with that account got removed - - # Create an User associated with account and VMs - user_1 = User.create( - self.apiclient, - self.services["user"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created user: %s" % user_1.id) - user_2 = User.create( - self.apiclient, - self.services["user"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created user: %s" % user_2.id) - vm_1 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM in account: %s, ID: %s" % ( - self.account.account.name, - vm_1.id - )) - vm_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM in account: %s, ID: %s" % ( - self.account.account.name, - vm_2.id - )) - # Get users associated with an account - # (Total 3: 2 - Created & 1 default generated while account creation) - users = list_users( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(users, list), - True, - "Check for valid list users response" - ) - for user in users: - - self.debug("Deleting user: %s" % user.id) - cmd = deleteUser.deleteUserCmd() - cmd.id = user.id - self.apiclient.deleteUser(cmd) - - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - self.assertEqual( - isinstance(interval, list), - True, - "Check for valid list configurations response" - ) - self.debug("account.cleanup.interval: %s" % interval[0].value) - - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value)) - - # Account is removed after last user is deleted - account_response = list_accounts( - self.apiclient, - id=self.account.account.id - ) - self.assertEqual( - account_response, - None, - "Check List VM response" - ) - # All VMs associated with account are removed. - vm_response = list_virtual_machines( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - vm_response, - None, - "Check List VM response" - ) - # DomR associated with account is deleted - with self.assertRaises(Exception): - list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - return - - -class TestNonRootAdminsPrivileges(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestNonRootAdminsPrivileges, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone settings - cls.zone = get_zone(cls.api_client, cls.services) - - # Create an account, domain etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"], - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls._cleanup = [ - cls.account, - cls.domain - ] - 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, terminate the created accounts - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_non_root_admin_Privileges(self): - """Test to verify Non Root admin previleges""" - - # Validate the following - # 1. Create few accounts/users in ROOT domain - # 2. Verify listAccounts API gives only accounts associated with new - # domain. - - # Create accounts for ROOT domain - account_1 = Account.create( - self.apiclient, - self.services["account"] - ) - self.debug("Created account: %s" % account_1.account.name) - self.cleanup.append(account_1) - account_2 = Account.create( - self.apiclient, - self.services["account"] - ) - self.debug("Created account: %s" % account_2.account.name) - self.cleanup.append(account_2) - - accounts_response = list_accounts( - self.apiclient, - domainid=self.domain.id - ) - - self.assertEqual( - isinstance(accounts_response, list), - True, - "Check list accounts response for valid data" - ) - - self.assertEqual( - len(accounts_response), - 1, - "Check List accounts response" - ) - # Verify only account associated with domain is listed - for account in accounts_response: - self.assertEqual( - account.domainid, - self.domain.id, - "Check domain ID of account" - ) - return - - -class TestServiceOfferingSiblings(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestServiceOfferingSiblings, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Create Domains, accounts etc - cls.domain_1 = Domain.create( - cls.api_client, - cls.services["domain"] - ) - cls.domain_2 = Domain.create( - cls.api_client, - cls.services["domain"] - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain_1.id - ) - # Create account for doamin_1 - cls.account_1 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_1.id - ) - - # Create an account for domain_2 - cls.account_2 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_2.id - ) - - cls._cleanup = [ - cls.account_1, - cls.account_2, - cls.service_offering, - cls.domain_1, - cls.domain_2, - ] - 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, terminate the created domains, accounts - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_service_offering_siblings(self): - """Test to verify service offerings at same level in hierarchy""" - - # Validate the following - # 1. Verify service offering is visible for domain_1 - # 2. Verify service offering is not visible for domain_2 - - service_offerings = list_service_offering( - self.apiclient, - domainid=self.domain_1.id - ) - self.assertEqual( - isinstance(service_offerings, list), - True, - "Check if valid list service offerings response" - ) - - self.assertNotEqual( - len(service_offerings), - 0, - "Check List Service Offerings response" - ) - - for service_offering in service_offerings: - self.debug("Validating service offering: %s" % service_offering.id) - self.assertEqual( - service_offering.id, - self.service_offering.id, - "Check Service offering ID for domain" + str(self.domain_1.name) - ) - # Verify private service offering is not visible to other domain - service_offerings = list_service_offering( - self.apiclient, - domainid=self.domain_2.id - ) - self.assertEqual( - service_offerings, - None, - "Check List Service Offerings response for other domain" - ) - return - -@unittest.skip("Open Questions") -class TestServiceOfferingHierarchy(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestServiceOfferingHierarchy, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Create domain, service offerings etc - cls.domain_1 = Domain.create( - cls.api_client, - cls.services["domain"] - ) - cls.domain_2 = Domain.create( - cls.api_client, - cls.services["domain"], - parentdomainid=cls.domain_1.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain_1.id - ) - # Create account for doamin_1 - cls.account_1 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_1.id - ) - - # Create an account for domain_2 - cls.account_2 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_2.id - ) - - cls._cleanup = [ - cls.account_1, - cls.account_2, - cls.service_offering, - cls.domain_1, - cls.domain_2, - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_service_offering_hierarchy(self): - """Test to verify service offerings at same level in hierarchy""" - - # Validate the following - # 1. Verify service offering is visible for domain_1 - # 2. Verify service offering is also visible for domain_2 - - service_offerings = list_service_offering( - self.apiclient, - domainid=self.domain_1.id - ) - self.assertEqual( - isinstance(service_offerings, list), - True, - "Check List Service Offerings for a valid response" - ) - self.assertNotEqual( - len(service_offerings), - 0, - "Check List Service Offerings response" - ) - - for service_offering in service_offerings: - self.assertEqual( - service_offering.id, - self.service_offering.id, - "Check Service offering ID for domain" + str(self.domain_1.name) - ) - - # Verify private service offering is not visible to other domain - service_offerings = list_service_offering( - self.apiclient, - domainid=self.domain_2.id - ) - self.assertEqual( - isinstance(service_offerings, list), - True, - "Check List Service Offerings for a valid response" - ) - self.assertNotEqual( - len(service_offerings), - 0, - "Check List Service Offerings response" - ) - - for service_offering in service_offerings: - self.assertEqual( - service_offering.id, - self.service_offering.id, - "Check Service offering ID for domain" + str(self.domain_2.name) - ) - return - -@unittest.skip("Open Questions") -class TesttemplateHierarchy(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TesttemplateHierarchy, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone settings - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["template"]["zoneid"] = cls.zone.id - - # Create domains, accounts and template - cls.domain_1 = Domain.create( - cls.api_client, - cls.services["domain"] - ) - cls.domain_2 = Domain.create( - cls.api_client, - cls.services["domain"], - parentdomainid=cls.domain_1.id - ) - - # Create account for doamin_1 - cls.account_1 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_1.id - ) - - # Create an account for domain_2 - cls.account_2 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain_2.id - ) - - cls.template = Template.register( - cls.api_client, - cls.services["template"], - account=cls.account_1.account.name, - domainid=cls.domain_1.id - ) - cls._cleanup = [ - cls.template, - cls.account_1, - cls.account_2, - cls.domain_1, - cls.domain_2, - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_template_hierarchy(self): - """Test to verify template at same level in hierarchy""" - - # Validate the following - # 1. Verify template is visible for domain_1 - # 2. Verify template is also visible for domain_2 - - # Sleep to ensure that template state is reflected across - time.sleep(self.services["sleep"]) - - templates = list_templates( - self.apiclient, - templatefilter='self', - account=self.account_1.account.name, - domainid=self.domain_1.id - ) - self.assertEqual( - isinstance(templates, list), - True, - "Check List templates for a valid response" - ) - self.assertNotEqual( - len(templates), - 0, - "Check List Template response" - ) - - for template in templates: - self.assertEqual( - template.id, - self.template.id, - "Check Template ID for domain" + str(self.domain_1.name) - ) - - # Verify private service offering is not visible to other domain - templates = list_templates( - self.apiclient, - templatefilter='self', - account=self.account_2.account.name, - domainid=self.domain_2.id - ) - self.assertEqual( - isinstance(templates, list), - True, - "Check List templates for a valid response" - ) - self.assertNotEqual( - len(templates), - 0, - "Check List Service Offerings response" - ) - - for template in templates: - self.assertEqual( - template.id, - self.template.id, - "Check Template ID for domain" + str(self.domain_2.name) - ) - return - -class TestAddVmToSubDomain(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAddVmToSubDomain, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Setup working Environment- Create domain, zone, pod cluster etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services, - ) - cls.sub_domain = Domain.create( - cls.api_client, - cls.services["domain"], - parentdomainid=cls.domain.id - ) - - # Create account for doamin_1 - cls.account_1 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - # Create an account for domain_2 - cls.account_2 = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.sub_domain.id - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain.id - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account_1.account.name, - domainid=cls.account_1.account.domainid, - serviceofferingid=cls.service_offering.id - ) - - cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account_2.account.name, - domainid=cls.account_2.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.account_2, - cls.account_1, - cls.sub_domain, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Clean up, terminate the created resources - 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, terminate the created resources - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - - def test_01_add_vm_to_subdomain(self): - """ Test Sub domain allowed to launch VM when a Domain level zone is - created""" - - # Validate the following - # 1. Verify VM created by Account_1 is in Running state - # 2. Verify VM created by Account_2 is in Running state - - vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_1.id - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check List VM for a valid response" - ) - self.assertNotEqual( - len(vm_response), - 0, - "Check List Template response" - ) - - for vm in vm_response: - self.debug("VM ID: %s and state: %s" % (vm.id, vm.state)) - self.assertEqual( - vm.state, - 'Running', - "Check State of Virtual machine" - ) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.vm_2.id - ) - self.assertNotEqual( - len(vm_response), - 0, - "Check List Template response" - ) - - for vm in vm_response: - self.debug("VM ID: %s and state: %s" % (vm.id, vm.state)) - self.assertEqual( - vm.state, - 'Running', - "Check State of Virtual machine" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_blocker_bugs.py b/tools/testClient/testcase/P1-tests/test_blocker_bugs.py deleted file mode 100644 index 1c36f57e6bc..00000000000 --- a/tools/testClient/testcase/P1-tests/test_blocker_bugs.py +++ /dev/null @@ -1,1272 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" Tests for Blocker bugs -""" -from testcase.libs.base import * -from testcase.libs.utils import * -from testcase.libs.common import * - -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient - -class Services: - """Test Services - """ - - 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": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, # in GBs - "diskdevice": "/dev/xvdb", # Data Disk - }, - "templates": { - "displaytext": 'Template from snapshot', - "name": 'Template from snapshot', - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - "templatefilter": 'self', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", - "hypervisor": 'XenServer', - "format" : 'VHD', - "isfeatured": True, - "ispublic": True, - "isextractable": True, - "passwordenabled":True, - }, - "paths": { - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - }, - "static_nat": { - "startport": 22, - "endport": 22, - "protocol": "TCP" - }, - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - # Cent OS 5.3 (64 bit) - "sleep":60, - "mode": 'advanced', - # Networking mode, Advanced, Basic - } - - -class TestSnapshots(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["zoneid"] = cls.zone.id - - cls.services["template"] = cls.template.id - cls.services["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - cls._cleanup = [ - cls.service_offering, - cls.disk_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_volume_from_snapshot(self): - """TS_BUG_001-Test Creating snapshot from volume having spaces in name(KVM) - """ - - # Validate the following - #1. Create a virtual machine and data volume - #2. Attach data volume to VM - #3. Login to machine; create temp/test directories on data volume - #4. Snapshot the Volume - #5. Create another Volume from snapshot - #6. Mount/Attach volume to another server - #7. Compare data - - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume with ID: %s" % volume.id) - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - self.debug("Attach volume: %s to VM: %s" % - (volume.id, self.virtual_machine.id)) - try: - ssh_client = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH failed for VM: %s" % - self.virtual_machine.ipaddress) - - self.debug("Formatting volume: %s to ext3" % volume.id) - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["volume"]["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - ), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - list_volume_response = Volume.list( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volume response for valid data" - ) - volume_response = list_volume_response[0] - #Create snapshot from attached volume - snapshot = Snapshot.create( - self.apiclient, - volume_response.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created snapshot: %s" % snapshot.id) - #Create volume from snapshot - volume_from_snapshot = Volume.create_from_snapshot( - self.apiclient, - snapshot.id, - self.services["volume"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created Volume: %s from Snapshot: %s" % ( - volume_from_snapshot.id, - snapshot.id)) - volumes = Volume.list( - self.apiclient, - id=volume_from_snapshot.id - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(volumes), - None, - "Check Volume list Length" - ) - self.assertEqual ( - volumes[0].id, - volume_from_snapshot.id, - "Check Volume in the List Volumes" - ) - #Attaching volume to new VM - new_virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - mode=self.services["mode"] - ) - self.debug("Deployed new VM for account: %s" % self.account.account.name) - self.cleanup.append(new_virtual_machine) - - self.debug("Attaching volume: %s to VM: %s" % ( - volume_from_snapshot.id, - new_virtual_machine.id - )) - - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume_from_snapshot.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) - - try: - #Login to VM to verify test directories and files - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - ] - - for c in cmds: - self.debug("Command: %s" % c) - ssh.execute(c) - - returned_data_0 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - )) - returned_data_1 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - )) - except Exception as e: - self.fail("SSH access failed for VM: %s" % - new_virtual_machine.ipaddress) - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - return - - -class TestTemplate(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestTemplate, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["templates"]["zoneid"] = cls.zone.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestTemplate, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_create_template(self): - """TS_BUG_002-Test to create and deploy VM using password enabled template - """ - - # Validate the following: - #1. Create a password enabled template - #2. Deploy VM using this template - #3. Deploy VM should return password set in template. - - self.debug("Registering a new template") - # Register new template - template = Template.register( - self.apiclient, - self.services["templates"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Registering template with ID: %s" % template.id) - try: - # Wait for template to download - template.download(self.apiclient) - except Exception as e: - self.fail("Exception while downloading template %s: %s"\ - % (template.id, e)) - - self.cleanup.append(template) - - # Wait for template status to be changed across - time.sleep(self.services["sleep"]) - - list_template_response = Template.list( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id, - zoneid=self.zone.id - ) - - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check list response returns a valid list" - ) - #Verify template response to check whether template added successfully - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - template_response = list_template_response[0] - - self.assertEqual( - template_response.isready, - True, - "Check display text of newly created template" - ) - - # Deploy new virtual machine using template - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - ) - self.debug("Deployed VM with ID: %s " % virtual_machine.id) - self.assertEqual( - hasattr(virtual_machine,"password"), - True, - "Check if the deployed VM returned a password" - ) - return - - -class TestNATRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestNATRules, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.public_ip = PublicIPAddress.create( - cls.api_client, - accountid=cls.account.account.name, - zoneid=cls.zone.id, - domainid=cls.account.account.domainid, - services=cls.services["virtual_machine"] - ) - cls._cleanup = [ - cls.virtual_machine, - cls.account, - cls.service_offering - ] - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestNATRules, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def tearDown(self): - cleanup_resources(self.apiclient, self.cleanup) - return - - def test_01_firewall_rules_port_fw(self): - """"Checking firewall rules deletion after static NAT disable""" - - # Validate the following: - #1. Enable static NAT for a VM - #2. Open up some ports. At this point there will be new rows in the - # firewall_rules table. - #3. Disable static NAT for the VM. - #4. Check fire wall rules are deleted from firewall_rules table. - - public_ip = self.public_ip.ipaddress - - # Enable Static NAT for VM - StaticNATRule.enable( - self.apiclient, - public_ip.id, - self.virtual_machine.id - ) - self.debug("Enabled static NAT for public IP ID: %s" % - public_ip.id) - #Create Static NAT rule - nat_rule = StaticNATRule.create( - self.apiclient, - self.services["static_nat"], - public_ip.id - ) - self.debug("Created Static NAT rule for public IP ID: %s" % - public_ip.id) - list_rules_repsonse = StaticNATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(list_rules_repsonse, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_rules_repsonse), - 0, - "Check IP Forwarding Rule is created" - ) - self.assertEqual( - list_rules_repsonse[0].id, - nat_rule.id, - "Check Correct IP forwarding Rule is returned" - ) - # Verify the entries made in firewall_rules tables - self.debug( - "select id from user_ip_address where uuid = '%s';" \ - % public_ip.id - ) - qresultset = self.dbclient.execute( - "select id from user_ip_address where uuid = '%s';" \ - % public_ip.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check database query returns a valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - public_ip_id = qresult[0] - # Verify the entries made in firewall_rules tables - self.debug( - "select id, state from firewall_rules where ip_address_id = '%s';" \ - % public_ip_id - ) - qresultset = self.dbclient.execute( - "select id, state from firewall_rules where ip_address_id = '%s';" \ - % public_ip_id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check database query returns a valid data for firewall rules" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - for qresult in qresultset: - self.assertEqual( - qresult[1], - 'Active', - "Check state of the static NAT rule in database" - ) - - nat_rule.delete(self.apiclient) - - list_rules_repsonse = StaticNATRule.list( - self.apiclient, - id=nat_rule.id - ) - - self.assertEqual( - list_rules_repsonse, - None, - "Check Port Forwarding Rule is deleted" - ) - - # Verify the entries made in firewall_rules tables - self.debug( - "select id, state from firewall_rules where ip_address_id = '%s';" \ - % public_ip.id - ) - qresultset = self.dbclient.execute( - "select id, state from firewall_rules where ip_address_id = '%s';" \ - % public_ip.id - ) - - self.assertEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - return - - -class TestRouters(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestRouters, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - - # Create an account, domain etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"], - ) - cls.admin_account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user_account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - - cls._cleanup = [ - cls.service_offering, - cls.admin_account, - cls.user_account, - cls.domain - ] - 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, terminate the created instance, users etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_list_routers_admin(self): - """TS_BUG_007-Check listRouters() using Admin User - """ - - # Validate the following - # 1. PreReq: have rounters that are owned by other account - # 2. Create domain and create accounts in that domain - # 3. Create one VM for each account - # 4. Using Admin , run listRouters. It should return all the routers - - vm_1 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.admin_account.account.name, - domainid=self.admin_account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM with ID: %s" % vm_1.id) - vm_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.user_account.account.name, - domainid=self.user_account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM with ID: %s" % vm_2.id) - routers = list_routers( - self.apiclient, - account=self.admin_account.account.name, - domainid=self.admin_account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check list response returns a valid list" - ) - # ListRouter Should return 2 records - self.assertEqual( - len(routers), - 1, - "Check list router response" - ) - for router in routers: - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - return - - -class TestRouterRestart(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestRouterRestart, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.cleanup = [ - cls.vm_1, - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRouterRestart, cls).getClsTestClient().getApiClient() - #Clean up, terminate the created templates - 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() - return - - - def test_01_restart_network_cleanup(self): - """TS_BUG_008-Test restart network - """ - - # Validate the following - # 1. When cleanup = true, router is destroyed and a new one created - # 2. New router will have new publicIp and linkLocalIp and - # all it's services should resume - - # Find router associated with user account - list_router_response = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(list_router_response, list), - True, - "Check list response returns a valid list" - ) - router = list_router_response[0] - - #Store old values before restart - old_linklocalip = router.linklocalip - - timeout = 10 - # Network should be in Implemented or Setup stage before restart - while True: - networks = Network.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - network = networks[0] - if network.state in ["Implemented", "Setup"]: - break - elif timeout == 0: - break - else: - time.sleep(60) - timeout = timeout - 1 - - self.debug("Restarting network: %s" % network.id) - cmd = restartNetwork.restartNetworkCmd() - cmd.id = network.id - cmd.cleanup = True - self.apiclient.restartNetwork(cmd) - - # Get router details after restart - list_router_response = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(list_router_response, list), - True, - "Check list response returns a valid list" - ) - router = list_router_response[0] - - self.assertNotEqual( - router.linklocalip, - old_linklocalip, - "Check link-local IP after restart" - ) - return - - -class TestTemplates(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - - # Get Zone, templates etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - - # create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = Volume.list( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - try: - if isinstance(list_volume, list): - cls.volume = list_volume[0] - except Exception as e: - raise Exception("Warning: Exception during setup : %s" % e) - - cls._cleanup = [ - cls.service_offering, - cls.account, - ] - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - #Cleanup created resources such as templates and VMs - 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, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_check_template_size(self): - """TS_BUG_009-Test the size of template created from root disk - """ - - # Validate the following: - # 1. Deploy new VM using the template created from Volume - # 2. VM should be in Up and Running state - - #Create template from volume - template = Template.create( - self.apiclient, - self.services["templates"], - self.volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Creating template with ID: %s" % template.id) - # Volume and Template Size should be same - self.assertEqual( - template.size, - self.volume.size, - "Check if size of template and volume are same" - ) - return - - def test_02_check_size_snapshotTemplate(self): - """TS_BUG_010-Test check size of snapshot and template - """ - - # Validate the following - # 1. Deploy VM using default template, small service offering - # and small data disk offering. - # 2. Perform snapshot on the root disk of this VM. - # 3. Create a template from snapshot. - # 4. Check the size of snapshot and template - - # Create a snapshot from the ROOTDISK - snapshot = Snapshot.create( - self.apiclient, - self.volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created snapshot with ID: %s" % snapshot.id) - snapshots = Snapshot.list( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - - # Generate template from the snapshot - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"] - ) - self.cleanup.append(template) - - self.debug("Created template from snapshot with ID: %s" % template.id) - templates = Template.list( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - self.assertEqual( - isinstance(templates, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].isready, - True, - "Check new template state in list templates call" - ) - # check size of template with that of snapshot - self.assertEqual( - templates[0].size, - self.volume.size, - "Check if size of snapshot and template matches" - ) - return - - def test_03_resuse_template_name(self): - """TS_BUG_011-Test Reusing deleted template name - """ - - # Validate the following - # 1. Deploy VM using default template, small service offering - # and small data disk offering. - # 2. Perform snapshot on the root disk of this VM. - # 3. Create a template from snapshot. - # 4. Delete the template and create a new template with same name - # 5. Template should be created succesfully - - # Create a snapshot from the ROOTDISK - snapshot = Snapshot.create( - self.apiclient, - self.volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created snapshot with ID: %s" % snapshot.id) - snapshots = Snapshot.list( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - - # Generate template from the snapshot - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"], - random_name=False - ) - self.debug("Created template from snapshot: %s" % template.id) - templates = Template.list( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - self.assertEqual( - isinstance(templates, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].isready, - True, - "Check new template state in list templates call" - ) - - self.debug("Deleting template: %s" % template.id) - template.delete(self.apiclient) - - # Wait for some time to ensure template state is reflected in other calls - time.sleep(self.services["sleep"]) - - # Generate template from the snapshot - self.debug("Creating template from snapshot: %s with same name" % - template.id) - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"], - random_name=False - ) - - templates = Template.list( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - self.assertEqual( - isinstance(templates, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].name, - self.services["templates"]["name"], - "Check the name of the template" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_egress_rules.py b/tools/testClient/testcase/P1-tests/test_egress_rules.py deleted file mode 100644 index 1edb37a8626..00000000000 --- a/tools/testClient/testcase/P1-tests/test_egress_rules.py +++ /dev/null @@ -1,2335 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -""" P1 for Egresss & Ingress rules -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time -import subprocess - - -class Services: - """Test Security groups Services - """ - - def __init__(self): - self.services = { - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "fr3sca", - }, - "virtual_machine": { - # Create a small virtual machine instance with disk offering - "displayname": "Test VM", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - "userdata": 'This is sample data', - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "security_group": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.0/0', - }, - "sg_invalid_port": { - "name": 'SSH', - "protocol": 'TCP', - "startport": -22, - "endport": -22, - "cidrlist": '0.0.0.0/0', - }, - "sg_invalid_cidr": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.10' - }, - "sg_cidr_anywhere": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.0/0' - }, - "sg_cidr_restricted": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '10.0.0.1/24', - }, - "sg_account": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.0/0', - }, - "mgmt_server": { - "username": "root", - "password": "fr3sca", - "ipaddress": "192.168.100.21" - }, - "ostypeid": '85cb528f-72ed-4df9-ac6a-f6ccf0892ff2', - # CentOS 5.3 (64-bit) - "sleep": 60, - "timeout": 10, - "mode": 'basic', - # Networking mode: Basic or Advanced - } - - -class TestDefaultSecurityGroupEgress(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultSecurityGroupEgress, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_deployVM_InDefaultSecurityGroup(self): - """Test deploy VM in default security group with no egress rules - """ - - # Validate the following: - # 1. Deploy a VM. - # 2. Deployed VM should be running, verify with listVirtualMachiens - # 3. listSecurityGroups for this account. should list the default - # security group with no egress rules - # 4. listVirtualMachines should show that the VM belongs to default - # security group - - self.debug("Deploying VM in account: %s" % self.account.account.name) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM with ID: %s" % self.virtual_machine.id) - self.cleanup.append(self.virtual_machine) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id - ) - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check for list VM response" - ) - vm_response = list_vm_response[0] - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - - vm_response.id, - self.virtual_machine.id, - "Check virtual machine id in listVirtualMachines" - ) - - self.assertEqual( - vm_response.state, - 'Running', - "VM state should be running" - ) - self.assertEqual( - hasattr(vm_response, "securitygroup"), - True, - "List VM response should have atleast one security group" - ) - - # Verify listSecurity groups response - security_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(security_groups, list), - True, - "Check for list security groups response" - ) - self.assertEqual( - len(security_groups), - 1, - "Check List Security groups response" - ) - self.debug("List Security groups response: %s" % - str(security_groups)) - sec_grp = security_groups[0] - self.assertEqual( - sec_grp.name, - 'default', - "List Sec Group should only list default sec. group" - ) - return - - -class TestAuthorizeIngressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestAuthorizeIngressRule, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_authorizeIngressRule(self): - """Test authorize ingress rule - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. deployVirtualMachine into this security group (ssh). deployed VM - # should be Running - # 5. listSecurityGroups should show two groups, default and ssh - # 6. verify that ssh-access into the VM is now allowed - # 7. verify from within the VM is able to ping outside world - # (ping www.google.com) - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.debug("Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = self.virtual_machine.get_ssh_client() - - # Ping to outsite world - res = ssh.execute("ping -c 1 www.google.com") - # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): - # icmp_req=1 ttl=57 time=25.9 ms - # --- www.l.google.com ping statistics --- - # 1 packets transmitted, 1 received, 0% packet loss, time 0ms - # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - result = str(res) - self.assertEqual( - result.count("1 received"), - 1, - "Ping to outside world from VM should be successful" - ) - return - - -class TestDefaultGroupEgress(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultGroupEgress, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_01_default_group_with_egress(self): - """Test default group with egress rule before VM deploy and ping, ssh - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. authorizeSecurityGroupEgress to allow ssh access only out to - # CIDR: 0.0.0.0/0 - # 5. deployVirtualMachine into this security group (ssh) - # 6. deployed VM should be Running, ssh should be allowed into the VM, - # ping out to google.com from the VM should fail, - # ssh from within VM to mgt server should pass - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug("Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - # Authorize Security group to SSH to VM - self.debug("Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - - ssh = self.virtual_machine.get_ssh_client() - - self.debug("Ping to google.com from VM") - # Ping to outsite world - res = ssh.execute("ping -c 1 www.google.com") - # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): - # icmp_req=1 ttl=57 time=25.9 ms - # --- www.l.google.com ping statistics --- - # 1 packets transmitted, 1 received, 0% packet loss, time 0ms - # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - result = str(res) - self.assertEqual( - result.count("0 received"), - 1, - "Ping to outside world from VM should be successful" - ) - - try: - self.debug("SSHing into management server from VM") - res = ssh.execute("ssh %s@%s" % ( - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["ipaddress"] - )) - self.debug("SSH result: %s" % str(res)) - - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - result = str(res) - self.assertNotEqual( - result.count("No route to host"), - 1, - "SSH into management server from VM should be successful" - ) - return - - -class TestDefaultGroupEgressAfterDeploy(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestDefaultGroupEgressAfterDeploy, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_01_default_group_with_egress(self): - """ Test default group with egress rule added after vm deploy and ping, - ssh test - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. deployVirtualMachine into this security group (ssh) - # 5. authorizeSecurityGroupEgress to allow ssh access only out to - # CIDR: 0.0.0.0/0 - # 6. deployed VM should be Running, ssh should be allowed into the VM, - # ping out to google.com from the VM should fail - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug("Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = self.virtual_machine.get_ssh_client() - - self.debug("Ping to google.com from VM") - # Ping to outsite world - res = ssh.execute("ping -c 1 www.google.com") - # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): - # icmp_req=1 ttl=57 time=25.9 ms - # --- www.l.google.com ping statistics --- - # 1 packets transmitted, 1 received, 0% packet loss, time 0ms - # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms - self.debug("SSH result: %s" % str(res)) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - result = str(res) - self.assertEqual( - result.count("0 received"), - 1, - "Ping to outside world from VM should be successful" - ) - return - - -class TestRevokeEgressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestRevokeEgressRule, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_revoke_egress_rule(self): - """Test revoke security group egress rule - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. authorizeSecurityGroupEgress to allow ssh access only out to - # CIDR: 0.0.0.0/0 - # 5. deployVirtualMachine into this security group (ssh) - # 6. deployed VM should be Running, ssh should be allowed into the VM, - # ping out to google.com from the VM should fail, - # ssh from within VM to mgt server should pass - # 7. Revoke egress rule. Verify ping and SSH access to management server - # is restored - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = self.virtual_machine.get_ssh_client() - - self.debug("Ping to google.com from VM") - # Ping to outsite world - res = ssh.execute("ping -c 1 www.google.com") - # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): - # icmp_req=1 ttl=57 time=25.9 ms - # --- www.l.google.com ping statistics --- - # 1 packets transmitted, 1 received, 0% packet loss, time 0ms - # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms - self.debug("SSH result: %s" % str(res)) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - result = str(res) - self.assertEqual( - result.count("0 received"), - 1, - "Ping to outside world from VM should be successful" - ) - - try: - self.debug("SSHing into management server from VM") - res = ssh.execute("ssh %s@%s" % ( - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["ipaddress"] - )) - self.debug("SSH result: %s" % str(res)) - - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - result = str(res) - self.assertNotEqual( - result.count("No route to host"), - 1, - "SSH into management server from VM should be successful" - ) - - self.debug( - "Revoke Egress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - result = security_group.revokeEgress( - self.apiclient, - id=ssh_egress_rule["ruleid"] - ) - self.debug("Revoke egress rule result: %s" % result) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = self.virtual_machine.get_ssh_client(reconnect=True) - - self.debug("Ping to google.com from VM") - # Ping to outsite world - res = ssh.execute("ping -c 1 www.google.com") - # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212): - # icmp_req=1 ttl=57 time=25.9 ms - # --- www.l.google.com ping statistics --- - # 1 packets transmitted, 1 received, 0% packet loss, time 0ms - # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - result = str(res) - self.assertEqual( - result.count("1 received"), - 1, - "Ping to outside world from VM should be successful" - ) - - try: - self.debug("SSHing into management server from VM") - res = ssh.execute("ssh %s@%s" % ( - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["ipaddress"] - )) - self.debug("SSH result: %s" % str(res)) - - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - result = str(res) - self.assertNotEqual( - result.count("No route to host"), - 1, - "SSH into management server from VM should be successful" - ) - return - - -class TestInvalidAccountAuthroize(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestInvalidAccountAuthroize, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_invalid_account_authroize(self): - """Test invalid account authroize - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupEgress to allow ssh access only out to - # non-existent random account and default security group - # 4. listSecurityGroups should show ssh and default security groups - # 5. authorizeSecurityGroupEgress API should fail since there is no - # account - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - with self.assertRaises(Exception): - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=random_gen(), - domainid=self.account.account.domainid - ) - return - - -class TestMultipleAccountsEgressRuleNeg(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestMultipleAccountsEgressRuleNeg, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.accountA = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.accountB = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.accountA.account.name - cls._cleanup = [ - cls.accountA, - cls.accountB, - cls.service_offering - ] - 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 test_multiple_account_egress_rule_negative(self): - """Test multiple account egress rules negative case - """ - - # Validate the following: - # 1. createaccount of type user A - # 2. createaccount of type user B - # 3. createsecuritygroup (SSH-A) for account A - # 4. authorizeSecurityGroupEgress in account A to allow ssh access - # only out to VMs in account B's default security group - # 5. authorizeSecurityGroupIngress in account A to allow ssh incoming - # access from anywhere into Vm's of account A. listSecurityGroups - # for account A should show two groups (default and ssh-a) and ssh - # ingress rule and account based egress rule - # 6. deployVM in account A into security group SSH-A. deployed VM - # should be Running - # 7. deployVM in account B. deployed VM should be Running - # 8. ssh into VM in account A and from there ssh to VM in account B. - # ssh should fail - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - # Authorize to only account not CIDR - user_secgrp_list = {self.accountB.account.name: 'default'} - - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["sg_account"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid, - user_secgrp_list=user_secgrp_list - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - self.virtual_machineA = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.accountA.account.name, - domainid=self.accountA.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.cleanup.append(self.virtual_machineA) - self.debug("Deploying VM in account: %s" % self.accountA.account.name) - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machineA.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "VM state after deployment should be running" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - self.virtual_machineB = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.accountB.account.name, - domainid=self.accountB.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(self.virtual_machineB) - self.debug("Deploying VM in account: %s" % self.accountB.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machineB.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "VM state after deployment should be running" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machineA.ssh_ip) - ssh = self.virtual_machineA.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machineA.ipaddress, e) - ) - - try: - self.debug("SSHing into VM type B from VM A") - self.debug("VM IP: %s" % self.virtual_machineB.ssh_ip) - res = ssh.execute("ssh %s@%s" % ( - self.services["virtual_machine"]["username"], - self.virtual_machineB.ssh_ip - )) - self.debug("SSH result: %s" % str(res)) - - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machineA.ipaddress, e) - ) - result = str(res) - self.assertEqual( - result.count("Connection timed out"), - 1, - "SSH into management server from VM should not be successful" - ) - return - - -class TestMultipleAccountsEgressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestMultipleAccountsEgressRule, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.accountA = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.accountB = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.accountA.account.name - cls._cleanup = [ - cls.accountA, - cls.accountB, - cls.service_offering - ] - 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 test_multiple_account_egress_rule_positive(self): - """Test multiple account egress rules positive case - """ - - # Validate the following: - # 1. createaccount of type user A - # 2. createaccount of type user B - # 3. createsecuritygroup (SSH-A) for account A - # 4. authorizeSecurityGroupEgress in account A to allow ssh access - # only out to VMs in account B's default security group - # 5. authorizeSecurityGroupIngress in account A to allow ssh incoming - # access from anywhere into Vm's of account A. listSecurityGroups - # for account A should show two groups (default and ssh-a) and ssh - # ingress rule and account based egress rule - # 6. deployVM in account A into security group SSH-A. deployed VM - # should be Running - # 7. deployVM in account B. deployed VM should be Running - # 8. ssh into VM in account A and from there ssh to VM in account B. - # ssh should fail - - security_groupA = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - self.debug("Created security group with ID: %s" % security_groupA.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - security_groupB = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.accountB.account.name, - domainid=self.accountB.account.domainid - ) - self.debug("Created security group with ID: %s" % security_groupB.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.accountB.account.name, - domainid=self.accountB.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_groupA.id) - # Authorize to only account not CIDR - user_secgrp_list = {self.accountB.account.name: security_groupB.name} - - egress_rule = security_groupA.authorizeEgress( - self.apiclient, - self.services["sg_account"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid, - user_secgrp_list=user_secgrp_list - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_groupA.id) - ingress_ruleA = security_groupA.authorize( - self.apiclient, - self.services["security_group"], - account=self.accountA.account.name, - domainid=self.accountA.account.domainid - ) - - self.assertEqual( - isinstance(ingress_ruleA, dict), - True, - "Check ingress rule created properly" - ) - - ssh_ruleA = (ingress_ruleA["ingressrule"][0]).__dict__ - - self.virtual_machineA = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.accountA.account.name, - domainid=self.accountA.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_groupA.id] - ) - self.cleanup.append(self.virtual_machineA) - self.debug("Deploying VM in account: %s" % self.accountA.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machineA.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "VM state after deployment should be running" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_groupB.id) - ingress_ruleB = security_groupB.authorize( - self.apiclient, - self.services["security_group"], - account=self.accountB.account.name, - domainid=self.accountB.account.domainid - ) - - self.assertEqual( - isinstance(ingress_ruleB, dict), - True, - "Check ingress rule created properly" - ) - - ssh_ruleB = (ingress_ruleB["ingressrule"][0]).__dict__ - - self.virtual_machineB = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.accountB.account.name, - domainid=self.accountB.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_groupB.id] - ) - self.cleanup.append(self.virtual_machineB) - self.debug("Deploying VM in account: %s" % self.accountB.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machineB.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "VM state after deployment should be running" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machineA.ssh_ip) - ssh = self.virtual_machineA.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machineA.ipaddress, e) - ) - - try: - self.debug("SSHing into VB type B from VM A") - self.debug("VM IP: %s" % self.virtual_machineB.ssh_ip) - - res = ssh.execute("ssh %s@%s" % ( - self.services["virtual_machine"]["username"], - self.virtual_machineB.ssh_ip - )) - self.debug("SSH result: %s" % str(res)) - - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machineA.ipaddress, e) - ) - result = str(res) - self.assertNotEqual( - result.count("Connection timed out"), - 1, - "SSH into management server from VM should be successful" - ) - return - - -class TestStartStopVMWithEgressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestStartStopVMWithEgressRule, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_start_stop_vm_egress(self): - """ Test stop start Vm with egress rules - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. authorizeSecurityGroupEgress to allow ssh access only out to - # CIDR: 0.0.0.0/0 - # 5. deployVirtualMachine into this security group (ssh) - # 6. stopVirtualMachine - # 7. startVirtualMachine - # 8. ssh in to VM - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - # Stop virtual machine - self.debug("Stopping virtual machine: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Stopped", - "VM state should be stopped" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - # Start virtual machine - self.debug("Starting virtual machine: %s" % self.virtual_machine.id) - self.virtual_machine.start(self.apiclient) - - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VM should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "VM state should be stopped" - ) - self.debug("VM: %s state: %s" % (vm.id, vm.state)) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - return - - -@unittest.skip("Valid bug- ID: CS-12647") -class TestInvalidParametersForEgress(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestInvalidParametersForEgress, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_invalid_parameters(self): - """ Test invalid parameters for egress rules - """ - - # Validate the following: - # 1. createUserAccount - # 2. createSecurityGroup (test) - # 3. authorizeEgressRule (negative port) - Should fail - # 4. authorizeEgressRule (invalid CIDR) - Should fail - # 5. authorizeEgressRule (invalid account) - Should fail - # 6. authorizeEgressRule (22, cidr: anywhere) and - # authorizeEgressRule (22, cidr: restricted) - Should pass - # 7. authorizeEgressRule (21, cidr : 10.1.1.0/24) and - # authorizeEgressRule (21, cidr: 10.1.1.0/24) - Should fail - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s with invalid port" - % security_group.id) - with self.assertRaises(Exception): - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["sg_invalid_port"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug( - "Authorizing egress rule for sec group ID: %s with invalid cidr" - % security_group.id) - with self.assertRaises(Exception): - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["sg_invalid_cidr"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug( - "Authorizing egress rule for sec group ID: %s with invalid account" - % security_group.id) - with self.assertRaises(Exception): - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=random_gen(), - domainid=self.account.account.domainid - ) - self.debug( - "Authorizing egress rule for sec group ID: %s with cidr: anywhere and port: 22" - % security_group.id) - egress_rule_A = security_group.authorizeEgress( - self.apiclient, - self.services["sg_cidr_anywhere"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule_A, dict), - True, - "Check egress rule created properly" - ) - - egress_rule_R = security_group.authorizeEgress( - self.apiclient, - self.services["sg_cidr_restricted"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule_R, dict), - True, - "Check egress rule created properly" - ) - - self.debug( - "Authorizing egress rule for sec group ID: %s with duplicate port" - % security_group.id) - with self.assertRaises(Exception): - security_group.authorizeEgress( - self.apiclient, - self.services["sg_cidr_restricted"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - return - - -class TestEgressAfterHostMaintainance(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestEgressAfterHostMaintainance, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.pod = get_pod( - cls.api_client, - zoneid=cls.zone.id - ) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - 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 test_egress_after_host_maintainance(self): - """Test maintenance case for egress - """ - - # Validate the following: - # 1. createaccount of type user - # 2. createsecuritygroup (ssh) for this account - # 3. authorizeSecurityGroupIngress to allow ssh access to the VM - # 4. authorizeSecurityGroupEgress to allow ssh access only out to - # CIDR: 0.0.0.0/0 - # 5. deployVirtualMachine into this security group (ssh) - # 6. deployed VM should be Running, ssh should be allowed into the VM - # 7. Enable maintainance mode for host, cance maintainance mode - # 8. User should be able to SSH into VM after maintainace - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - - # Authorize Security group to SSH to VM - self.debug( - "Authorizing egress rule for sec group ID: %s for ssh access" - % security_group.id) - egress_rule = security_group.authorizeEgress( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(egress_rule, dict), - True, - "Check egress rule created properly" - ) - ssh_egress_rule = (egress_rule["egressrule"][0]).__dict__ - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.id) - ssh = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - vms = VirtualMachine.list( - self.apiclient, - id=self.virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "Check list VMs response for valid host" - ) - vm = vms[0] - - self.debug("Enabling host maintainance for ID: %s" % vm.hostid) - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = vm.hostid - self.apiclient.prepareHostForMaintenance(cmd) - - self.debug("Canceling host maintainance for ID: %s" % vm.hostid) - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = vm.hostid - self.apiclient.cancelHostMaintenance(cmd) - - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - self.debug("Starting VM: %s" % self.virtual_machine.id) - - self.virtual_machine.start(self.apiclient) - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.id) - ssh = self.virtual_machine.get_ssh_client(reconnect=True) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_high_availability.py b/tools/testClient/testcase/P1-tests/test_high_availability.py deleted file mode 100644 index e4ee99e2216..00000000000 --- a/tools/testClient/testcase/P1-tests/test_high_availability.py +++ /dev/null @@ -1,968 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -""" P1 tests for high availability -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - - -class Services: - """Test network offering Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "HA", - "lastname": "HA", - "username": "HA", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "lbrule": { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "fw_rule":{ - "startport": 1, - "endport": 6000, - "cidr": '55.55.0.0/11', - # Any network (For creating FW rule) - }, - "virtual_machine": { - "displayname": "VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostypeid": '9958b10f-9e5d-4ef1-908d-a047372d823b', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 100, - "mode":'advanced' - } - - -class TestHighAvailability(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super( - TestHighAvailability, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone( - cls.api_client, - cls.services - ) - cls.pod = get_pod( - cls.api_client, - zoneid=cls.zone.id, - services=cls.services - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - offerha=True - ) - cls._cleanup = [ - cls.service_offering, - ] - 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.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [self.account] - return - -# def tearDown(self): -# try: -# #Clean up, terminate the created accounts, domains etc -# cleanup_resources(self.apiclient, self.cleanup) -# self.testClient.close() -# except Exception as e: -# raise Exception("Warning: Exception during cleanup : %s" % e) -# return - - def test_01_host_maintenance_mode(self): - """Test host maintenance mode - """ - - # Validate the following - # 1. Create Vms. Acquire IP. Create port forwarding & load balancing - # rules for Vms. - # 2. Host 1: put to maintenance mode. All Vms should failover to Host - # 2 in cluster. Vms should be in running state. All port forwarding - # rules and load balancing Rules should work. - # 3. After failover to Host 2 succeeds, deploy Vms. Deploy Vms on host - # 2 should succeed. - # 4. Host 1: cancel maintenance mode. - # 5. Host 2 : put to maintenance mode. All Vms should failover to - # Host 1 in cluster. - # 6. After failover to Host 1 succeeds, deploy VMs. Deploy Vms on - # host 1 should succeed. - - hosts = Host.list( - self.apiclient, - zoneid=self.zone.id, - resourcestate='Enabled', - type='Routing' - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should return valid host response" - ) - self.assertEqual( - len(hosts), - 2, - "There must be two hosts present in a cluster" - ) - self.debug("Checking HA with hosts: %s, %s" % ( - hosts[0].name, - hosts[1].name - )) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug("Deployed VM on host: %s" % vm.hostid) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in RUnning state" - ) - networks = Network.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return valid list for the account" - ) - network = networks[0] - - self.debug("Associating public IP for account: %s" % - self.account.account.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=network.id - ) - - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Creating PF rule for IP address: %s" % - public_ip.ipaddress.ipaddress) - nat_rule= NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=public_ip.ipaddress.id - ) - - self.debug("Creating LB rule on IP with NAT: %s" % - public_ip.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Created LB rule with ID: %s" % lb_rule.id) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - - first_host = vm.hostid - self.debug("Enabling maintenance mode for host %s" % vm.hostid) - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = first_host - self.apiclient.prepareHostForMaintenance(cmd) - - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - - timeout = self.services["timeout"] - # Poll and check state of VM while it migrates from one host to another - while True: - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - - self.debug("VM 1 state: %s" % vm.state) - if vm.state in ["Stopping", "Stopped", "Running", "Starting"]: - if vm.state == "Running": - break - else: - time.sleep(self.services["sleep"]) - timeout = timeout - 1 - else: - self.fail( - "VM migration from one-host-to-other failed while enabling maintenance" - ) - second_host = vm.hostid - self.assertEqual( - vm.state, - "Running", - "VM should be in Running state after enabling host maintenance" - ) - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Spawn an instance on other host - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug("Deployed VM on host: %s" % vm.hostid) - self.debug("VM 2 state: %s" % vm.state) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - - self.debug("Canceling host maintenance for ID: %s" % first_host) - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = first_host - self.apiclient.cancelHostMaintenance(cmd) - self.debug("Maintenance mode canceled for host: %s" % first_host) - - self.debug("Enabling maintenance mode for host %s" % second_host) - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = second_host - self.apiclient.prepareHostForMaintenance(cmd) - self.debug("Maintenance mode enabled for host: %s" % second_host) - - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - - # Poll and check the status of VMs - timeout = self.services["timeout"] - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug( - "VM state after enabling maintenance on first host: %s" % - vm.state) - if vm.state in ["Stopping", "Stopped", "Running", "Starting"]: - if vm.state == "Running": - break - else: - time.sleep(self.services["sleep"]) - timeout = timeout - 1 - else: - self.fail( - "VM migration from one-host-to-other failed while enabling maintenance" - ) - - for vm in vms: - self.debug( - "VM states after enabling maintenance mode on host: %s - %s" % - (first_host, vm.state)) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - # Spawn an instance on other host - virtual_machine_3 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine_3.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - - self.debug("Deployed VM on host: %s" % vm.hostid) - self.debug("VM 3 state: %s" % vm.state) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - - self.debug("Canceling host maintenance for ID: %s" % second_host) - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = second_host - self.apiclient.cancelHostMaintenance(cmd) - self.debug("Maintenance mode canceled for host: %s" % second_host) - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - return - - def test_02_host_maintenance_mode_with_activities(self): - """Test host maintenance mode with activities - """ - - # Validate the following - # 1. Create Vms. Acquire IP. Create port forwarding & load balancing - # rules for Vms. - # 2. While activities are ongoing: Create snapshots, recurring - # snapshots, create templates, download volumes, Host 1: put to - # maintenance mode. All Vms should failover to Host 2 in cluster - # Vms should be in running state. All port forwarding rules and - # load balancing Rules should work. - # 3. After failover to Host 2 succeeds, deploy Vms. Deploy Vms on host - # 2 should succeed. All ongoing activities in step 3 should succeed - # 4. Host 1: cancel maintenance mode. - # 5. While activities are ongoing: Create snapshots, recurring - # snapshots, create templates, download volumes, Host 2: put to - # maintenance mode. All Vms should failover to Host 1 in cluster. - # 6. After failover to Host 1 succeeds, deploy VMs. Deploy Vms on - # host 1 should succeed. All ongoing activities in step 6 should - # succeed. - - hosts = Host.list( - self.apiclient, - zoneid=self.zone.id, - resourcestate='Enabled', - type='Routing' - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should return valid host response" - ) - self.assertEqual( - len(hosts), - 2, - "There must be two hosts present in a cluster" - ) - self.debug("Checking HA with hosts: %s, %s" % ( - hosts[0].name, - hosts[1].name - )) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug("Deployed VM on host: %s" % vm.hostid) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in RUnning state" - ) - networks = Network.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return valid list for the account" - ) - network = networks[0] - - self.debug("Associating public IP for account: %s" % - self.account.account.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=network.id - ) - - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Creating PF rule for IP address: %s" % - public_ip.ipaddress.ipaddress) - nat_rule= NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=public_ip.ipaddress.id - ) - - self.debug("Creating LB rule on IP with NAT: %s" % - public_ip.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Created LB rule with ID: %s" % lb_rule.id) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine.id, - type='ROOT', - listall=True - ) - volume = volumes[0] - self.debug( - "Root volume of VM(%s): %s" % ( - virtual_machine.name, - volume.name - )) - # Create a snapshot from the ROOTDISK - self.debug("Creating snapshot on ROOT volume: %s" % volume.name) - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - self.debug("Snapshot created: ID - %s" % snapshot.id) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id, - listall=True - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - # Generate template from the snapshot - self.debug("Generating template from snapshot: %s" % snapshot.name) - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"] - ) - self.cleanup.append(template) - self.debug("Created template from snapshot: %s" % template.id) - - templates = list_templates( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - - self.assertEqual( - isinstance(templates, list), - True, - "List template call should return the newly created template" - ) - - self.assertEqual( - templates[0].isready, - True, - "The newly created template should be in ready state" - ) - - first_host = vm.hostid - self.debug("Enabling maintenance mode for host %s" % vm.hostid) - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = first_host - self.apiclient.prepareHostForMaintenance(cmd) - - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - - timeout = self.services["timeout"] - # Poll and check state of VM while it migrates from one host to another - while True: - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - - self.debug("VM 1 state: %s" % vm.state) - if vm.state in ["Stopping", "Stopped", "Running", "Starting"]: - if vm.state == "Running": - break - else: - time.sleep(self.services["sleep"]) - timeout = timeout - 1 - else: - self.fail( - "VM migration from one-host-to-other failed while enabling maintenance" - ) - second_host = vm.hostid - self.assertEqual( - vm.state, - "Running", - "VM should be in Running state after enabling host maintenance" - ) - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Spawn an instance on other host - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug("Deployed VM on host: %s" % vm.hostid) - self.debug("VM 2 state: %s" % vm.state) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - - self.debug("Canceling host maintenance for ID: %s" % first_host) - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = first_host - self.apiclient.cancelHostMaintenance(cmd) - self.debug("Maintenance mode canceled for host: %s" % first_host) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_2.id, - type='ROOT', - listall=True - ) - volume = volumes[0] - self.debug( - "Root volume of VM(%s): %s" % ( - virtual_machine_2.name, - volume.name - )) - # Create a snapshot from the ROOTDISK - self.debug("Creating snapshot on ROOT volume: %s" % volume.name) - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - self.debug("Snapshot created: ID - %s" % snapshot.id) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id, - listall=True - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - # Generate template from the snapshot - self.debug("Generating template from snapshot: %s" % snapshot.name) - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"] - ) - self.cleanup.append(template) - self.debug("Created template from snapshot: %s" % template.id) - - templates = list_templates( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - - self.assertEqual( - isinstance(templates, list), - True, - "List template call should return the newly created template" - ) - - self.assertEqual( - templates[0].isready, - True, - "The newly created template should be in ready state" - ) - - self.debug("Enabling maintenance mode for host %s" % second_host) - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = second_host - self.apiclient.prepareHostForMaintenance(cmd) - self.debug("Maintenance mode enabled for host: %s" % second_host) - - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - - # Poll and check the status of VMs - timeout = self.services["timeout"] - while True: - vms = VirtualMachine.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - self.debug( - "VM state after enabling maintenance on first host: %s" % - vm.state) - if vm.state in ["Stopping", "Stopped", "Running", "Starting"]: - if vm.state == "Running": - break - else: - time.sleep(self.services["sleep"]) - timeout = timeout - 1 - else: - self.fail( - "VM migration from one-host-to-other failed while enabling maintenance" - ) - - for vm in vms: - self.debug( - "VM states after enabling maintenance mode on host: %s - %s" % - (first_host, vm.state)) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - # Spawn an instance on other host - virtual_machine_3 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine_3.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs should return valid response for deployed VM" - ) - self.assertNotEqual( - len(vms), - 0, - "List VMs should return valid response for deployed VM" - ) - vm = vms[0] - - self.debug("Deployed VM on host: %s" % vm.hostid) - self.debug("VM 3 state: %s" % vm.state) - self.assertEqual( - vm.state, - "Running", - "Deployed VM should be in Running state" - ) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % virtual_machine.id) - ssh = virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (virtual_machine.ipaddress, e) - ) - - self.debug("Canceling host maintenance for ID: %s" % second_host) - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = second_host - self.apiclient.cancelHostMaintenance(cmd) - self.debug("Maintenance mode canceled for host: %s" % second_host) - self.debug("Waiting for SSVMs to come up") - wait_for_ssvms( - self.apiclient, - zoneid=self.zone.id, - podid=self.pod.id, - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_network_offering.py b/tools/testClient/testcase/P1-tests/test_network_offering.py deleted file mode 100644 index bea2f53f5b9..00000000000 --- a/tools/testClient/testcase/P1-tests/test_network_offering.py +++ /dev/null @@ -1,1782 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -""" P1 tests for network offering -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - - -class Services: - """Test network offering Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "network_offering": { - "name": 'Network offering-VR services', - "displaytext": 'Network offering-VR services', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'VirtualRouter', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "network_offering_netscaler": { - "name": 'Network offering-netscaler', - "displaytext": 'Network offering-netscaler', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'Netscaler', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - }, - "lbrule": { - "name": "SSH", - "alg": "leastconn", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - "openfirewall": False, - }, - "lbrule_port_2221": { - "name": "SSH", - "alg": "leastconn", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2221, - "openfirewall": False, - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "natrule_port_66": { - "privateport": 22, - "publicport": 66, - "protocol": "TCP" - }, - "fw_rule": { - "startport": 1, - "endport": 6000, - "cidr": '55.55.0.0/11', - # Any network (For creating FW rule) - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostypeid": '9958b10f-9e5d-4ef1-908d-a047372d823b', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode": 'advanced' - } - - -class TestNOVirtualRouter(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNOVirtualRouter, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [ - cls.service_offering, - ] - 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.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_network_off_without_conserve_mode(self): - """Test Network offering with Conserve mode off and VR - All services - """ - - # Validate the following - # 1. Create a Network from the above network offering and deploy a VM. - # 2. On source NAT ipaddress, we should NOT be allowed to add a - # LB rules - # 3. On source NAT ipaddress, we should be NOT be allowed to add - # PF rule - # 4. On an ipaddress that has PF rules, we should NOT be allowed to - # add a LB rules. - # 5. On an ipaddress that has Lb rules, we should NOT allow PF rules - # to be programmed. - # 6. We should be allowed to program multiple PF rules on the same Ip - # address on different public ports. - # 7. We should be allowed to program multiple LB rules on the same Ip - # address for different public port ranges. - # 8. On source NAT ipaddress, we should be allowed to Enable VPN. - # 9. On SOurce NAT ipaddress, we will be allowed to add firewall rule - - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:off" - ) - self.network_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering"], - conservemode=False - ) - self.cleanup.append(self.network_offering) - - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - src_nat = src_nat_list[0] - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_nat_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - - self.debug("Associated %s with network %s" % ( - ip_with_nat_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating PF rule for IP address: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - self.debug("Trying to create LB rule on IP with NAT: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Creating PF rule with public port: 66") - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_port_66"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - # Check if NAT rule created successfully - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return valid list" - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_lb_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - self.debug("Associated %s with network %s" % ( - ip_with_lb_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating LB rule for IP address: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name - ) - - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id - ) - - self.debug("Creating LB rule with public port: 2221") - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule_port_2221"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name - ) - - # Check if NAT rule created successfully - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - - self.assertEqual( - isinstance(lb_rules, list), - True, - "List LB rules should return valid list" - ) - - self.debug("Creating firewall rule on source NAT: %s" % - src_nat.ipaddress) - #Create Firewall rule on source NAT - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created firewall rule: %s" % fw_rule.id) - - fw_rules = FireWallRule.list( - self.apiclient, - id=fw_rule.id - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "List fw rules should return a valid firewall rules" - ) - - self.assertNotEqual( - len(fw_rules), - 0, - "Length of fw rules response should not be zero" - ) - return - - def test_02_network_off_with_conserve_mode(self): - """Test Network offering with Conserve mode ON and VR - All services - """ - - # Validate the following - # 1. Create a Network from the above network offering and deploy a VM. - # 2. On source NAT ipaddress, we should be allowed to add a LB rules - # 3. On source NAT ipaddress, we should be allowed to add a PF rules - # 4. On source NAT ipaddress, we should be allowed to add a Firewall - # rules - # 5. On an ipaddress that has Lb rules, we should be allowed to - # program PF rules. - # 6. We should be allowed to program multiple PF rules on the same Ip - # address on different public ports. - # 7. We should be allowed to program multiple LB rules on the same Ip - # address for different public port ranges. - # 8. On source NAT ipaddress, we should be allowed to Enable VPN - # access. - - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:off" - ) - self.network_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering"], - conservemode=True - ) - self.cleanup.append(self.network_offering) - - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - - src_nat = src_nat_list[0] - - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - self.debug("Created LB rule on source NAT: %s" % src_nat.ipaddress) - - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - self.assertEqual( - isinstance(lb_rules, list), - True, - "List lb rules should return a valid lb rules" - ) - self.assertNotEqual( - len(lb_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) - - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT should return a valid port forwarding rules" - ) - self.assertNotEqual( - len(nat_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - self.debug("Creating firewall rule on source NAT: %s" % - src_nat.ipaddress) - #Create Firewall rule on source NAT - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created firewall rule: %s" % fw_rule.id) - - fw_rules = FireWallRule.list( - self.apiclient, - id=fw_rule.id - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "List fw rules should return a valid firewall rules" - ) - - self.assertNotEqual( - len(fw_rules), - 0, - "Length of fw rules response should not be zero" - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating PF rule for IP address: %s" % - public_ip.ipaddress.ipaddress) - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=public_ip.ipaddress.id - ) - - self.debug("Trying to create LB rule on IP with NAT: %s" % - public_ip.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Creating PF rule with public port: 66") - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_port_66"], - ipaddressid=public_ip.ipaddress.id - ) - - # Check if NAT rule created successfully - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return valid list" - ) - - self.debug("Creating LB rule with public port: 2221") - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule_port_2221"], - ipaddressid=public_ip.ipaddress.id, - accountid=self.account.account.name - ) - - # Check if NAT rule created successfully - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - - self.assertEqual( - isinstance(lb_rules, list), - True, - "List LB rules should return valid list" - ) - - # User should be able to enable VPN on source NAT - self.debug("Created VPN with source NAT IP: %s" % src_nat.ipaddress) - # Assign VPN to source NAT - vpn = Vpn.create( - self.apiclient, - src_nat.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - vpns = Vpn.list( - self.apiclient, - publicipid=src_nat.id, - listall=True, - ) - - self.assertEqual( - isinstance(vpns, list), - True, - "List VPNs should return a valid VPN list" - ) - - self.assertNotEqual( - len(vpns), - 0, - "Length of list VPN response should not be zero" - ) - return - - -class TestNOWithNetscaler(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNOWithNetscaler, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [ - cls.service_offering, - ] - 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.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_network_off_without_conserve_mode(self): - """Test Nw off with Conserve mode off, VR-All services, LB-netscaler - """ - - # Validate the following - # 1. Create a Network from the above network offering and deploy a VM. - # 2. On source NAT ipaddress, we should NOT be allowed to add LB rule - # 3. On source NAT ipaddress, we should NOT be allowed to add PF rule - # 4. On an ipaddress that has PF rules, we should NOT be allowed to - # add a LB rules. - # 5. On an ipaddress that has Lb rules , we should NOT allow firewall - # rules to be programmed. - # 6. On an ipaddress that has Lb rules , we should NOT allow PF rules - # to be programmed. - # 7. We should be allowed to program multiple PF rules on the same Ip - # address on different public ports. - # 8. We should be allowed to program multiple LB rules on the same Ip - # address for different public port ranges. - # 9. On source NAT ipaddress, we should NOT be allowed to Enable VPN. - - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:ON" - ) - self.network_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering_netscaler"], - conservemode=False - ) - self.cleanup.append(self.network_offering) - - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - - src_nat = src_nat_list[0] - - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - self.debug("Creating firewall rule on source NAT: %s" % - src_nat.ipaddress) - #Create Firewall rule on source NAT - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - - self.debug("Created firewall rule: %s" % fw_rule.id) - - fw_rules = FireWallRule.list( - self.apiclient, - id=fw_rule.id - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "List fw rules should return a valid firewall rules" - ) - - self.assertNotEqual( - len(fw_rules), - 0, - "Length of fw rules response should not be zero" - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_nat_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - - self.debug("Associated %s with network %s" % ( - ip_with_nat_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating PF rule for IP address: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - self.debug("Trying to create LB rule on IP with NAT: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Creating PF rule with public port: 66") - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_port_66"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - # Check if NAT rule created successfully - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return valid list" - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_lb_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - self.debug("Associated %s with network %s" % ( - ip_with_lb_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating LB rule for IP address: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name, - networkid=self.network.id - ) - - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id - ) - - self.debug("Trying to create FW rule on IP with LB rule") - with self.assertRaises(Exception): - FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - - self.debug("Creating LB rule with public port: 2221") - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule_port_2221"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name, - networkid=self.network.id - ) - - # Check if NAT rule created successfully - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - - self.assertEqual( - isinstance(lb_rules, list), - True, - "List LB rules should return valid list" - ) - - # User should be able to enable VPN on source NAT - self.debug("Enabling VPN on source NAT IP: %s" % src_nat.ipaddress) - # Assign VPN to source NAT - with self.assertRaises(Exception): - Vpn.create( - self.apiclient, - src_nat.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - return - - def test_02_network_off_with_conserve_mode_netscaler(self): - """Test NW off with Conserve mode ON, LB-Netscaler and VR-All services - """ - - # Validate the following - # 1. Create a Network from the above network offering and deploy a VM. - # 2. On source NAT ipaddress, we should NOT be allowed to add LB rule - # 3. On source NAT ipaddress, we should be allowed to add PF rule and - # Fierwall rules. - # 4. On an ipaddress that has PF rules, we should NOT be allowed to - # add a LB rules. - # 5. On an ipaddress that has Lb rules , we should NOT allow firewall - # rules to be programmed. - # 6. On an ipaddress that has Lb rules , we should NOT allow PF rules - # to be programmed. - # 7. We should be allowed to program multiple PF rules on the same Ip - # address on different public ports. - # 8. We should be allowed to program multiple LB rules on the same Ip - # address for different public port ranges. - # 9. On source NAT ipaddress, we should be allowed to Enable VPN. - - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:ON" - ) - self.network_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering_netscaler"], - conservemode=True - ) - self.cleanup.append(self.network_offering) - - self.debug("Created n/w offering with ID: %s" % - self.network_offering.id) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - - src_nat = src_nat_list[0] - - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) - - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT should return a valid port forwarding rules" - ) - self.assertNotEqual( - len(nat_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - self.debug("Creating firewall rule on source NAT: %s" % - src_nat.ipaddress) - #Create Firewall rule on source NAT - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created firewall rule: %s" % fw_rule.id) - - fw_rules = FireWallRule.list( - self.apiclient, - id=fw_rule.id - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "List fw rules should return a valid firewall rules" - ) - - self.assertNotEqual( - len(fw_rules), - 0, - "Length of fw rules response should not be zero" - ) - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_nat_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - - self.debug("Associated %s with network %s" % ( - ip_with_nat_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating PF rule for IP address: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - self.debug("Trying to create LB rule on IP with NAT: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - # Create Load Balancer rule on IP already having NAT rule - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_nat_rule.ipaddress.id, - accountid=self.account.account.name - ) - self.debug("Creating PF rule with public port: 66") - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_port_66"], - ipaddressid=ip_with_nat_rule.ipaddress.id - ) - - # Check if NAT rule created successfully - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return valid list" - ) - - self.debug("Associating public IP for network: %s" % self.network.id) - ip_with_lb_rule = PublicIPAddress.create( - self.apiclient, - accountid=self.account.account.name, - zoneid=self.zone.id, - domainid=self.account.account.domainid, - networkid=self.network.id - ) - self.debug("Associated %s with network %s" % ( - ip_with_lb_rule.ipaddress.ipaddress, - self.network.id - )) - self.debug("Creating LB rule for IP address: %s" % - ip_with_lb_rule.ipaddress.ipaddress) - - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name, - networkid=self.network.id - ) - - self.debug("Trying to create PF rule on IP with LB rule: %s" % - ip_with_nat_rule.ipaddress.ipaddress) - - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=ip_with_lb_rule.ipaddress.id - ) - - self.debug("Trying to create FW rule on IP with LB rule") - with self.assertRaises(Exception): - FireWallRule.create( - self.apiclient, - ipaddressid=src_nat.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - - self.debug("Creating LB rule with public port: 2221") - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule_port_2221"], - ipaddressid=ip_with_lb_rule.ipaddress.id, - accountid=self.account.account.name, - networkid=self.network.id - ) - - # Check if NAT rule created successfully - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - - self.assertEqual( - isinstance(lb_rules, list), - True, - "List LB rules should return valid list" - ) - - # User should be able to enable VPN on source NAT - self.debug("Created VPN with source NAT IP: %s" % src_nat.ipaddress) - # Assign VPN to source NAT - vpn = Vpn.create( - self.apiclient, - src_nat.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - vpns = Vpn.list( - self.apiclient, - publicipid=src_nat.id, - listall=True, - ) - - self.assertEqual( - isinstance(vpns, list), - True, - "List VPNs should return a valid VPN list" - ) - - self.assertNotEqual( - len(vpns), - 0, - "Length of list VNP response should not be zero" - ) - return - - -class TestNetworkUpgrade(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetworkUpgrade, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering - ] - 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.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_nwupgrade_netscaler_conserve_on(self): - """Test Nw upgrade to netscaler lb service and conserve mode ON - """ - - # Validate the following - # 1. Upgrade a network with VR and conserve mode ON TO - # A network that has Lb provided by "Netscaler" and all other - # services provided by "VR" and Conserve mode ON - # 2. Have PF and LB rules on the same ip address. Upgrade network - # should fail. - # 3. Have SourceNat,PF and VPN on the same IP address. Upgrade of - # network should succeed. - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - - src_nat = src_nat_list[0] - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - self.debug("Created LB rule on source NAT: %s" % src_nat.ipaddress) - - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - self.assertEqual( - isinstance(lb_rules, list), - True, - "List lb rules should return a valid lb rules" - ) - self.assertNotEqual( - len(lb_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) - - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT should return a valid port forwarding rules" - ) - self.assertNotEqual( - len(nat_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:ON LB- Netscaler" - ) - ns_lb_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering_netscaler"], - conservemode=True - ) - self.cleanup.append(ns_lb_offering) - ns_lb_offering.update(self.apiclient, state='Enabled') - #Stop all the VMs associated with network to update cidr - self.debug("Stopping the VM: %s" % virtual_machine.name) - virtual_machine.stop(self.apiclient) - - self.debug("Updating network offering for network: %s" % - self.network.id) - with self.assertRaises(Exception): - self.network.update( - self.apiclient, - networkofferingid=ns_lb_offering.id, - changecidr=True - ) - - self.debug("Network upgrade failed!") - self.debug("Deleting LB Rule: %s" % lb_rule.id) - lb_rule.delete(self.apiclient) - self.debug("LB rule deleted") - - # Assign VPN to source NAT - self.debug("Enabling VPN on source NAT") - vpn = Vpn.create( - self.apiclient, - src_nat.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - vpns = Vpn.list( - self.apiclient, - publicipid=src_nat.id, - listall=True, - ) - - self.assertEqual( - isinstance(vpns, list), - True, - "List VPNs should return a valid VPN list" - ) - - self.assertNotEqual( - len(vpns), - 0, - "Length of list VPN response should not be zero" - ) - self.debug("Upgrading the network: %s" % self.network.id) - self.network.update( - self.apiclient, - networkofferingid=ns_lb_offering.id, - changecidr=True - ) - networks = Network.list( - self.apiclient, - id=self.network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List Networks should return a valid list for given network ID" - ) - self.assertNotEqual( - len(networks), - 0, - "Length of list networks should not be 0" - ) - network = networks[0] - self.assertEqual( - network.networkofferingid, - ns_lb_offering.id, - "Network offering ID should match with new offering ID" - ) - return - - def test_02_nwupgrade_netscaler_conserve_off(self): - """Test Nw upgrade to netscaler lb service and conserve mode OFF - """ - - # Validate the following - # 1. Upgrade a network with VR and conserve mode ON TO - # A network that has Lb provided by "Netscaler" and all other - # services provided by "VR" and Conserve mode OFF - # 2. Have PF and LB rules on the same ip address. Upgrade network - # should fail. - # 3. Have SourceNat,PF and VPN on the same IP address. Upgrade of - # network should fail. - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - src_nat_list = PublicIPAddress.list( - self.apiclient, - associatednetworkid=self.network.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - listall=True, - issourcenat=True, - ) - self.assertEqual( - isinstance(src_nat_list, list), - True, - "List Public IP should return a valid source NAT" - ) - self.assertNotEqual( - len(src_nat_list), - 0, - "Length of response from listPublicIp should not be 0" - ) - - src_nat = src_nat_list[0] - self.debug("Trying to create LB rule on source NAT IP: %s" % - src_nat.ipaddress) - # Create Load Balancer rule with source NAT - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=src_nat.id, - accountid=self.account.account.name - ) - self.debug("Created LB rule on source NAT: %s" % src_nat.ipaddress) - - lb_rules = LoadBalancerRule.list( - self.apiclient, - id=lb_rule.id - ) - self.assertEqual( - isinstance(lb_rules, list), - True, - "List lb rules should return a valid lb rules" - ) - self.assertNotEqual( - len(lb_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - - self.debug( - "Trying to create a port forwarding rule in source NAT: %s" % - src_nat.ipaddress) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule"], - ipaddressid=src_nat.id - ) - self.debug("Created PF rule on source NAT: %s" % src_nat.ipaddress) - - nat_rules = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT should return a valid port forwarding rules" - ) - self.assertNotEqual( - len(nat_rules), - 0, - "Length of response from listLbRules should not be 0" - ) - # Create a network offering with all virtual router services enabled - self.debug( - "Creating n/w offering with all services in VR & conserve mode:ON LB- Netscaler" - ) - ns_lb_offering = NetworkOffering.create( - self.api_client, - self.services["network_offering_netscaler"], - conservemode=False - ) - self.cleanup.append(ns_lb_offering) - ns_lb_offering.update(self.apiclient, state='Enabled') - #Stop all the VMs associated with network to update cidr - self.debug("Stopping the VM: %s" % virtual_machine.name) - virtual_machine.stop(self.apiclient) - - self.debug("Updating network offering for network: %s" % - self.network.id) - with self.assertRaises(Exception): - self.network.update( - self.apiclient, - networkofferingid=ns_lb_offering.id, - changecidr=True - ) - - self.debug("Network upgrade failed!") - self.debug("Deleting LB Rule: %s" % lb_rule.id) - lb_rule.delete(self.apiclient) - self.debug("LB rule deleted") - - # Assign VPN to source NAT - self.debug("Enabling VPN on source NAT") - vpn = Vpn.create( - self.apiclient, - src_nat.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - vpns = Vpn.list( - self.apiclient, - publicipid=src_nat.id, - listall=True, - ) - - self.assertEqual( - isinstance(vpns, list), - True, - "List VPNs should return a valid VPN list" - ) - - self.assertNotEqual( - len(vpns), - 0, - "Length of list VPN response should not be zero" - ) - self.debug("Upgrading the network: %s" % self.network.id) - with self.assertRaises(Exception): - self.network.update( - self.apiclient, - networkofferingid=ns_lb_offering.id, - changecidr=True - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_project_configs.py b/tools/testClient/testcase/P1-tests/test_project_configs.py deleted file mode 100644 index eb3a36c4260..00000000000 --- a/tools/testClient/testcase/P1-tests/test_project_configs.py +++ /dev/null @@ -1,1230 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Project -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - - -class Services: - """Test Project Services - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "project": { - "name": "Project", - "displaytext": "Test project", - }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": 'root', - "password": 'fr3sca', - "port": 22, - }, - "account": { - "email": "administrator@clogeny.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "user": { - "email": "administrator@clogeny.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "template": { - "displaytext": "Public Template", - "name": "Public template", - "ostypeid": 'f9b709f2-e0fc-4c0f-80f1-b0494168f58d', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", - "hypervisor": 'XenServer', - "format" : 'VHD', - "isfeatured": True, - "ispublic": True, - "isextractable": True, - }, - "configs": { - "project.invite.timeout": 300, - }, - "mail_account": { - "server": 'imap.gmail.com', - "email": 'administrator@clogeny.com', - "password": 'fr3sca21!', - "folder": 'inbox', - }, - "ostypeid": 'f9b709f2-e0fc-4c0f-80f1-b0494168f58d', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode":'advanced' - } - - -class TestUserProjectCreation(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestUserProjectCreation, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - - # Create domains, account etc. - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls._cleanup = [cls.account, cls.user, cls.domain] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - - def test_01_admin_project_creation(self): - """Test create project as a domain admin and domain user - """ - - # Validate the following - # 1. Check if 'allow.user.create.projects' configuration is true - # 2. Create a Project as domain admin - # 3. Create a Project as domain user - # 4. In both 2 and 3 project creation should be successful - - configs = Configurations.list( - self.apiclient, - name='allow.user.create.projects' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'true', - "'allow.user.create.projects' should be true" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.user.account.name, - domainid=self.user.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain user with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - return - @unittest.skip("Known bug-able to create project as a domain user") - def test_02_user_project_creation(self): - """Test create project as a domain admin and domain user - """ - - # Validate the following - # 1. Check if 'allow.user.create.projects' configuration is false - # 2. Create a Project as domain admin. Project creation should be - # successful. - # 3. Create a Project as domain user. Project creation should fail - - configs = Configurations.list( - self.apiclient, - name='allow.user.create.projects' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'allow.user.create.projects' should be true" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - with self.assertRaises(Exception): - project = Project.create( - self.apiclient, - self.services["project"], - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.debug("Project creation with domain user: %s failed" % - self.user.account.name) - return - - -class TestProjectInviteRequired(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestProjectInviteRequired, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - - # Create domains, account etc. - cls.domain = get_domain(cls.api_client, cls.services) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user = Account.create( - cls.api_client, - cls.services["user"], - admin=True, - domainid=cls.domain.id - ) - - cls._cleanup = [cls.account, cls.user] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - - def test_03_add_user_to_project(self): - """Add user to project when 'project.invite.required' is false""" - - # Validate the following: - # 1. Create a Project - # 2. Add users to the project. Verify user is added to project - # as regular user - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be true" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - - return - - def test_04_add_user_to_project(self): - """Add user to project when 'project.invite.required' is true""" - - # Validate the following: - # 1. Create a Project - # 2. Add users to the project. verify user is shown in pending state - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'true', - "'project.invite.required' should be true" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - return - - def test_05_invitation_timeout(self): - """Test global config project invitation timeout""" - - # Validate the following: - # 1. Set configuration to 5 mins - # 2. Create a Project - # 3. Add users to the project - # 4. As a user accept invitation within 5 mins. Verify invitation is - # accepted and user become regular user of project - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.timeout' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - int(config.value), - self.services["configs"]["project.invite.timeout"], - "'project.invite.timeout' should be %s" % - self.services["configs"]["project.invite.timeout"] - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - - # Accept the invite - ProjectInvitation.update( - self.apiclient, - projectid=project.id, - accept=True, - account=self.user.account.name - ) - self.debug( - "Accepting project invitation for project: %s user: %s" % ( - project.name, - self.user.account.name - )) - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - return - - def test_06_invitation_timeout_after_expiry(self): - """Test global config project invitation timeout""" - - # Validate the following: - # 1. Set configuration to 5 mins - # 2. Create a Project - # 3. Add users to the project - # 4. As a user accept invitation after 5 mins. Verify invitation is - # not accepted and is shown as expired - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.timeout' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - int(config.value), - self.services["configs"]["project.invite.timeout"], - "'project.invite.timeout' should be %s" % - self.services["configs"]["project.invite.timeout"] - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - - # sleep for 'project.invite.timeout' * 2 interval to wait for invite - # to expire - time.sleep(int(config.value) * 2) - - with self.assertRaises(Exception): - # Accept the invite - ProjectInvitation.update( - self.apiclient, - projectid=project.id, - accept=True, - account=self.user.account.name - ) - self.debug( - "Accepting invitation after expiry project: %s user: %s" % ( - project.name, - self.user.account.name - )) - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - account=self.user.account.name, - domainid=self.user.account.domainid - ) - - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Expired', - "Newly added user is not added as a regular user" - ) - return - - def test_07_invite_after_expiry(self): - """Test global config project invitation timeout""" - - # Validate the following: - # 1. Set configuration to 5 mins - # 2. Create a Project - # 3. Add users to the project - # 4. As a user accept invitation after 5 mins. - # 5. Resend the invitation - # 6. Verify invitation is sent again - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.timeout' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - int(config.value), - self.services["configs"]["project.invite.timeout"], - "'project.invite.timeout' should be %s" % - self.services["configs"]["project.invite.timeout"] - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - - # sleep for 'project.invite.timeout' * 2 interval to wait for invite - # to expire - time.sleep(int(config.value) * 2) - - self.debug("Adding %s user again to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - return - - def test_08_decline_invitation(self): - """Test decline invitation""" - - # Validate the following: - # 1. Set configuration to 5 mins - # 2. Create a Project - # 3. Add users to the project - # 4. As a user decline invitation within 5 mins. - # 5. Verify invitation is rejected and user doesn't become regular - # user. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.timeout' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - int(config.value), - self.services["configs"]["project.invite.timeout"], - "'project.invite.timeout' should be %s" % - self.services["configs"]["project.invite.timeout"] - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = ProjectInvitation.list( - self.apiclient, - state='Pending', - account=self.user.account.name, - domainid=self.user.account.domainid - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.state, - 'Pending', - "Newly added user is not added as a regular user" - ) - # Accept the invite - ProjectInvitation.update( - self.apiclient, - projectid=project.id, - accept=False, - account=self.user.account.name - ) - self.debug( - "Declining invitation for project: %s user: %s" % ( - project.name, - self.user.account.name - )) - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.assertEqual( - accounts_reponse, - None, - "Check for a valid list accounts response" - ) - return - @unittest.skip("Requires SMPT configs") - def test_09_invite_to_project_by_email(self): - """Test invite user to project by email""" - - # Validate the following: - # 1. Set configuration to 5 mins - # 2. Create a Project - # 3. Add users to the project - # 4. As a user decline invitation within 5 mins. - # 5. Verify invitation is rejected and user doesn't become regular - # user. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.timeout' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - int(config.value), - self.services["configs"]["project.invite.timeout"], - "'project.invite.timeout' should be %s" % - self.services["configs"]["project.invite.timeout"] - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding user with email: %s to project: %s" % ( - self.user.account.email, - project.name - )) - - # Add user to the project - project.addAccount( - self.apiclient, - email=self.user.account.user[0].email - ) - - # Fetch the latest mail sent to user - mail_content = fetch_latest_mail( - self.services["mail_account"], - from_mail=self.user.account.user[0].email - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_project_limits.py b/tools/testClient/testcase/P1-tests/test_project_limits.py deleted file mode 100644 index cfb4a247e2e..00000000000 --- a/tools/testClient/testcase/P1-tests/test_project_limits.py +++ /dev/null @@ -1,880 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Resource limits -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import datetime - -class Services: - """Test Resource Limits Services - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "project": { - "name": "Project", - "displaytext": "Test project", - }, - "account": { - "email": "administrator@clogeny.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "user": { - "email": "administrator@clogeny.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Tiny Disk Offering", - "name": "Tiny Disk Offering", - "disksize": 1 - }, - "volume": { - "diskname": "Test Volume", - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostypeid": '471a4b5b-5523-448f-9608-7d6218995733', - "templatefilter": 'self', - }, - "ostypeid": '471a4b5b-5523-448f-9608-7d6218995733', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode": 'advanced', - } - - -class TestProjectLimits(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestProjectLimits, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - - # Create domains, account etc. - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.admin = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.user = Account.create( - cls.api_client, - cls.services["user"], - domainid=cls.domain.id - ) - cls._cleanup = [ - cls.admin, - cls.user, - cls.domain - ] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_project_limits(self): - """ Test project limits - """ - - # Validate the following - # 1. Create a Project. Verify once projects are created, they inherit - # a default set of resource limits as configured by the Cloud Stack - # ROOT admin. - # 2. Reduce Project resources limits. Verify limits can be reduced by - # the Project Owner of each project and project limit applies to - # number of virtual instances, disk volumes, snapshots, IP address. - # Also, verify resource limits for the project are independent of - # account resource limits - # 3. Increase Projects Resources limits above domains limit. Verify - # project can’t have more resources than domain level limit allows. - # 4. Create Resource more than its set limit for a project. Verify - # resource allocation should fail giving proper message - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.admin.account.name, - domainid=self.admin.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - # Get the resource limits for ROOT domain - resource_limits = list_resource_limits(self.apiclient) - - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - - # Reduce resource limits for project - # Resource: 0 - Instance. Number of instances a user can create. - # Resource: 1 - IP. Number of public IP addresses a user can own. - # Resource: 2 - Volume. Number of disk volumes a user can create. - # Resource: 3 - Snapshot. Number of snapshots a user can create. - # Resource: 4 - Template. Number of templates that a user can - # register/create - for resource in resource_limits: - update_resource_limit( - self.apiclient, - resource.resourcetype, - max=1, - projectid=project.id - ) - self.debug( - "Updating resource (ID: %s) limit for project: %s" % ( - resource, - project.id - )) - resource_limits = list_resource_limits( - self.apiclient, - projectid=project.id - ) - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - for resource in resource_limits: - self.assertEqual( - resource.max, - 1, - "Resource limit should be updated to 1" - ) - - # Get the resource limits for domain - resource_limits = list_resource_limits( - self.apiclient, - domainid=self.domain.id - ) - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - - for resource in resource_limits: - # Update domain resource limits to 2 - update_resource_limit( - self.apiclient, - resource.resourcetype, - domainid=self.domain.id, - max=2 - ) - with self.assertRaises(Exception): - self.debug( - "Attempting to update project: %s resource limit to: %s" % ( - project.id, - max_value - )) - # Update project resource limits to 3 - update_resource_limit( - self.apiclient, - resource.resourcetype, - max=3, - projectid=project.id - ) - return - @unittest.skip("No provision for updating resource limits from account through API") - def test_02_project_limits_normal_user(self): - """ Test project limits - """ - - # Validate the following - # 1. Create a Project - # 2. Reduce the projects limits as a domain admin. Verify resource - # count is updated - # 3. Reduce the projects limits as a project user owner who is not a - # domain admin. Resource count should fail - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.admin.account.name, - domainid=self.admin.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - # Get the resource limits for ROOT domain - resource_limits = list_resource_limits(self.apiclient) - - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - - # Reduce resource limits for project - # Resource: 0 - Instance. Number of instances a user can create. - # Resource: 1 - IP. Number of public IP addresses a user can own. - # Resource: 2 - Volume. Number of disk volumes a user can create. - # Resource: 3 - Snapshot. Number of snapshots a user can create. - # Resource: 4 - Template. Number of templates that a user can - # register/create - for resource in resource_limits: - update_resource_limit( - self.apiclient, - resource.resourcetype, - max=1, - projectid=project.id - ) - self.debug( - "Updating resource (ID: %s) limit for project: %s" % ( - resource, - project.id - )) - resource_limits = list_resource_limits( - self.apiclient, - projectid=project.id - ) - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - for resource in resource_limits: - self.assertEqual( - resource.max, - 1, - "Resource limit should be updated to 1" - ) - - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - ) - - # Get the resource limits for domain - resource_limits = list_resource_limits( - self.apiclient, - domainid=self.domain.id - ) - self.assertEqual( - isinstance(resource_limits, list), - True, - "List resource API should return a valid list" - ) - self.assertNotEqual( - len(resource_limits), - 0, - "List resource API response should not be empty" - ) - - for resource in resource_limits: - #with self.assertRaises(Exception): - self.debug( - "Attempting to update resource limit by user: %s" % ( - self.user.account.name - )) - # Update project resource limits to 3 - update_resource_limit( - self.apiclient, - resource.resourcetype, - account=self.user.account.name, - domainid=self.user.account.domainid, - max=3, - projectid=project.id - ) - return - - -class TestResourceLimitsProject(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestResourceLimitsProject, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Domains, Account etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["account"] = cls.account.account.name - - # Create Service offering and disk offerings etc - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls._cleanup = [ - cls.project, - cls.service_offering, - cls.disk_offering, - cls.account, - cls.domain - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_03_vm_per_project(self): - """Test VM limit per project - """ - - # Validate the following - # 1. Set max VM per project to 2 - # 2. Create account and start 2 VMs. Verify VM state is Up and Running - # 3. Try to create 3rd VM instance. The appropriate error or alert - # should be raised - - self.debug( - "Updating instance resource limits for project: %s" % - self.project.id) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 0, # Instance - max=2, - projectid=self.project.id - ) - - self.debug("Deploying VM for project: %s" % self.project.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug("Deploying VM for project: %s" % self.project.id) - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - # Exception should be raised for second instance - with self.assertRaises(Exception): - VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - return - - def test_04_publicip_per_project(self): - """Test Public IP limit per project - """ - - # Validate the following - # 1. set max no of IPs per project to 2. - # 2. Create an account in this domain - # 3. Create 1 VM in this domain - # 4. Acquire 1 IP in the domain. IP should be successfully acquired - # 5. Try to acquire 3rd IP in this domain. It should give the user an - # appropriate error and an alert should be generated. - - self.debug( - "Updating public IP resource limits for project: %s" % - self.project.id) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 1, # Public Ip - max=2, - projectid=self.project.id - ) - - self.debug("Deploying VM for Project: %s" % self.project.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - networks = Network.list( - self.apiclient, - projectid=self.project.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check list networks response returns a valid response" - ) - self.assertNotEqual( - len(networks), - 0, - "Check list networks response returns a valid network" - ) - network = networks[0] - self.debug("Associating public IP for project: %s" % - self.project.id) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - zoneid=virtual_machine_1.zoneid, - services=self.services["server"], - networkid=network.id, - projectid=self.project.id - ) - self.cleanup.append(public_ip_1) - # Verify Public IP state - self.assertEqual( - public_ip_1.ipaddress.state in [ - 'Allocated', - 'Allocating' - ], - True, - "Check Public IP state is allocated or not" - ) - - # Exception should be raised for second Public IP - with self.assertRaises(Exception): - public_ip_2 = PublicIPAddress.create( - self.apiclient, - zoneid=virtual_machine_1.zoneid, - services=self.services["server"], - networkid=network.id, - projectid=self.project.id - ) - return - - def test_05_snapshots_per_project(self): - """Test Snapshot limit per project - """ - - # Validate the following - # 1. set max no of snapshots per project to 1. - # 2. Create one snapshot in the project. Snapshot should be - # successfully created - # 5. Try to create another snapshot in this project. It should give - # user an appropriate error and an alert should be generated. - - self.debug( - "Updating snapshot resource limits for project: %s" % - self.project.id) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 3, # Snapshot - max=1, - projectid=self.project.id - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a snapshot from the ROOTDISK - snapshot_1 = Snapshot.create(self.apiclient, - volumes[0].id, - projectid=self.project.id - ) - self.cleanup.append(snapshot_1) - # Verify Snapshot state - self.assertEqual( - snapshot_1.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - - # Exception should be raised for second snapshot - with self.assertRaises(Exception): - Snapshot.create(self.apiclient, - volumes[0].id, - projectid=self.project.id - ) - return - - def test_06_volumes_per_project(self): - """Test Volumes limit per project - """ - - # Validate the following - # 1. set max no of volume per project to 1. - # 2. Create 1 VM in this project - # 4. Try to Create another VM in the project. It should give the user - # an appropriate error that Volume limit is exhausted and an alert - # should be generated. - - self.debug( - "Updating volume resource limits for project: %s" % - self.project.id) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 2, # Volume - max=2, - projectid=self.project.id - ) - - self.debug("Deploying VM for project: %s" % self.project.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - # Exception should be raised for second volume - with self.assertRaises(Exception): - Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - diskofferingid=self.disk_offering.id, - projectid=self.project.id - ) - return - - def test_07_templates_per_project(self): - """Test Templates limit per project - """ - - # Validate the following - # 1. set max no of templates per project to 1. - # 2. Create a template in this project. Both template should be in - # ready state - # 3. Try create 2nd template in the project. It should give the user - # appropriate error and an alert should be generated. - - # Reset the volume limits - update_resource_limit( - self.apiclient, - 2, # Volume - max=5, - projectid=self.project.id - ) - self.debug( - "Updating template resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 4, # Template - max=1, - projectid=self.project.id - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - projectid=self.project.id - ) - - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( - template_1.isready, - True, - "Check Template is in ready state or not" - ) - - # Exception should be raised for second template - with self.assertRaises(Exception): - Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - projectid=self.project.id - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_project_resources.py b/tools/testClient/testcase/P1-tests/test_project_resources.py deleted file mode 100644 index 1a6dc17643b..00000000000 --- a/tools/testClient/testcase/P1-tests/test_project_resources.py +++ /dev/null @@ -1,1313 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Resource creation -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import datetime - -class Services: - """Test Resource creation Services - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "project": { - "name": "Project", - "displaytext": "Test project", - }, - "account": { - "email": "administrator@clogeny.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "user": { - "email": "administrator@clogeny.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Tiny Disk Offering", - "name": "Tiny Disk Offering", - "disksize": 1 - }, - "volume": { - "diskname": "Test Volume", - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "templatefilter": 'self', - "ispublic": False, - }, - "network": { - "name": "Test Network", - "displaytext": "Test Network", - }, - "domain_network": { - "name": "Domainwide Network", - "displaytext": "Domainwide Network", - "gateway": '192.168.100.1', - "netmask": '255.255.255.0', - "startip": '192.168.100.200', - "endip": '192.168.100.201', - "vlan": 4001, - "acltype": 'domain' - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "lbrule": { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - }, - "fw_rule": { - "startport": 1, - "endport": 6000, - "cidr": '55.55.0.0/11', - # Any network (For creating FW rule) - }, - "security_group": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.0/0', - }, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode": 'advanced', - } - - -class TestOfferings(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestOfferings, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone and template - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create domains, account etc. - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain.id - ) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls._cleanup = [ - cls.account, - cls.service_offering, - cls.disk_offering - ] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_service_offerings(self): - """ Test service offerings in a project - """ - - # Validate the following - # 1. Create a project. - # 2. List service offerings for the project. All SO available in the - # domain can be used for project resource creation. - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - self.debug( - "Deploying VM instance for project: %s & service offering: %s" % ( - project.id, - self.service_offering.id - )) - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=project.id - ) - # Verify VM state - self.assertEqual( - virtual_machine.state, - 'Running', - "Check VM state is Running or not" - ) - - return - - def test_02_project_disk_offerings(self): - """ Test project disk offerings - """ - - # Validate the following - # 1. Create a project. - # 2. List service offerings for the project. All disk offerings - # available in the domain can be used for project resource creation - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug( - "Create a data volume for project: %s" % project.id) - # Create a volume for project - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - diskofferingid=self.disk_offering.id, - projectid=project.id - ) - self.cleanup.append(volume) - # Verify Volume state - self.assertEqual( - volume.state in [ - 'Allocated', - 'Ready' - ], - True, - "Check Volume state is Ready or not" - ) - return - - -class TestNetwork(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetwork, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone and template - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create domains, account etc. - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain.id - ) - cls._cleanup = [ - cls.account, - cls.service_offering, - ] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_03_network_create(self): - """ Test create network in project - """ - - # Validate the following - # 1. Create a project. - # 2. Add virtual/direct network resource to the project. User shared - # network resource for the project - # 3. Verify any number of Project level Virtual/Direct networks can be - # created and used for vm deployment within the project. - # 4. Verify shared networks (zone and domain wide) from outside the - # project can also be used in a project. - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - network_offerings = list_network_offerings( - self.apiclient, - projectid=project.id, - supportedServices='SourceNat', - type='isolated', - state='Enabled' - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "Check for the valid network offerings" - ) - network_offering = network_offerings[0] - - self.debug("creating a network with network offering ID: %s" % - network_offering.id) - self.services["network"]["zoneid"] = self.zone.id - network = Network.create( - self.apiclient, - self.services["network"], - networkofferingid=network_offering.id, - projectid=project.id - ) - self.debug("Created network with ID: %s" % network.id) - networks= Network.list( - self.apiclient, - projectid=project.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check for the valid network list response" - ) - network_response = networks[0] - - self.debug("Deploying VM with network: %s" % network.id) - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - networkids=[str(network.id)], - serviceofferingid=self.service_offering.id, - projectid=project.id - ) - self.debug("Deployed VM with ID: %s" % virtual_machine.id) - # Verify VM state - self.assertEqual( - virtual_machine.state, - 'Running', - "Check VM state is Running or not" - ) - - network_offerings = list_network_offerings( - self.apiclient, - state='Enabled', - guestiptype='Shared', - name='DefaultSharedNetworkOffering', - displaytext='Offering for Shared networks' - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "Check for the valid network offerings" - ) - network_offering = network_offerings[0] - - self.debug("creating a shared network in domain: %s" % - self.domain.id) - domain_network = Network.create( - self.apiclient, - self.services["domain_network"], - domainid=self.domain.id, - networkofferingid=network_offering.id, - zoneid=self.zone.id - ) - self._cleanup.append(domain_network) - self.debug("Created network with ID: %s" % domain_network.id) - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - networkids=[str(domain_network.id)], - serviceofferingid=self.service_offering.id, - projectid=project.id - ) - self.debug("Deployed VM with ID: %s" % virtual_machine.id) - # Verify VM state - self.assertEqual( - virtual_machine.state, - 'Running', - "Check VM state is Running or not" - ) - return - - -class TestTemplates(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestTemplates, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Domains, Account etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.user = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["account"] = cls.account.account.name - - # Create Service offering and disk offerings etc - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [ - cls.project, - cls.service_offering, - cls.account, - cls.user, - cls.domain - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_04_public_template_use_in_project(self): - """Test Templates creation in projects - """ - - # Validate the following - # 1. Create a project - # 2. Verify Public templates can be used without any restriction - # 3. Verify that template created in project can be used in project - # without any restrictions - - self.debug("Deploying VM for with public template: %s" % - self.template.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - projectid=self.project.id - ) - - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( - template_1.isready, - True, - "Check Template is in ready state or not" - ) - return - - def test_05_use_private_template_in_project(self): - """Test use of private template in a project - """ - - # Validate the following - # 1. Create a project - # 2. Verify that in order to use somebody’s Private template for vm - # creation in the project, permission to use the template has to - # be granted to the Project (use API “updateTemplatePermissions” - # with project id to achieve that). - - self.debug("Deploying VM for with public template: %s" % - self.template.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug("Stopping the VM: %s" % virtual_machine_1.id) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - projectid=self.project.id - ) - - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( - template_1.isready, - True, - "Check Template is in ready state or not" - ) - - # Update template permissions to grant permission to project - self.debug( - "Updating template permissions:%s to grant access to project: %s" % ( - template_1.id, - self.project.id - )) - - template_1.updatePermissions( - self.apiclient, - op='add', - projectids=self.project.id - ) - self.debug("Deploying VM for with privileged template: %s" % - self.template.id) - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=template_1.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - return - - -class TestSnapshots(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestSnapshots, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Domains, Account etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["account"] = cls.account.account.name - - # Create Service offering and disk offerings etc - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [ - cls.project, - cls.service_offering, - cls.account, - cls.domain - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_06_create_snapshots_in_project(self): - """Test create snapshots in project - """ - - # Validate the following - # 1. Create a project - # 2. Add some snapshots to the project - # 3. Verify snapshot created inside project can only be used in inside - # the project - - self.debug("Deploying VM for Project: %s" % self.project.id) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a snapshot from the ROOTDISK - snapshot = Snapshot.create(self.apiclient, - volumes[0].id, - projectid=self.project.id - ) - self.cleanup.append(snapshot) - # Verify Snapshot state - self.assertEqual( - snapshot.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - - snapshots = Snapshot.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - snapshots, - None, - "Snapshots should not be available outside the project" - ) - return - - -class TestPublicIpAddress(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestPublicIpAddress, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Domains, Account etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["account"] = cls.account.account.name - - # Create Service offering and disk offerings etc - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=cls.template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - - cls._cleanup = [ - cls.project, - cls.service_offering, - cls.account, - cls.domain - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_07_associate_public_ip(self): - """Test associate public IP within the project - """ - - # Validate the following - # 1. Create a project - # 2. Add some public Ips to the project - # 3. Verify public IP assigned can only used to create PF/LB rules - # inside project - - networks = Network.list( - self.apiclient, - projectid=self.project.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check list networks response returns a valid response" - ) - self.assertNotEqual( - len(networks), - 0, - "Check list networks response returns a valid network" - ) - network = networks[0] - self.debug("Associating public IP for project: %s" % self.project.id) - public_ip = PublicIPAddress.create( - self.apiclient, - zoneid=self.virtual_machine.zoneid, - services=self.services["server"], - networkid=network.id, - projectid=self.project.id - ) - self.cleanup.append(public_ip) - - #Create NAT rule - self.debug( - "Creating a NAT rule within project, VM ID: %s" % - self.virtual_machine.id) - nat_rule = NATRule.create( - self.apiclient, - self.virtual_machine, - self.services["natrule"], - public_ip.ipaddress.id, - projectid=self.project.id - ) - self.debug("created a NAT rule with ID: %s" % nat_rule.id) - nat_rule_response = NATRule.list( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rule_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(nat_rule_response), - 0, - "Check Port Forwarding Rule is created" - ) - self.assertEqual( - nat_rule_response[0].id, - nat_rule.id, - "Check Correct Port forwarding Rule is returned" - ) - - #Create Load Balancer rule and assign VMs to rule - self.debug("Created LB rule for public IP: %s" % - public_ip.ipaddress.ipaddress) - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - public_ip.ipaddress.id, - projectid=self.project.id - ) - self.cleanup.append(lb_rule) - self.debug("Assigning VM: %s to LB rule: %s" % ( - self.virtual_machine.name, - lb_rule.id - )) - lb_rule.assign(self.apiclient, [self.virtual_machine]) - - lb_rules = list_lb_rules( - self.apiclient, - id=lb_rule.id - ) - self.assertEqual( - isinstance(lb_rules, list), - True, - "Check list response returns a valid list" - ) - #verify listLoadBalancerRules lists the added load balancing rule - self.assertNotEqual( - len(lb_rules), - 0, - "Check Load Balancer Rule in its List" - ) - self.assertEqual( - lb_rules[0].id, - lb_rule.id, - "Check List Load Balancer Rules returns valid Rule" - ) - - #Create Firewall rule with configurations from settings file - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"], - projectid=self.project.id - ) - self.debug("Created firewall rule: %s" % fw_rule.id) - - # After Router start, FW rule should be in Active state - fw_rules = FireWallRule.list( - self.apiclient, - id=fw_rule.id, - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "Check for list FW rules response return valid data" - ) - - self.assertEqual( - fw_rules[0].state, - 'Active', - "Check list load balancing rules" - ) - self.assertEqual( - fw_rules[0].startport, - str(self.services["fw_rule"]["startport"]), - "Check start port of firewall rule" - ) - - self.assertEqual( - fw_rules[0].endport, - str(self.services["fw_rule"]["endport"]), - "Check end port of firewall rule" - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - ) - self.cleanup.append(virtual_machine_1) - - self.debug("VM state after deploy: %s" % virtual_machine_1.state) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug("Creating NAT rule for VM (ID: %s) outside project" % - virtual_machine_1.id) - with self.assertRaises(Exception): - NATRule.create( - self.apiclient, - virtual_machine_1, - self.services["natrule"], - public_ip.ipaddress.id, - ) - - self.debug("Creating LB rule for public IP: %s outside project" % - public_ip.ipaddress.ipaddress) - with self.assertRaises(Exception): - LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - public_ip.ipaddress.id, - accountid=self.account.account.name - ) - self.debug( - "Creating firewall rule for public IP: %s outside project" % - public_ip.ipaddress.ipaddress) - with self.assertRaises(Exception): - FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"], - ) - return - - -class TestSecurityGroup(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super( - TestSecurityGroup, - cls - ).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["server"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["account"] = cls.account.account.name - - cls._cleanup = [ - cls.project, - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestSecurityGroup, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_08_security_group(self): - """Test security groups in project - """ - - # Validate the following: - # 1. Create a project - # 2. Assign some security groups to that project - # 3. Verify the security groups can only be assigned to VM belonging - # to that project. - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - projectid=self.project.id - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - projectid=self.project.id - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertNotEqual( - len(sercurity_groups), - 0, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - projectid=self.project.id - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.debug( - "Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id], - projectid=self.project.id - ) - self.debug("Deployed VM (ID: %s) in project: %s" % ( - self.virtual_machine.id, - self.project.id - )) - self.assertEqual( - self.virtual_machine.state, - 'Running', - "VM state should be running after deployment" - ) - # Deploy another VM with same security group outside the project - self.debug( - "Deploying VM with security group: %s outside project:%s" % ( - security_group.id, - self.project.id - )) - with self.assertRaises(Exception): - VirtualMachine.create( - self.apiclient, - self.services["server"], - serviceofferingid=self.service_offering.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - securitygroupids=[security_group.id], - ) - return \ No newline at end of file diff --git a/tools/testClient/testcase/P1-tests/test_project_usage.py b/tools/testClient/testcase/P1-tests/test_project_usage.py deleted file mode 100644 index be1e801f9bb..00000000000 --- a/tools/testClient/testcase/P1-tests/test_project_usage.py +++ /dev/null @@ -1,1710 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Snapshots -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "project": { - "name": "Project", - "displaytext": "Test project", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "volume": { - "diskname": "TestDiskServ", - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "templates": { - "displaytext": 'Template', - "name": 'Template', - "ostypeid": '471a4b5b-5523-448f-9608-7d6218995733', - "templatefilter": 'self', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.qcow2.bz2" - }, - "iso": { - "displaytext": "Test ISO", - "name": "Test ISO", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostypeid": '471a4b5b-5523-448f-9608-7d6218995733', - }, - "lbrule": { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "vpn_user": { - "username": "test", - "password": "test", - }, - "ostypeid": '471a4b5b-5523-448f-9608-7d6218995733', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode":'advanced' - } - - -class TestVmUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVmUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vm_usage(self): - """Test Create/Destroy VM and verify usage calculation - """ - - # Validate the following - # 1. Create a VM. Verify usage_events table contains VM .create, - # VM.start , Network.offering.assign , Volume.create events - # 2. Stop the VM. Verify usage_events table contains - # network.offerings.remove ,VM .stop Events for the created account. - # 3. Destroy the VM after some time. Verify usage_events table contains - # VM.Destroy and volume .delete Event for the created account - # 4. Delete the account - - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop the VM - self.virtual_machine.stop(self.apiclient) - - time.sleep(self.services["sleep"]) - # Destroy the VM - self.debug("Destroying the VM: %s" % self.virtual_machine.id) - self.virtual_machine.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - # Check if VM.CREATE, VM.DESTROY events present in usage_event table - self.assertEqual( - qresult.count('VM.START'), - 1, - "Check VM.START event in events table" - ) - - self.assertEqual( - qresult.count('NETWORK.OFFERING.ASSIGN'), - 1, - "Check NETWORK.OFFERING.ASSIGN in events table" - ) - self.assertEqual( - qresult.count('VM.CREATE'), - 1, - "Check VM.CREATE in list events" - ) - - self.assertEqual( - qresult.count('VOLUME.CREATE'), - 1, - "Check VOLUME.CREATE in events table" - ) - - self.assertEqual( - qresult.count('VM.STOP'), - 1, - "Check VM.STOP in events table" - ) - - self.assertEqual( - qresult.count('NETWORK.OFFERING.REMOVE'), - 1, - "Check NETWORK.OFFERING.REMOVE in list events" - ) - - self.assertEqual( - qresult.count('VM.DESTROY'), - 1, - "Check VM.DESTROY in events table" - ) - - self.assertEqual( - qresult.count('VOLUME.DELETE'), - 1, - "Check VOLUME.DELETE in events table" - ) - return - - -class TestPublicIPUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestPublicIPUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = cls.template.id - - # Create VMs, Assign Public IP etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=cls.template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - networks = Network.list( - cls.api_client, - projectid=cls.project.id, - listall=True - ) - if isinstance(networks, list): - network = networks[0] - else: - raise Exception("List networks call failed") - - cls.public_ip = PublicIPAddress.create( - cls.api_client, - zoneid=cls.zone.zoneid, - services=cls.services["server"], - networkid=network.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_public_ip_usage(self): - """Test Assign new IP and verify usage calculation - """ - - # Validate the following - # 1. Acquire a IP for the network of this account. Verify usage_event - # table has Acquire IP event for the IP for this account - # 2. Release one of the IP of this account. Verify usage_event table - # has IP.Release event for released IP for this account - # 3. Delete the newly created account - - self.debug("Deleting public IP: %s" % - self.public_ip.ipaddress.ipaddress) - - # Release one of the IP - self.public_ip.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - # Check if NET.IPASSIGN, NET.IPRELEASE events present in usage_event - # table - self.assertEqual( - qresult.count('NET.IPASSIGN') > 0, - True, - "Check NET.IPASSIGN event in events table" - ) - - self.assertEqual( - qresult.count('NET.IPRELEASE') > 0, - True, - "Check NET.IPRELEASE in events table" - ) - return - - -class TestVolumeUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVolumeUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["server"]["diskoffering"] = cls.disk_offering.id - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_offering, - cls.disk_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, terminate the created instance, volumes - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_volume_usage(self): - """Test Create/delete a volume and verify correct usage is recorded - """ - - # Validate the following - # 1. Volume.create event for both root and data disk is there for the - # created account in cloud.usage_event table - # 2. Stop the VM - # 3. Detach the data disk from this VM - # 4. Destroy the Data disk. Volume.delete event is generated for data - # disk of the destroyed VM - - # Stop VM - self.debug("Stopping VM with ID: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - volume_response = list_volumes( - self.apiclient, - projectid=self.project.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(volume_response, list), - True, - "Check for valid list volumes response" - ) - data_volume = volume_response[0] - - # Detach data Disk - self.debug("Detaching volume ID: %s VM with ID: %s" % ( - data_volume.id, - self.virtual_machine.id - )) - self.virtual_machine.detach_volume(self.apiclient, data_volume) - - # Delete Data disk - self.debug("Delete volume ID: %s" % data_volume.id) - cmd = deleteVolume.deleteVolumeCmd() - cmd.id = data_volume.id - self.apiclient.deleteVolume(cmd) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - # Check VOLUME.CREATE, VOLUME.DESTROY events in cloud.usage_event table - self.assertEqual( - qresult.count('VOLUME.CREATE'), - 2, - "Check VOLUME.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('VOLUME.DELETE'), - 1, - "Check VOLUME.DELETE in events table" - ) - return - - -class TestTemplateUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestTemplateUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["server"]["zoneid"] = cls.zone.id - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = list_volumes( - cls.api_client, - projectid=cls.project.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - cls.volume = list_volume[0] - else: - raise Exception("List Volumes failed!") - cls._cleanup = [ - cls.project, - 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, terminate the created instance, templates - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_template_usage(self): - """Test Upload/ delete a template and verify correct usage is generated - for the template uploaded - """ - - # Validate the following - # 1. Create a account - # 2. Upload a template from this account. template.create event is - # recorded in cloud.usage_event table for this account - # 3. Delete the template. template.delete event is recorded in - # cloud.usage_event tables for this account - # 4. Destroy the account - - #Create template from Virtual machine and Volume ID - self.template = Template.create( - self.apiclient, - self.services["templates"], - self.volume.id, - projectid=self.project.id - ) - self.debug("Created template with ID: %s" % self.template.id) - # Delete template - self.template.delete(self.apiclient) - self.debug("Deleted template with ID: %s" % self.template.id) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for TEMPLATE.CREATE, TEMPLATE.DELETE in cloud.usage_event table - self.assertEqual( - qresult.count('TEMPLATE.CREATE'), - 1, - "Check TEMPLATE.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('TEMPLATE.DELETE'), - 1, - "Check TEMPLATE.DELETE in events table" - ) - return - - -class TestISOUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestISOUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["iso"]["zoneid"] = cls.zone.id - # Create Account, ISO image etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.iso = Iso.create( - cls.api_client, - cls.services["iso"], - projectid=cls.project.id - ) - try: - # Wait till ISO gets downloaded - cls.iso.download(cls.api_client) - except Exception as e: - raise Exception("%s: Failed to download ISO: %s" % ( - e, - cls.iso.id - )) - cls._cleanup = [ - cls.project, - 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, terminate the created ISO images - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_ISO_usage(self): - """Test Create/Delete a ISO and verify its usage is generated correctly - """ - - # Validate the following - # 1. Create a account - # 2. Upload a ISO from this account. ISO.create event is recorded in - # cloud.usage_event table for this account - # 3. Delete the ISO. ISO.delete event is recorded in cloud.usage_event - # tables for this account - # 4. Destroy the account - - # Delete the ISO - self.debug("Deleting ISO with ID: %s" % self.iso.id) - self.iso.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for ISO.CREATE, ISO.DELETE events in cloud.usage_event table - self.assertEqual( - qresult.count('ISO.CREATE'), - 1, - "Check ISO.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('ISO.DELETE'), - 1, - "Check ISO.DELETE in events table" - ) - return - - -class TestLBRuleUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestLBRuleUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, LB Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - networks = Network.list( - cls.api_client, - projectid=cls.project.id, - listall=True - ) - if isinstance(networks, list): - network = networks[0] - else: - raise Exception("List networks call failed") - - cls.public_ip_1 = PublicIPAddress.create( - cls.api_client, - zoneid=cls.zone.zoneid, - services=cls.services["server"], - networkid=network.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance, LB rules - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_lb_usage(self): - """Test Create/Delete a LB rule and verify correct usage is recorded - """ - - # Validate the following - # 1. Acquire a IP for this account. lb.rule.create event is registered - # for this account in cloud.usage_event table - # 2. Create a LB rule on the IP associated with this account - # 3. Delete the created LB rule from the account. lb.rule.delete event - # is registered for this account in cloud.usage_event table - # 4. Delete this account. - - self.debug( - "Creating load balancer rule for public IP: %s" % - self.public_ip_1.ipaddress.id) - #Create Load Balancer rule and assign VMs to rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - self.public_ip_1.ipaddress.id, - projectid=self.project.id - ) - # Delete LB Rule - self.debug("Deleting LB rule with ID: %s" % lb_rule.id) - lb_rule.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for LB.CREATE, LB.DELETE in cloud.usage_event table - self.assertEqual( - qresult.count('LB.CREATE'), - 1, - "Check LB.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('LB.DELETE'), - 1, - "Check LB.DELETE in events table" - ) - return - - -class TestSnapshotUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestSnapshotUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_snapshot_usage(self): - """Test Create/Delete a manual snap shot and verify - correct usage is recorded - """ - - # Validate the following - # 1. Create snapshot of the root disk for this account.Snapshot.create - # event is there for the created account in cloud.usage_event table - # 2. Destroy the snapshot after some time. Snapshot.delete event is - # generated for the destroyed Snapshot - # 3. Delete the account - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - projectid=self.project.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check if list volumes return a valid data" - ) - - volume = volumes[0] - - # Create a snapshot from the ROOTDISK - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - - # Delete snapshot Rule - self.debug("Deleting snapshot: %s" % snapshot.id) - snapshot.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check if database query returns a valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query Result: %s" % qresult) - - # Check for SNAPSHOT.CREATE, SNAPSHOT.DELETE events in cloud.usage_event - # table - self.assertEqual( - qresult.count('SNAPSHOT.CREATE'), - 1, - "Check SNAPSHOT.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('SNAPSHOT.DELETE'), - 1, - "Check SNAPSHOT.DELETE in events table" - ) - return - - -class TestNatRuleUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNatRuleUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - networks = Network.list( - cls.api_client, - projectid=cls.project.id, - listall=True - ) - if isinstance(networks, list): - network = networks[0] - else: - raise Exception("List networks call failed") - - cls.public_ip_1 = PublicIPAddress.create( - cls.api_client, - zoneid=cls.zone.zoneid, - services=cls.services["server"], - networkid=network.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance, NAT rules - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_nat_usage(self): - """Test Create/Delete a PF rule and verify correct usage is recorded - """ - - # Validate the following - # 1. Acquire a IP for this account - # 2. Create a PF rule on the IP associated with this account. - # NET.RULEADD event is registered for this account in - # cloud.usage_event table - # 3. Delete the created PF rule from the account. NET.RULEDelete event - # is registered for this account in cloud.usage_event table - # 4. Delete this account. - - self.debug("Creating NAT rule with public IP: %s" % - self.public_ip_1.ipaddress.id) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - self.virtual_machine, - self.services["natrule"], - self.public_ip_1.ipaddress.id - ) - - # Delete NAT Rule - self.debug("Deleting NAT rule: %s" % nat_rule.id) - nat_rule.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for NET.RULEADD, NET.RULEDELETE in cloud.usage_event table - self.assertEqual( - qresult.count('NET.RULEADD'), - 1, - "Check NET.RULEADD event in events table" - ) - - self.assertEqual( - qresult.count('NET.RULEDELETE'), - 1, - "Check NET.RULEDELETE in events table" - ) - return - - -class TestVpnUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVpnUsage, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Service offerings, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - serviceofferingid=cls.service_offering.id, - projectid=cls.project.id - ) - networks = Network.list( - cls.api_client, - projectid=cls.project.id, - listall=True - ) - if isinstance(networks, list): - network = networks[0] - else: - raise Exception("List networks call failed") - - cls.public_ip = PublicIPAddress.create( - cls.api_client, - zoneid=cls.zone.zoneid, - services=cls.services["server"], - networkid=network.id, - projectid=cls.project.id - ) - cls._cleanup = [ - cls.project, - cls.service_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, terminate the created instance, VPN users - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vpn_usage(self): - """Test Create/Delete a VPN and verify correct usage is recorded - """ - - # Validate the following - # 1. Enable VPN for this IP. vpn.add.user event is registered for this - # account in cloud.usage_event table - # 2. Add user to this vpn - # 3. Delete user for this VPN. vpn.user.delete event is registered for - # this account in cloud.usage_event table - # 4. Delete this account. - - self.debug("Created VPN with public IP: %s" % - self.public_ip.ipaddress.id) - #Assign VPN to Public IP - vpn = Vpn.create( - self.apiclient, - self.public_ip.ipaddress.id, - projectid=self.project.id - ) - - self.debug("Created VPN user for account: %s" % - self.account.account.name) - - vpnuser = VpnUser.create( - self.apiclient, - self.services["vpn_user"]["username"], - self.services["vpn_user"]["password"], - projectid=self.project.id - ) - - # Remove VPN user - self.debug("Deleting VPN user: %s" % vpnuser.id) - vpnuser.delete(self.apiclient) - - # Delete VPN access - self.debug("Deleting VPN: %s" % vpn.publicipid) - vpn.delete(self.apiclient) - - # Fetch project account ID from project UUID - self.debug( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id) - - qresultset = self.dbclient.execute( - "select project_account_id from projects where uuid = '%s';" \ - % self.project.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for VPN user related events - self.assertEqual( - qresult.count('VPN.USER.ADD'), - 1, - "Check VPN.USER.ADD event in events table" - ) - - self.assertEqual( - qresult.count('VPN.USER.ADD'), - 1, - "Check VPN.USER.ADD in events table" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_projects.py b/tools/testClient/testcase/P1-tests/test_projects.py deleted file mode 100644 index aee9070e583..00000000000 --- a/tools/testClient/testcase/P1-tests/test_projects.py +++ /dev/null @@ -1,1808 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Project -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - - -class Services: - """Test Project Services - """ - - def __init__(self): - self.services = { - "domain": { - "name": "Domain", - }, - "project": { - "name": "Project", - "displaytext": "Test project", - }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": 'root', - "password": 'fr3sca', - "port": 22, - }, - "account": { - "email": "administrator@clogeny.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "user": { - "email": "administrator@clogeny.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "disk_offering": { - "displaytext": "Tiny Disk Offering", - "name": "Tiny Disk Offering", - "disksize": 1 - }, - "volume": { - "diskname": "Test Volume", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "virtual_machine": { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "ostypeid": '8531d1df-faac-4895-a741-238d3b10e6e6', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode":'advanced' - } - - -class TestMultipleProjectCreation(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestMultipleProjectCreation, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - - # Create domains, account etc. - cls.domain = get_domain( - cls.api_client, - cls.services - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls._cleanup = [cls.account, cls.user] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_create_multiple_projects_by_account(self): - """ Verify an account can own multiple projects and can belong to - multiple projects - """ - - # Validate the following - # 1. Create multiple project. Verify at step 1 An account is allowed - # to create multiple projects - # 2. add one account to multiple project. Verify at step 2 an account - # is allowed to added to multiple project - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project_1 = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project_1) - self.debug("Created project with domain admin with ID: %s" % - project_1.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project_1.id, - listall=True - ) - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project_1.name, - list_project.name, - "Check project name from list response" - ) - # Create another project as a domain admin - project_2 = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project_2) - self.debug("Created project with domain user with ID: %s" % - project_2.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project_2.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - # Add user to the project - project_1.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project_1.id, - account=self.user.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - # Add user to the project - project_2.addAccount( - self.apiclient, - self.user.account.name, - self.user.account.email - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project_2.id, - account=self.user.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - return - - -class TestCrossDomainAccountAdd(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestCrossDomainAccountAdd, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - cls.domain = get_domain( - cls.api_client, - cls.services - ) - - # Create domains, account etc. - cls.new_domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.user = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.new_domain.id - ) - - cls._cleanup = [cls.account, cls.user] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_02_cross_domain_account_add(self): - """ Verify No cross domain projects - """ - - # Validate the following - # 1. Create a project in a domain. - # 2. Add different domain account to the project. Add account should - # fail - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - - self.debug("Adding user: %s from domain: %s to project: %s" %( - self.user.account.name, - self.user.account.domainid, - project.id - )) - with self.assertRaises(Exception): - # Add user to the project from different domain - project.addAccount( - self.apiclient, - self.user.account.name - ) - self.debug("User add to project failed!") - return - - -class TestDeleteAccountWithProject(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestDeleteAccountWithProject, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - cls.domain = get_domain( - cls.api_client, - cls.services - ) - - # Create account - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_03_delete_account_with_project(self): - """ Test As long as the project exists, its owner can't be removed - """ - - # Validate the following - # 1. Create a project. - # 2. Delete account who is owner of the project. Delete account should - # fail - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - # Deleting account who is owner of the project - with self.assertRaises(Exception): - self.account.delete(self.apiclient) - self.debug("Deleting account %s failed!" % - self.account.account.name) - return - -@unittest.skip("Deleting domain doesn't cleanup account") -class TestDeleteDomainWithProject(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestDeleteDomainWithProject, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - # Create account - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls._cleanup = [] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_04_delete_domain_with_project(self): - """ Test Verify delete domain with cleanup=true should delete projects - belonging to the domain - """ - - # Validate the following - # 1. Create a project in a domain - # 2. Delete domain forcefully. Verify that project is also deleted as - # as part of domain cleanup - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - - self.debug("Deleting domain: %s forcefully" % self.domain.name) - # Delete domain with cleanup=True - self.domain.delete(self.apiclient, cleanup=True) - self.debug("Removed domain: %s" % self.domain.name) - - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - self.assertEqual( - isinstance(interval, list), - True, - "Check if account.cleanup.interval config present" - ) - self.debug( - "Sleep for account cleanup interval: %s" % - interval[0].value) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value)) - - # Project should be deleted as part of domain cleanup - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - self.assertEqual( - list_projects_reponse, - None, - "Project should be deleted as part of domain cleanup" - ) - return - - -class TestProjectOwners(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestProjectOwners, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.zone = get_zone(cls.api_client, cls.services) - - # Create accounts - cls.admin = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.new_admin = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls._cleanup = [cls.admin, cls.new_admin] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_05_user_project_owner_promotion(self): - """ Test Verify a project user can be later promoted to become a - owner - """ - - # Validate the following - # 1. Create a project. - # 2. Add account to the project. Edit account to make it a project - # owner. verify new user is project owner and old account is - # regular user of the project. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.admin.account.name, - domainid=self.admin.account.domainid - ) - self.cleanup.append(project) - # Cleanup created project at end of test - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.new_admin.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.new_admin.account.name, - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.new_admin.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - - # Update the project with new admin - project.update( - self.apiclient, - account=self.new_admin.account.name - ) - - # listProjectAccount to verify the user is new admin of the project - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.new_admin.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Admin', - "Newly added user is not added as a regular user" - ) - - # listProjectAccount to verify old user becomes a regular user - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.admin.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - return - - def test_06_max_one_project_owner(self): - """ Test Verify there can only be one owner of a project at a time - """ - - # Validate the following - # 1. Create a project. - # 2. Add account to the project. Edit account to make it a project - # owner. - # 3. Update project to add another account as an owner - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.admin.account.name, - domainid=self.admin.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - self.user = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup.append(self.user) - self.debug("Created account with ID: %s" % - self.user.account.name) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.new_admin.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.new_admin.account.name, - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.new_admin.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - self.debug("Updating project with new Admin: %s" % - self.new_admin.account.name) - # Update the project with new admin - project.update( - self.apiclient, - account=self.new_admin.account.name - ) - - # listProjectAccount to verify the user is new admin of the project - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.new_admin.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Admin', - "Newly added user is not added as a regular user" - ) - - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - - self.debug("Updating project with new Admin: %s" % - self.user.account.name) - - # Update the project with new admin - project.update( - self.apiclient, - account=self.user.account.name - ) - - # listProjectAccount to verify the user is new admin of the project - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.debug(accounts_reponse) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Admin', - "Newly added user is not added as a regular user" - ) - - # listProjectAccount to verify old user becomes a regular user - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.new_admin.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - return - - -class TestProjectResources(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestProjectResources, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone - cls.zone = get_zone(cls.api_client, cls.services) - cls.domain = get_domain( - cls.api_client, - cls.services - ) - - # Create account, disk offering etc. - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.user = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls._cleanup = [cls.account, cls.disk_offering] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_07_project_resources_account_delete(self): - """ Test Verify after an account is removed from the project, all his - resources stay with the project. - """ - - # Validate the following - # 1. Create a project. - # 2. Add some accounts to project. Add resources to the project - # 3. Delete the account. Verify resources are still there after - # account deletion. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.cleanup.append(project) - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name, - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - # Create some resources(volumes) for the projects - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - diskofferingid=self.disk_offering.id, - projectid=project.id - ) - self.cleanup.append(volume) - - # Delete the project user - self.user.delete(self.apiclient) - - volumes = Volume.list(self.apiclient, id=volume.id) - - self.assertEqual( - isinstance(volumes, list), - True, - "Check for a valid list volumes response" - ) - - self.assertNotEqual( - len(volumes), - 0, - "Check list volumes API response returns a valid list" - ) - volume_response = volumes[0] - - self.assertEqual( - volume_response.name, - volume.name, - "Volume should exist after project user deletion." - ) - return - - def test_08_cleanup_after_project_delete(self): - """ Test accounts are unassigned from project after project deletion - """ - - # Validate the following - # 1. Create a project. - # 2. Add some accounts to project. Add resources to the project - # 3. Delete the project. Verify resources are freed after - # account deletion. - # 4. Verify all accounts are unassigned from project. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Create project as a domain admin - project = Project.create( - self.apiclient, - self.services["project"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - # Cleanup created project at end of test - self.debug("Created project with domain admin with ID: %s" % - project.id) - - list_projects_reponse = Project.list( - self.apiclient, - id=project.id, - listall=True - ) - - self.assertEqual( - isinstance(list_projects_reponse, list), - True, - "Check for a valid list projects response" - ) - list_project = list_projects_reponse[0] - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - - self.assertEqual( - project.name, - list_project.name, - "Check project name from list response" - ) - self.user = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup.append(self.user) - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - project.name - )) - # Add user to the project - project.addAccount( - self.apiclient, - self.user.account.name - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=project.id, - account=self.user.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(list_projects_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - # Create some resources(volumes) for the projects - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - diskofferingid=self.disk_offering.id, - projectid=project.id - ) - self.debug("Created a volume: %s for project: %s" % ( - volume.id, - project.name - )) - # Delete the project user - self.debug("Deleting project: %s" % project.name) - project.delete(self.apiclient) - self.debug("Successfully deleted project: %s" % project.name) - - volumes = Volume.list(self.apiclient, id=volume.id) - - self.assertEqual( - volumes, - None, - "Resources (volume) should be deleted as part of cleanup" - ) - - accounts = Project.listAccounts(self.apiclient, projectid=project.id) - - self.assertEqual( - accounts, - None, - "Accounts should be un-assigned from project" - ) - return - - -class TestProjectSuspendActivate(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestProjectSuspendActivate, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, domain, template etc - cls.zone = get_zone(cls.api_client, cls.services) - cls.domain = get_domain( - cls.api_client, - cls.services - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - # Create account, service offering, disk offering etc. - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"], - domainid=cls.domain.id - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.user = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - # Create project as a domain admin - cls.project = Project.create( - cls.api_client, - cls.services["project"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls._cleanup = [ - cls.project, - cls.account, - cls.disk_offering, - cls.service_offering - ] - 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, terminate the created accounts, domains etc - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_09_project_suspend(self): - """ Test Verify after an account is removed from the project, all his - resources stay with the project. - """ - - # Validate the following - # 1. Create a project. - # 2. Add some accounts to project. Add resources to the project - # 3. Delete the account. Verify resources are still there after - # account deletion. - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - self.debug("Adding %s user to project: %s" % ( - self.user.account.name, - self.project.name - )) - # Add user to the project - self.project.addAccount( - self.apiclient, - self.user.account.name, - ) - - # listProjectAccount to verify the user is added to project or not - accounts_reponse = Project.listAccounts( - self.apiclient, - projectid=self.project.id, - account=self.user.account.name, - ) - self.assertEqual( - isinstance(accounts_reponse, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(accounts_reponse), - 0, - "Check list project response returns a valid project" - ) - account = accounts_reponse[0] - - self.assertEqual( - account.role, - 'Regular', - "Newly added user is not added as a regular user" - ) - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - self.debug("Created a VM: %s for project: %s" % ( - virtual_machine.id, - self.project.id - )) - self.debug("Suspending a project: %s" % self.project.name) - self.project.suspend(self.apiclient) - - # Check status of all VMs associated with project - vms = VirtualMachine.list( - self.apiclient, - projectid=self.project.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(vms), - 0, - "Check list project response returns a valid project" - ) - - for vm in vms: - self.debug("VM ID: %s state: %s" % (vm.id, vm.state)) - self.assertEqual( - vm.state, - 'Stopped', - "VM should be in stopped state after project suspension" - ) - - self.debug("Attempting to create volume in suspended project") - with self.assertRaises(Exception): - # Create some resources(volumes) for the projects - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - diskofferingid=self.disk_offering.id, - projectid=self.project.id - ) - - self.debug("Volume creation failed") - - # Start the stopped VM - self.debug("Attempting to start VM: %s in suspended project" % - virtual_machine.id) - with self.assertRaises(Exception): - virtual_machine.start(self.apiclient) - self.debug("VM start failed!") - - # Destroy Stopped VM - virtual_machine.delete(self.apiclient) - self.debug("Destroying VM: %s" % virtual_machine.id) - - # Check status of all VMs associated with project - vms = VirtualMachine.list( - self.apiclient, - projectid=self.project.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(vms), - 0, - "Check list project response returns a valid project" - ) - - for vm in vms: - self.debug("VM ID: %s state: %s" % (vm.id, vm.state)) - self.assertEqual( - vm.state, - 'Destroyed', - "VM should be in stopped state after project suspension" - ) - return - - def test_10_project_activation(self): - """ Test project activation after suspension - """ - - # Validate the following - # 1. Activate the project - # 2. Verify project is activated and we are able to add resources - - # Verify 'project.invite.required' is set to false - configs = Configurations.list( - self.apiclient, - name='project.invite.required' - ) - self.assertEqual( - isinstance(configs, list), - True, - "Check for a valid list configurations response" - ) - config = configs[0] - self.assertEqual( - (config.value).lower(), - 'false', - "'project.invite.required' should be set to false" - ) - - # Activating the project - self.debug("Activating project: %s" % self.project.name) - self.project.activate(self.apiclient) - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - serviceofferingid=self.service_offering.id, - projectid=self.project.id - ) - - self.cleanup.append(virtual_machine) - self.debug("Created a VM: %s for project: %s" % ( - virtual_machine.id, - self.project.id - )) - # Check status of all VMs associated with project - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "Check for a valid list accounts response" - ) - - self.assertNotEqual( - len(vms), - 0, - "Check list project response returns a valid project" - ) - - for vm in vms: - self.debug("VM ID: %s state: %s" % (vm.id, vm.state)) - self.assertEqual( - vm.state, - 'Running', - "VM should be in Running state after project activation" - ) - return \ No newline at end of file diff --git a/tools/testClient/testcase/P1-tests/test_resource_limits.py b/tools/testClient/testcase/P1-tests/test_resource_limits.py deleted file mode 100644 index c1bbeb2f134..00000000000 --- a/tools/testClient/testcase/P1-tests/test_resource_limits.py +++ /dev/null @@ -1,1472 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Resource limits -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import datetime - -class Services: - """Test Resource Limits Services - """ - - 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": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "volume": { - "diskname": "TestDiskServ", - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - "templatefilter": 'self', - }, - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode": 'advanced', - } - -class TestResourceLimitsAccount(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestResourceLimitsAccount, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Account, VMs etc - cls.account_1 = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - # Create Account, VMs etc - cls.account_2 = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls._cleanup = [ - cls.disk_offering, - cls.service_offering, - cls.account_1, - cls.account_2 - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vm_per_account(self): - """Test VM limit per account - """ - - # Validate the following - # 1. Set user_vm=1 limit for account 1. - # 2. Try to start 2 VMs account 1. Verify start of second VM is denied - # for this account. - # 3. Try to start 2 VMs account 2. Verify 2 SM are started properly - - self.debug( - "Updating instance resource limit for account: %s" % - self.account_1.account.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 0, # Instance - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - max=1 - ) - self.debug( - "Deploying VM instance in account: %s" % - self.account_1.account.name) - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine) - - # Verify VM state - self.assertEqual( - virtual_machine.state, - 'Running', - "Check VM state is Running or not" - ) - - # Exception should be raised for second instance (account_1) - with self.assertRaises(Exception): - VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug( - "Deploying VM instance in account: %s" % - self.account_2.account.name) - # Start 2 instances for account_2 - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Deploying VM instance in account: %s" % - self.account_2.account.name) - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - return - - def test_02_publicip_per_account(self): - """Test Public IP limit per account - """ - - # Validate the following - # 1. Set Public_IP= 2 limit for account 1. - # 2. start 1 VMs account 1 - # 3. start 1 VMs account 2 - # 4. Acquire 2 IP in account 1. Verify account with limit should be - # denied to acquire more than one IP. - # 5. Acquire 2 IP in account 2. Verify account 2 should be able to - # Acquire IP without any warning - - self.debug( - "Updating public IP resource limit for account: %s" % - self.account_1.account.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 1, # Public Ip - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - max=2 - ) - - self.debug( - "Deploying VM instance in account: %s" % - self.account_1.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Deploying VM instance in account: %s" % - self.account_2.account.name) - # Create VM for second account - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug( - "Associating public IP for account: %s" % - virtual_machine_1.account) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - virtual_machine_1.account, - virtual_machine_1.zoneid, - virtual_machine_1.domainid, - self.services["server"] - ) - self.cleanup.append(public_ip_1) - - # Sleep to ensure that state is reflected across all the calls - time.sleep(self.services["sleep"]) - - # Verify Public IP state - self.assertEqual( - public_ip_1.ipaddress.state in [ - 'Allocated', - 'Allocating' - ], - True, - "Check Public IP state is allocated or not" - ) - - # Exception should be raised for second instance (account_1) - with self.assertRaises(Exception): - public_ip_2 = PublicIPAddress.create( - self.apiclient, - virtual_machine_1.account, - virtual_machine_1.zoneid, - virtual_machine_1.domainid, - self.services["server"] - ) - - self.debug( - "Associating public IP for account: %s" % - virtual_machine_2.account) - # Assign Public IP for account 2 - public_ip_3 = PublicIPAddress.create( - self.apiclient, - virtual_machine_2.account, - virtual_machine_2.zoneid, - virtual_machine_2.domainid, - self.services["server"] - ) - self.cleanup.append(public_ip_3) - - # Verify Public IP state - self.assertEqual( - public_ip_3.ipaddress.state in [ - 'Allocated', - 'Allocating' - ], - True, - "Check Public IP state is allocated or not" - ) - self.debug( - "Associating public IP for account: %s" % - virtual_machine_2.account) - public_ip_4 = PublicIPAddress.create( - self.apiclient, - virtual_machine_2.account, - virtual_machine_2.zoneid, - virtual_machine_2.domainid, - self.services["server"] - ) - self.cleanup.append(public_ip_4) - # Verify Public IP state - self.assertEqual( - public_ip_4.ipaddress.state in [ - 'Allocated', - 'Allocating' - ], - True, - "Check Public IP state is allocated or not" - ) - return - - def test_03_snapshots_per_account(self): - """Test Snapshot limit per account - """ - - # Validate the following - # 1. Set snapshot= 2 limit for account 1. - # 2. start 1 VMs account 1 - # 3. start 1 VMs account 2 - # 4. Create 2 snapshot in account 1. Verify account with limit should - # be denied to create more than one snapshot. - # 5. Create 2 snapshot in account 2. Verify account 2 should be able to - # create snapshots without any warning - - self.debug( - "Updating public IP resource limit for account: %s" % - self.account_1.account.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 3, # Snapshot - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - max=1 - ) - - self.debug( - "Deploying VM instance in account: %s" % - self.account_1.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Deploying VM instance in account: %s" % - self.account_1.account.name) - # Create VM for second account - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_1.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a snapshot from the ROOTDISK (Account 1) - snapshot_1 = Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - ) - self.cleanup.append(snapshot_1) - # Verify Snapshot state - self.assertEqual( - snapshot_1.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - - # Exception should be raised for second snapshot (account_1) - with self.assertRaises(Exception): - Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - ) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_2.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a snapshot from the ROOTDISK (Account 2) - snapshot_2 = Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - ) - self.cleanup.append(snapshot_2) - # Verify Snapshot state - self.assertEqual( - snapshot_2.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a second snapshot from the ROOTDISK (Account 2) - snapshot_3 = Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - ) - self.cleanup.append(snapshot_3) - # Verify Snapshot state - self.assertEqual( - snapshot_3.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - return - - def test_04_volumes_per_account(self): - """Test Volumes limit per account - """ - - # Validate the following - # 1. Set volumes=2 limit for account 1. - # 2. Start 1 VMs account 1 - # 3. Start 1 VMs account 2 - # 4. Create 2 volumes in account 1. Verify account with limit should be - # denied to create more than one volume. - # 5. Create 2 volumes in account 2. Verify account 2 should be able to - # create Volume without any warning - - self.debug( - "Updating volume resource limit for account: %s" % - self.account_1.account.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 2, # Volume - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - max=2 - ) - - self.debug( - "Deploying VM for account: %s" % self.account_1.account.name) - - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Deploying VM for account: %s" % self.account_2.account.name) - - # Create VM for second account - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Create a data volume for account: %s" % self.account_1.account.name) - volume_1 = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.cleanup.append(volume_1) - # Verify Volume state - self.assertEqual( - volume_1.state in [ - 'Allocated', - 'Ready' - ], - True, - "Check Volume state is Ready or not" - ) - - # Exception should be raised for second snapshot (account_1) - with self.assertRaises(Exception): - Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - diskofferingid=self.disk_offering.id - ) - - self.debug( - "Create a data volume for account: %s" % self.account_2.account.name) - # Create volume for Account 2 - volume_2 = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.cleanup.append(volume_2) - # Verify Volume state - self.assertEqual( - volume_2.state in [ - 'Allocated', - 'Ready' - ], - True, - "Check Volume state is Ready or not" - ) - - self.debug( - "Create a data volume for account: %s" % self.account_2.account.name) - # Create a second volume from the ROOTDISK (Account 2) - volume_3 = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.cleanup.append(volume_3) - # Verify Volume state - self.assertEqual( - volume_3.state in [ - 'Allocated', - 'Ready' - ], - True, - "Check Volume state is Ready or not" - ) - return - - def test_05_templates_per_account(self): - """Test Templates limit per account - """ - - # Validate the following - # 1. Set templates=1 limit for account 1. - # 2. Try to create 2 templates in account 1. Verify account with limit - # should be denied to create more than 1 template. - # 3. Try to create 2 templates in account 2. Verify account 2 should be - # able to create template without any error - - self.debug( - "Updating template resource limit for account: %s" % - self.account_1.account.name) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 4, # Template - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - max=1 - ) - - self.debug( - "Updating volume resource limit for account: %s" % - self.account_1.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account_1.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - self.debug( - "Deploying virtual machine for account: %s" % - self.account_2.account.name) - # Create VM for second account - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_2.account.name, - domainid=self.account_2.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_1.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK (Account 1) - template_1 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - ) - - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( - template_1.isready, - True, - "Check Template is in ready state or not" - ) - - # Exception should be raised for second snapshot (account_1) - with self.assertRaises(Exception): - Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account_1.account.name, - domainid=self.account_1.account.domainid, - ) - virtual_machine_2.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_2.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a snapshot from the ROOTDISK (Account 1) - template_2 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - ) - - self.cleanup.append(template_2) - # Verify Template state - self.assertEqual( - template_2.isready, - True, - "Check Template is in ready state or not" - ) - self.debug( - "Creating template from volume: %s" % volume.id) - # Create a second volume from the ROOTDISK (Account 2) - template_3 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account_2.account.name, - domainid=self.account_2.account.domainid, - ) - - self.cleanup.append(template_3) - # Verify Template state - self.assertEqual( - template_3.isready, - True, - "Check Template is in ready state or not" - ) - return - - -class TestResourceLimitsDomain(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestResourceLimitsDomain, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - # Create Domains, Account etc - cls.domain = Domain.create( - cls.api_client, - cls.services["domain"] - ) - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - # Create Service offering and disk offerings etc - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account, - cls.domain - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vm_per_domain(self): - """Test VM limit per domain - """ - - # Validate the following - # 1. Set max VM per domain to 2 - # 2. Create account and start 2 VMs. Verify VM state is Up and Running - # 3. Try to create 3rd VM instance. The appropriate error or alert - # should be raised - - self.debug( - "Updating instance resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 0, # Instance - domainid=self.account.account.domainid, - max=2 - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_2) - # Verify VM state - self.assertEqual( - virtual_machine_2.state, - 'Running', - "Check VM state is Running or not" - ) - # Exception should be raised for second instance - with self.assertRaises(Exception): - VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account_1.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - return - - def test_01_publicip_per_domain(self): - """Test Public IP limit per domain - """ - - # Validate the following - # 1. set max no of IPs per domain to 2. - # 2. Create an account in this domain - # 3. Create 1 VM in this domain - # 4. Acquire 1 IP in the domain. IP should be successfully acquired - # 5. Try to acquire 3rd IP in this domain. It should give the user an - # appropriate error and an alert should be generated. - - self.debug( - "Updating public IP resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 1, # Public Ip - domainid=self.account.account.domainid, - max=2 - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - self.debug("Associating public IP for account: %s" % self.account.account.name) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - virtual_machine_1.account, - virtual_machine_1.zoneid, - virtual_machine_1.domainid, - self.services["server"] - ) - self.cleanup.append(public_ip_1) - # Verify Public IP state - self.assertEqual( - public_ip_1.ipaddress.state in [ - 'Allocated', - 'Allocating' - ], - True, - "Check Public IP state is allocated or not" - ) - - # Exception should be raised for second Public IP - with self.assertRaises(Exception): - public_ip_2 = PublicIPAddress.create( - self.apiclient, - virtual_machine_1.account, - virtual_machine_1.zoneid, - virtual_machine_1.domainid, - self.services["server"] - ) - return - - def test_03_snapshots_per_domain(self): - """Test Snapshot limit per domain - """ - - # Validate the following - # 1. set max no of snapshots per domain to 1. - # 2. Create an account in this domain - # 3. Create 1 VM in this domain - # 4. Create one snapshot in the domain. Snapshot should be successfully - # created - # 5. Try to create another snapshot in this domain. It should give the - # user an appropriate error and an alert should be generated. - - self.debug( - "Updating snapshot resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 3, # Snapshot - domainid=self.account.account.domainid, - max=1 - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_1.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - # Create a snapshot from the ROOTDISK - snapshot_1 = Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.cleanup.append(snapshot_1) - # Verify Snapshot state - self.assertEqual( - snapshot_1.state in [ - 'BackedUp', - 'CreatedOnPrimary' - ], - True, - "Check Snapshot state is Running or not" - ) - - # Exception should be raised for second snapshot - with self.assertRaises(Exception): - Snapshot.create(self.apiclient, - volumes[0].id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - return - - def test_04_volumes_per_domain(self): - """Test Volumes limit per domain - """ - - # Validate the following - # 1. set max no of volume per domain to 1. - # 2. Create an account in this domain - # 3. Create 1 VM in this domain - # 4. Try to Create another VM in the domain. It should give the user an - # appropriate error that Volume limit is exhausted and an alert - # should be generated. - - self.debug( - "Updating volume resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 2, # Volume - domainid=self.account.account.domainid, - max=2 - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - - # Exception should be raised for second volume - with self.assertRaises(Exception): - Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - return - - def test_05_templates_per_domain(self): - """Test Templates limit per domain - """ - - # Validate the following - # 1. set max no of templates per domain to 2. - # 2. Create an account in this domain - # 3. Create 2 templates in this domain. Both template should be in - # ready state - # 4. Try create 3rd template in the domain. It should give the user an - # appropriate error and an alert should be generated. - - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 2, # Volume - domainid=self.account.account.domainid, - max=5 - ) - - self.debug( - "Updating template resource limits for domain: %s" % - self.account.account.domainid) - # Set usage_vm=1 for Account 1 - update_resource_limit( - self.apiclient, - 4, # Template - domainid=self.account.account.domainid, - max=2 - ) - - self.debug("Deploying VM for account: %s" % self.account.account.name) - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.cleanup.append(virtual_machine_1) - # Verify VM state - self.assertEqual( - virtual_machine_1.state, - 'Running', - "Check VM state is Running or not" - ) - virtual_machine_1.stop(self.apiclient) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=virtual_machine_1.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check for list volume response return valid data" - ) - volume = volumes[0] - - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_1 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.cleanup.append(template_1) - # Verify Template state - self.assertEqual( - template_1.isready, - True, - "Check Template is in ready state or not" - ) - self.debug("Creating template from volume: %s" % volume.id) - # Create a template from the ROOTDISK - template_2 = Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.cleanup.append(template_2) - # Verify Template state - self.assertEqual( - template_2.isready, - True, - "Check Template is in ready state or not" - ) - - # Exception should be raised for second template - with self.assertRaises(Exception): - Template.create( - self.apiclient, - self.services["template"], - volumeid=volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - return - - -class TestResources(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestResources, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.zone = get_zone(cls.api_client, cls.services) - cls._cleanup = [] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_zones(self): - """Check the status of zones""" - - # Validate the following - # 1. List zones - # 2. Check allocation state is "enabled" or not - - zones = Zone.list( - self.apiclient, - id=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(zones, list), - True, - "Check if listZones returns a valid response" - ) - for zone in zones: - self.assertEqual( - zone.allocationstate, - 'Enabled', - "Zone allocation state should be enabled" - ) - return - - def test_02_pods(self): - """Check the status of pods""" - - # Validate the following - # 1. List pods - # 2. Check allocation state is "enabled" or not - - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(pods, list), - True, - "Check if listPods returns a valid response" - ) - for pod in pods: - self.assertEqual( - pod.allocationstate, - 'Enabled', - "Pods allocation state should be enabled" - ) - return - - def test_03_clusters(self): - """Check the status of clusters""" - - # Validate the following - # 1. List clusters - # 2. Check allocation state is "enabled" or not - - clusters = Cluster.list( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "Check if listClusters returns a valid response" - ) - for cluster in clusters: - self.assertEqual( - cluster.allocationstate, - 'Enabled', - "Clusters allocation state should be enabled" - ) - return - - def test_04_hosts(self): - """Check the status of hosts""" - - # Validate the following - # 1. List hosts with type=Routing - # 2. Check state is "Up" or not - - hosts = Host.list( - self.apiclient, - zoneid=self.zone.id, - type='Routing', - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check if listHosts returns a valid response" - ) - for host in hosts: - self.assertEqual( - host.state, - 'Up', - "Host should be in Up state and running" - ) - return - - def test_05_storage_pools(self): - """Check the status of Storage pools""" - - # Validate the following - # 1. List storage pools for the zone - # 2. Check state is "enabled" or not - - storage_pools = StoragePool.list( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(storage_pools, list), - True, - "Check if listStoragePools returns a valid response" - ) - for storage_pool in storage_pools: - self.assertEqual( - storage_pool.state, - 'Up', - "storage pool should be in Up state and running" - ) - return - - def test_06_secondary_storage(self): - """Check the status of secondary storage""" - - # Validate the following - # 1. List secondary storage - # 2. Check state is "Up" or not - - sec_storages = Host.list( - self.apiclient, - zoneid=self.zone.id, - type='SecondaryStorage', - listall=True - ) - self.assertEqual( - isinstance(sec_storages, list), - True, - "Check if listHosts returns a valid response" - ) - for sec_storage in sec_storages: - self.assertEqual( - sec_storage.state, - 'Up', - "Secondary storage should be in Up state" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_routers.py b/tools/testClient/testcase/P1-tests/test_routers.py deleted file mode 100644 index 7d115baf445..00000000000 --- a/tools/testClient/testcase/P1-tests/test_routers.py +++ /dev/null @@ -1,1200 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for routers -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time - - -class Services: - """Test router Services - """ - - def __init__(self): - self.services = { - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "virtual_machine": - { - "displayname": "Test VM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - # Hypervisor type should be same as - # hypervisor type of cluster - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "host": { - "username": "root", - "password": "fr3sca", - "publicport": 22, - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "testuser", - "password": "password", - }, - "natrule": - { - "privateport": 22, - "publicport": 222, - "protocol": "TCP" - }, - "lbrule": - { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - }, - "fw_rule":{ - "startport": 1, - "endport": 6000, - "cidr": '55.55.0.0/11', - # Any network (For creating FW rule - }, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - # Used for Get_Template : CentOS 5.3 (64 bit) - "mode": 'advanced', # Networking mode: Advanced, basic - } - - -class TestRouterServices(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestRouterServices, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRouterServices, cls).getClsTestClient().getApiClient() - #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def tearDown(self): - try: - cleanup_resources(self.apiclient, self._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self._cleanup = [] - return - - def test_01_AdvancedZoneRouterServices(self): - """Test advanced zone router services - """ - - # Validate the following: - # 1. Verify that list of services provided by this network are running - # a. DNS - # b. DHCP - # c. Gateway - # d. Firewall - # e. LB - # f. VPN - # g. userdata - # 2. wait for router to start and guest network to be created - # a. listRouters account=user, domainid=1 (router state=Running) - # b. listNetworks account=user domainid=1 (network state=Implemented) - # c. listVirtualMachines account=user domainid=1 (VM state=Running) - # 3. listNetwork - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - for router in routers: - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - self.debug("Router ID: %s & Router state: %s" % ( - router.id, - router.state - )) - # Network state associated with account should be 'Implemented' - networks = list_networks( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check for list networks response return valid data" - ) - - self.assertNotEqual( - len(networks), - 0, - "Check list networks response" - ) - for network in networks: - self.assertIn( - network.state, - ['Implemented','Allocated'], - "Check list network response for network state" - ) - self.debug("Network ID: %s & Network state: %s" % ( - network.id, - network.state - )) - # VM state associated with account should be 'Running' - virtual_machines = list_virtual_machines( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check for list virtual machines response return valid data" - ) - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - self.debug("VM ID: %s & VM state: %s" % ( - virtual_machine.id, - virtual_machine.state - )) - - # Check status of DNS, DHCP, FIrewall, LB VPN processes - networks = list_networks( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check for list networks response return valid data" - ) - self.assertNotEqual( - len(networks), - 0, - "Check list networks response" - ) - # Load Balancer, Userdata, VPN, Firewall, Gateway, DNS processes should - # be running - for network in networks: - self.assertEqual( - 'Lb' in str(network.service), - True, - "Check Load balancing process in list networks" - ) - self.assertEqual( - 'UserData' in str(network.service), - True, - "Check UserData service in list networks" - ) - self.assertEqual( - 'Vpn' in str(network.service), - True, - "Check Vpn service in list networks" - ) - self.assertEqual( - 'Firewall' in str(network.service), - True, - "Check Firewall service in list networks" - ) - self.assertEqual( - 'Dns' in str(network.service), - True, - "Check Dns service in list networks" - ) - return - - def test_02_NetworkGarbageCollection(self): - """Test network garbage collection - """ - - # Validate the following - # 1. wait for router to start and guest network to be created - # a.listRouters account=user, domainid=1 (router state=Running) - # b.listNetworks account=user domainid=1 (network state=Implemented) - # c.listVirtualMachines account=user domainid=1 (VM states=Running) - # 4. stopVirtualMachines (stop all VMs in this account) - # 5. wait for VMs to stop-listVirtualMachines account=user, domainid=1 - # (Both VM states = Stopped) - # 6. wait for network.gc.interval*2 seconds (600s) - # 7. listRouters account=user, domainid=1 - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - # Router associated with account should be in running state - for router in routers: - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - self.debug("Router ID: %s & Router state: %s" % ( - router.id, - router.state - )) - # Network state associated with account should be 'Implemented' - networks = list_networks( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(networks, list), - True, - "Check for list networks response return valid data" - ) - self.assertNotEqual( - len(networks), - 0, - "Check list networks response" - ) - # Check if network in 'Implemented' state - for network in networks: - self.assertIn( - network.state, - ['Implemented','Allocated'], - "Check list network response for network state" - ) - self.debug("Network ID: %s & Network state: %s" % ( - network.id, - network.state - )) - # VM state associated with account should be 'Running' - virtual_machines = list_virtual_machines( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check for list virtual machines response return valid data" - ) - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - self.debug("VM ID: %s & VM state: %s" % ( - virtual_machine.id, - virtual_machine.state - )) - # Stop virtual machine - cmd = stopVirtualMachine.stopVirtualMachineCmd() - cmd.id = virtual_machine.id - self.apiclient.stopVirtualMachine(cmd) - - gcinterval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - self.assertEqual( - isinstance(gcinterval, list), - True, - "Check for list intervals response return valid data" - ) - self.debug("network.gc.interval: %s" % gcinterval[0].value) - - gcwait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - self.assertEqual( - isinstance(gcwait, list), - True, - "Check for list intervals response return valid data" - ) - self.debug("network.gc.wait: %s" % gcwait[0].value) - - total_wait = int(gcinterval[0].value) + int (gcwait[0].value) - # Router is stopped after (network.gc.interval *2) time. Wait for - # (network.gc.interval+network.gc.wait) * 2 for moving router to 'Stopped' - time.sleep(total_wait * 2) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - for router in routers: - self.assertEqual( - router.state, - 'Stopped', - "Check list router response for router state" - ) - self.debug("Router ID: %s & Router state: %s" % ( - router.id, - router.state - )) - # Cleanup Vm_2 - Not required for further tests - self._cleanup.append(self.vm_2) - return - - def test_03_RouterStartOnVmDeploy(self): - """Test router start on VM deploy - """ - # Validate the following - # 1. deployVirtualMachine in the account - # 2. listVirtualMachines account=user, domainid=1 - # 3. when listVirtualMachines reports the userVM to be in state=Running - # 4. listRouters should report router to have come back to "Running" state - # 5. All other VMs in the account should remain in "Stopped" state - - vm = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed a VM with ID: %s" % vm.id) - - virtual_machines = list_virtual_machines( - self.apiclient, - id=vm.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check for list virtual machines response return valid data" - ) - - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - # VM state should be 'Running' - for virtual_machine in virtual_machines: - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - # Routers associated with account should be 'Running' after deployment - # of VM - for router in routers: - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - self.debug("Router ID: %s & Router state: %s" % ( - router.id, - router.state - )) - - # All other VMs (VM_1) should be in 'Stopped' - virtual_machines = list_virtual_machines( - self.apiclient, - id=self.vm_1.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check for list VMs response return valid data" - ) - - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.assertEqual( - virtual_machine.state, - 'Stopped', - "Check list VM response for Stopped state" - ) - self.debug("VM ID: %s & VM state: %s" % ( - virtual_machine.id, - virtual_machine.state - )) - return - - - -class TestRouterStopCreatePF(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestRouterStopCreatePF, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRouterStopCreatePF, cls).getClsTestClient().getApiClient() - # Clean up, terminate the created resources - cleanup_resources(cls.api_client, cls.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def tearDown(self): - try: - # Clean up, terminate the created resources - cleanup_resources(self.apiclient, self._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self._cleanup = [] - return - - def test_01_RouterStopCreatePF(self): - """Test router stop create port forwarding - """ - - # validate the following - # 1. wait for router to start, guest network to be implemented and - # VM to report Running - # 2. stopRouter for this account - # 3. wait for listRouters to report Router as 'Stopped' - # 4. listPublicIpAddresses account=user, domainid=1 - pick ipaddressid - # 5. createPortForwardingRule (ipaddressid from step 5.) - # a. for port 22 (ssh) for user VM deployed in step 1. - # b. public port 222 , private port 22 - # 6. startRouter stopped for this account - # 7. wait for listRouters to show router as Running - - # Get router details associated for that account - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - router = routers[0] - - self.debug("Stopping router ID: %s" % router.id) - - #Stop the router - cmd = stopRouter.stopRouterCmd() - cmd.id = router.id - self.apiclient.stopRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - router = routers[0] - - self.assertEqual( - router.state, - 'Stopped', - "Check list router response for router state" - ) - - public_ips = list_publicIP( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "Check for list public IPs response return valid data" - ) - public_ip = public_ips[0] - - self.debug("Creating NAT rule for VM ID: %s" % self.vm_1.id) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - self.vm_1, - self.services["natrule"], - public_ip.id - ) - - self.debug("Starting router ID: %s" % router.id) - #Start the router - cmd = startRouter.startRouterCmd() - cmd.id = router.id - self.apiclient.startRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - router = routers[0] - - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - # NAT Rule should be in Active state after router start - nat_rules = list_nat_rules( - self.apiclient, - id=nat_rule.id - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "Check for list NAT rules response return valid data" - ) - self.assertEqual( - nat_rules[0].state, - 'Active', - "Check list port forwarding rules" - ) - try: - - self.debug("SSH into VM with ID: %s" % nat_rule.ipaddress) - - self.vm_1.ssh_port = nat_rule.publicport - self.vm_1.get_ssh_client(nat_rule.ipaddress) - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.vm_1.ipaddress, e) - ) - return - -class TestRouterStopCreateLB(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestRouterStopCreateLB, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRouterStopCreateLB, cls).getClsTestClient().getApiClient() - #Clean up, terminate the created resources - cleanup_resources(cls.api_client, cls.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def tearDown(self): - try: - cleanup_resources(self.apiclient, self._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self._cleanup = [] - return - - def test_01_RouterStopCreateLB(self): - """Test router stop create Load balancing - """ - - # validate the following - # 1. listLoadBalancerRules (publicipid=ipaddressid of source NAT) - # 2. rule should be for port 2222 as applied and - # should be in state=Active - # 3. ssh access should be allowed to the userVMs over the source NAT IP - # and port 2222 - - # Get router details associated for that account - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - - router = routers[0] - - self.debug("Stopping router with ID: %s" % router.id) - #Stop the router - cmd = stopRouter.stopRouterCmd() - cmd.id = router.id - self.apiclient.stopRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - router = routers[0] - - self.assertEqual( - router.state, - 'Stopped', - "Check list router response for router state" - ) - - public_ips = list_publicIP( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "Check for list public IPs response return valid data" - ) - public_ip = public_ips[0] - self.debug("Creating LB rule for public IP: %s" % public_ip.id) - #Create Load Balancer rule and assign VMs to rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - public_ip.id, - accountid=self.account.account.name - ) - self.debug("Assigning VM %s to LB rule: %s" % ( - self.vm_1.id, - lb_rule.id - )) - lb_rule.assign(self.apiclient, [self.vm_1]) - - #Start the router - cmd = startRouter.startRouterCmd() - cmd.id = router.id - self.apiclient.startRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - router = routers[0] - - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - # After router start, LB RUle should be in Active state - lb_rules = list_lb_rules( - self.apiclient, - id=lb_rule.id - ) - self.assertEqual( - isinstance(lb_rules, list), - True, - "Check for list LB rules response return valid data" - ) - self.assertEqual( - lb_rules[0].state, - 'Active', - "Check list load balancing rules" - ) - self.assertEqual( - lb_rules[0].publicport, - str(self.services["lbrule"]["publicport"]), - "Check list load balancing rules" - ) - - try: - self.debug("SSH into VM with IP: %s" % public_ip.ipaddress) - self.vm_1.ssh_port = self.services["lbrule"]["publicport"] - self.vm_1.get_ssh_client(public_ip.ipaddress) - except Exception as e: - self.fail( - "SSH Access failed for %s: %s" % \ - (self.vm_1.ipaddress, e) - ) - return - - -class TestRouterStopCreateFW(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.api_client = super(TestRouterStopCreateFW, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - #Create an account, network, VM and IP addresses - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRouterStopCreateFW, cls).getClsTestClient().getApiClient() - #Clean up, terminate the created templates - cleanup_resources(cls.api_client, cls.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def tearDown(self): - try: - cleanup_resources(self.apiclient, self._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self._cleanup = [] - return - - def test_01_RouterStopCreateFW(self): - """Test router stop create Firewall rule - """ - - # validate the following - # 1. 1. listFirewallRules (filter by ipaddressid of sourcenat) - # 2. rule should be for ports 1-600 and in state=Active - # (optional backend) - # 3. verify on router using iptables -t nat -nvx if rules are applied - - # Get the router details associated with account - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - - self.assertNotEqual( - len(routers), - 0, - "Check list router response" - ) - - router = routers[0] - - self.debug("Stopping the router: %s" % router.id) - #Stop the router - cmd = stopRouter.stopRouterCmd() - cmd.id = router.id - self.apiclient.stopRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - router = routers[0] - - self.assertEqual( - router.state, - 'Stopped', - "Check list router response for router state" - ) - - public_ips = list_publicIP( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "Check for list public IP response return valid data" - ) - public_ip = public_ips[0] - - #Create Firewall rule with configurations from settings file - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created firewall rule: %s" % fw_rule.id) - - self.debug("Starting the router: %s" % router.id) - #Start the router - cmd = startRouter.startRouterCmd() - cmd.id = router.id - self.apiclient.startRouter(cmd) - - routers = list_routers( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list routers response return valid data" - ) - - router = routers[0] - - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - # After Router start, FW rule should be in Active state - fw_rules = list_firewall_rules( - self.apiclient, - id=fw_rule.id, - ) - self.assertEqual( - isinstance(fw_rules, list), - True, - "Check for list FW rules response return valid data" - ) - - self.assertEqual( - fw_rules[0].state, - 'Active', - "Check list load balancing rules" - ) - self.assertEqual( - fw_rules[0].startport, - str(self.services["fw_rule"]["startport"]), - "Check start port of firewall rule" - ) - - self.assertEqual( - fw_rules[0].endport, - str(self.services["fw_rule"]["endport"]), - "Check end port of firewall rule" - ) - hosts = list_hosts( - self.apiclient, - id=router.hostid, - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check for list hosts response return valid data" - ) - host = hosts[0] - # For DNS and DHCP check 'dnsmasq' process status - result = get_process_status( - host.ipaddress, - self.services['host']["publicport"], - self.services['host']["username"], - self.services['host']["password"], - router.linklocalip, - 'iptables -t nat -L' - ) - self.debug("iptables -t nat -L: %s" % result) - self.debug("Public IP: %s" % public_ip.ipaddress) - res = str(result) - self.assertEqual( - res.count(str(public_ip.ipaddress)), - 1, - "Check public IP address" - ) - return - diff --git a/tools/testClient/testcase/P1-tests/test_security_groups.py b/tools/testClient/testcase/P1-tests/test_security_groups.py deleted file mode 100644 index 0314e17d6f3..00000000000 --- a/tools/testClient/testcase/P1-tests/test_security_groups.py +++ /dev/null @@ -1,1627 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -""" P1 for Security groups -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * - -#Import System modules -import time -import subprocess - - -class Services: - """Test Security groups Services - """ - - def __init__(self): - self.services = { - "disk_offering":{ - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended in create account to - # ensure unique username generated each time - "password": "fr3sca", - }, - "virtual_machine": { - # Create a small virtual machine instance with disk offering - "displayname": "Test VM", - "username": "root", # VM creds for SSH - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - "userdata": 'This is sample data', - }, - "host": { - "publicport": 22, - "username": "root", # Host creds for SSH - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "security_group": { - "name": 'SSH', - "protocol": 'TCP', - "startport": 22, - "endport": 22, - "cidrlist": '0.0.0.0/0', - }, - "security_group_2": { - "name": 'ICMP', - "protocol": 'ICMP', - "startport": -1, - "endport": -1, - "cidrlist": '0.0.0.0/0', - }, - "ostypeid": '0c2c5d19-525b-41be-a8c3-c6607412f82b', - # CentOS 5.3 (64-bit) - "sleep": 60, - "timeout": 10, - "mode":'basic', - # Networking mode: Basic or Advanced - } - - -class TestDefaultSecurityGroup(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDefaultSecurityGroup, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestDefaultSecurityGroup, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_deployVM_InDefaultSecurityGroup(self): - """Test deploy VM in default security group - """ - - # Validate the following: - # 1. deploy Virtual machine using admin user - # 2. listVM should show a VM in Running state - # 3. listRouters should show one router running - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM with ID: %s" % self.virtual_machine.id) - self.cleanup.append(self.virtual_machine) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check for list VM response" - ) - vm_response = list_vm_response[0] - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - - vm_response.id, - self.virtual_machine.id, - "Check virtual machine id in listVirtualMachines" - ) - - self.assertEqual( - vm_response.displayname, - self.virtual_machine.displayname, - "Check virtual machine displayname in listVirtualMachines" - ) - - # Verify List Routers response for account - self.debug( - "Verify list routers response for account: %s" \ - % self.account.account.name - ) - routers = list_routers( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "Check for list Routers response" - ) - - self.debug("Router Response: %s" % routers) - self.assertEqual( - len(routers), - 1, - "Check virtual router is created for account or not" - ) - return - - def test_02_listSecurityGroups(self): - """Test list security groups for admin account - """ - - # Validate the following: - # 1. listSecurityGroups in admin account - # 2. There should be one security group (default) listed for the admin account - # 3. No Ingress Rules should be part of the default security group - - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - self.assertNotEqual( - len(sercurity_groups), - 0, - "Check List Security groups response" - ) - self.debug("List Security groups response: %s" % - str(sercurity_groups)) - self.assertEqual( - hasattr(sercurity_groups, 'ingressrule'), - False, - "Check ingress rule attribute for default security group" - ) - return - - def test_03_accessInDefaultSecurityGroup(self): - """Test access in default security group - """ - - # Validate the following: - # 1. deploy Virtual machine using admin user - # 2. listVM should show a VM in Running state - # 3. listRouters should show one router running - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Deployed VM with ID: %s" % self.virtual_machine.id) - self.cleanup.append(self.virtual_machine) - - list_vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check for list VM response" - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.virtual_machine.id - ) - - vm_response = list_vm_response[0] - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM available in List Virtual Machines" - ) - - self.assertEqual( - - vm_response.id, - self.virtual_machine.id, - "Check virtual machine id in listVirtualMachines" - ) - - self.assertEqual( - vm_response.displayname, - self.virtual_machine.displayname, - "Check virtual machine displayname in listVirtualMachines" - ) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.debug("List Security groups response: %s" % - str(sercurity_groups)) - self.assertNotEqual( - len(sercurity_groups), - 0, - "Check List Security groups response" - ) - self.assertEqual( - hasattr(sercurity_groups, 'ingressrule'), - False, - "Check ingress rule attribute for default security group" - ) - - # SSH Attempt to VM should fail - with self.assertRaises(Exception): - self.debug("SSH into VM: %s" % self.virtual_machine.ssh_ip) - ssh = remoteSSHClient.remoteSSHClient( - self.virtual_machine.ssh_ip, - self.virtual_machine.ssh_port, - self.virtual_machine.username, - self.virtual_machine.password - ) - return - - -class TestAuthorizeIngressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestAuthorizeIngressRule, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestAuthorizeIngressRule, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_authorizeIngressRule(self): - """Test authorize ingress rule - """ - - # Validate the following: - #1. Create Security group for the account. - #2. Createsecuritygroup (ssh-incoming) for this account - #3. authorizeSecurityGroupIngress to allow ssh access to the VM - #4. deployVirtualMachine into this security group (ssh-incoming) - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.debug("Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.id) - self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - return - - -class TestRevokeIngressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestRevokeIngressRule, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestRevokeIngressRule, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_revokeIngressRule(self): - """Test revoke ingress rule - """ - - # Validate the following: - #1. Create Security group for the account. - #2. Createsecuritygroup (ssh-incoming) for this account - #3. authorizeSecurityGroupIngress to allow ssh access to the VM - #4. deployVirtualMachine into this security group (ssh-incoming) - #5. Revoke the ingress rule, SSH access should fail - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - # Authorize Security group to SSH to VM - self.debug("Authorizing ingress rule for sec group ID: %s for ssh access" - % security_group.id) - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Should be able to SSH VM - try: - self.debug("SSH into VM: %s" % self.virtual_machine.id) - self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - self.debug("Revoking ingress rule for sec group ID: %s for ssh access" - % security_group.id) - # Revoke Security group to SSH to VM - result = security_group.revoke( - self.apiclient, - id=ssh_rule["ruleid"] - ) - - # SSH Attempt to VM should fail - with self.assertRaises(Exception): - self.debug("SSH into VM: %s" % self.virtual_machine.id) - remoteSSHClient.remoteSSHClient( - self.virtual_machine.ssh_ip, - self.virtual_machine.ssh_port, - self.virtual_machine.username, - self.virtual_machine.password - ) - return - - -class TestDhcpOnlyRouter(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDhcpOnlyRouter, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestDhcpOnlyRouter, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_dhcpOnlyRouter(self): - """Test router services for user account - """ - # Validate the following - #1. List routers for any user account - #2. The only service supported by this router should be dhcp - - # Find router associated with user account - list_router_response = list_routers( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(list_router_response, list), - True, - "Check list response returns a valid list" - ) - router = list_router_response[0] - - hosts = list_hosts( - self.apiclient, - zoneid=router.zoneid, - type='Routing', - state='Up', - virtualmachineid=self.virtual_machine.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list host returns a valid list" - ) - host = hosts[0] - - self.debug("Router ID: %s, state: %s" % (router.id, router.state)) - - self.assertEqual( - router.state, - 'Running', - "Check list router response for router state" - ) - - result = get_process_status( - host.ipaddress, - self.services['host']["publicport"], - self.services['host']["username"], - self.services['host']["password"], - router.linklocalip, - "service dnsmasq status" - ) - res = str(result) - self.debug("Dnsmasq process status: %s" % res) - - self.assertEqual( - res.count("running"), - 1, - "Check dnsmasq service is running or not" - ) - return - - -class TestdeployVMWithUserData(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestdeployVMWithUserData, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - - cls.services["domainid"] = cls.domain.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestdeployVMWithUserData, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_deployVMWithUserData(self): - """Test Deploy VM with User data""" - - # Validate the following - # 1. CreateAccount of type user - # 2. CreateSecurityGroup ssh-incoming - # 3. authorizeIngressRule to allow ssh-access - # 4. deployVirtualMachine into this group with some base64 encoded user-data - # 5. wget http://10.1.1.1/latest/user-data to get the latest userdata from the - # router for this VM - - # Find router associated with user account - list_router_response = list_routers( - self.apiclient, - zoneid=self.zone.id, - listall=True - ) - self.assertEqual( - isinstance(list_router_response, list), - True, - "Check list response returns a valid list" - ) - router = list_router_response[0] - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - # Should be able to SSH VM - try: - self.debug( - "SSH to VM with IP Address: %s"\ - % self.virtual_machine.ssh_ip - ) - - ssh = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH Access failed for %s: %s" % \ - (self.virtual_machine.ipaddress, e) - ) - - cmds = [ - "wget http://%s/latest/user-data" % router.guestipaddress, - "cat user-data", - ] - for c in cmds: - result = ssh.execute(c) - self.debug("%s: %s" % (c, result)) - - res = str(result) - self.assertEqual( - res.count(self.services["virtual_machine"]["userdata"]), - 1, - "Verify user data" - ) - return - - -class TestDeleteSecurityGroup(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - - self.services = Services().services - - # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) - - template = get_template( - self.apiclient, - self.zone.id, - self.services["ostypeid"] - ) - - self.services["domainid"] = self.domain.id - self.services["virtual_machine"]["zoneid"] = self.zone.id - self.services["virtual_machine"]["template"] = template.id - - self.service_offering = ServiceOffering.create( - self.apiclient, - self.services["service_offering"] - ) - self.account = Account.create( - self.apiclient, - self.services["account"], - domainid=self.domain.id - ) - self.services["account"] = self.account.account.name - self.cleanup = [ - self.account, - self.service_offering - ] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestDeleteSecurityGroup, cls).getClsTestClient().getApiClient() - cls._cleanup = [] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestDeleteSecurityGroup, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_delete_security_grp_running_vm(self): - """Test delete security group with running VM""" - - # Validate the following - # 1. createsecuritygroup (ssh-incoming) for this account - # 2. authorizeSecurityGroupIngress to allow ssh access to the VM - # 3. deployVirtualMachine into this security group (ssh-incoming) - # 4. deleteSecurityGroup created in step 1. Deletion should fail - # complaining there are running VMs in this group - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Deleting Security group should raise exception - security_group.delete(self.apiclient) - - #sleep to ensure that Security group is deleted properly - time.sleep(self.services["sleep"]) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - id=security_group.id - ) - self.assertNotEqual( - sercurity_groups, - None, - "Check List Security groups response" - ) - return - - def test_02_delete_security_grp_withoout_running_vm(self): - """Test delete security group without running VM""" - - # Validate the following - # 1. createsecuritygroup (ssh-incoming) for this account - # 2. authorizeSecurityGroupIngress to allow ssh access to the VM - # 3. deployVirtualMachine into this security group (ssh-incoming) - # 4. deleteSecurityGroup created in step 1. Deletion should fail - # complaining there are running VMs in this group - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # Destroy the VM - self.virtual_machine.delete(self.apiclient) - - config = list_configurations( - self.apiclient, - name='expunge.delay' - ) - self.assertEqual( - isinstance(config, list), - True, - "Check list configurations response" - ) - response = config[0] - self.debug("expunge.delay: %s" % response.value) - # Wait for some time more than expunge.delay - time.sleep(int(response.value) * 2) - - # Deleting Security group should raise exception - try: - self.debug("Deleting Security Group: %s" % security_group.id) - security_group.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete security group - ID: %s" \ - % security_group.id - ) - return - - -class TestIngressRule(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - self.services = Services().services - - # Get Zone, Domain and templates - self.domain = get_domain(self.apiclient, self.services) - self.zone = get_zone(self.apiclient, self.services) - - template = get_template( - self.apiclient, - self.zone.id, - self.services["ostypeid"] - ) - - self.services["domainid"] = self.domain.id - self.services["virtual_machine"]["zoneid"] = self.zone.id - self.services["virtual_machine"]["template"] = template.id - - self.service_offering = ServiceOffering.create( - self.apiclient, - self.services["service_offering"] - ) - self.account = Account.create( - self.apiclient, - self.services["account"], - domainid=self.domain.id - ) - self.services["account"] = self.account.account.name - self.cleanup = [ - self.account, - self.service_offering - ] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestIngressRule, cls).getClsTestClient().getApiClient() - cls._cleanup = [] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestIngressRule, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_authorizeIngressRule_AfterDeployVM(self): - """Test delete security group with running VM""" - - # Validate the following - # 1. createsecuritygroup (ssh-incoming, 22via22) for this account - # 2. authorizeSecurityGroupIngress to allow ssh access to the VM - # 3. deployVirtualMachine into this security group (ssh-incoming) - # 4. authorizeSecurityGroupIngress to allow ssh access (startport:222 to - # endport:22) to the VM - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule_1 = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule_1, dict), - True, - "Check ingress rule created properly" - ) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - # Authorize Security group to SSH to VM - ingress_rule_2 = security_group.authorize( - self.apiclient, - self.services["security_group_2"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule_2, dict), - True, - "Check ingress rule created properly" - ) - # SSH should be allowed on 22 & 2222 ports - try: - self.debug("Trying to SSH into VM %s on port %s" % ( - self.virtual_machine.ssh_ip, - self.services["security_group"]["endport"] - )) - self.virtual_machine.get_ssh_client() - - except Exception as e: - self.fail("SSH access failed for ingress rule ID: %s, %s" \ - % (ingress_rule_1["id"], e)) - - # User should be able to ping VM - try: - self.debug("Trying to ping VM %s" % self.virtual_machine.ssh_ip) - result = subprocess.call(['ping', '-c 1', self.virtual_machine.ssh_ip]) - - self.debug("Ping result: %s" % result) - # if ping successful, then result should be 0 - self.assertEqual( - result, - 0, - "Check if ping is successful or not" - ) - - except Exception as e: - self.fail("Ping failed for ingress rule ID: %s, %s" \ - % (ingress_rule_2["id"], e)) - return - - def test_02_revokeIngressRule_AfterDeployVM(self): - """Test Revoke ingress rule after deploy VM""" - - # Validate the following - # 1. createsecuritygroup (ssh-incoming, 22via22) for this account - # 2. authorizeSecurityGroupIngress to allow ssh access to the VM - # 3. deployVirtualMachine into this security group (ssh-incoming) - # 4. authorizeSecurityGroupIngress to allow ssh access (startport:222 - # to endport:22) to the VM - # 5. check ssh access via port 222 - # 6. revokeSecurityGroupIngress to revoke rule added in step 5. verify - # that ssh-access into the VM is now NOT allowed through ports 222 - # but allowed through port 22 - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule_2 = security_group.authorize( - self.apiclient, - self.services["security_group_2"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule_2, dict), - True, - "Check ingress rule created properly" - ) - - ssh_rule = (ingress_rule["ingressrule"][0]).__dict__ - icmp_rule = (ingress_rule_2["ingressrule"][0]).__dict__ - - # SSH should be allowed on 22 - try: - self.debug("Trying to SSH into VM %s on port %s" % ( - self.virtual_machine.ssh_ip, - self.services["security_group"]["endport"] - )) - self.virtual_machine.get_ssh_client() - - except Exception as e: - self.fail("SSH access failed for ingress rule ID: %s, %s" \ - % (ssh_rule["ruleid"], e)) - - # User should be able to ping VM - try: - self.debug("Trying to ping VM %s" % self.virtual_machine.ssh_ip) - result = subprocess.call(['ping', '-c 1', self.virtual_machine.ssh_ip]) - - self.debug("Ping result: %s" % result) - # if ping successful, then result should be 0 - self.assertEqual( - result, - 0, - "Check if ping is successful or not" - ) - - except Exception as e: - self.fail("Ping failed for ingress rule ID: %s, %s" \ - % (icmp_rule["ruleid"], e)) - - self.debug( - "Revoke Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - result = security_group.revoke( - self.apiclient, - id = icmp_rule["ruleid"] - ) - self.debug("Revoke ingress rule result: %s" % result) - - time.sleep(self.services["sleep"]) - # User should not be able to ping VM - try: - self.debug("Trying to ping VM %s" % self.virtual_machine.ssh_ip) - result = subprocess.call(['ping', '-c 1', self.virtual_machine.ssh_ip]) - - self.debug("Ping result: %s" % result) - # if ping successful, then result should be 0 - self.assertNotEqual( - result, - 0, - "Check if ping is successful or not" - ) - - except Exception as e: - self.fail("Ping failed for ingress rule ID: %s, %s" \ - % (icmp_rule["ruleid"], e)) - return - - def test_03_stopStartVM_verifyIngressAccess(self): - """Test Start/Stop VM and Verify ingress rule""" - - # Validate the following - # 1. createsecuritygroup (ssh-incoming, 22via22) for this account - # 2. authorizeSecurityGroupIngress to allow ssh access to the VM - # 3. deployVirtualMachine into this security group (ssh-incoming) - # 4. once the VM is running and ssh-access is available, - # stopVirtualMachine - # 5. startVirtualMachine. After stop start of the VM is complete - # verify that ssh-access to the VM is allowed - - security_group = SecurityGroup.create( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Created security group with ID: %s" % security_group.id) - # Default Security group should not have any ingress rule - sercurity_groups = SecurityGroup.list( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(sercurity_groups, list), - True, - "Check for list security groups response" - ) - - self.assertEqual( - len(sercurity_groups), - 2, - "Check List Security groups response" - ) - - self.debug( - "Authorize Ingress Rule for Security Group %s for account: %s" \ - % ( - security_group.id, - self.account.account.name - )) - - # Authorize Security group to SSH to VM - ingress_rule = security_group.authorize( - self.apiclient, - self.services["security_group"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(ingress_rule, dict), - True, - "Check ingress rule created properly" - ) - - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - securitygroupids=[security_group.id] - ) - self.debug("Deploying VM in account: %s" % self.account.account.name) - - # SSH should be allowed on 22 port - try: - self.debug("Trying to SSH into VM %s" % self.virtual_machine.ssh_ip) - self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH access failed for ingress rule ID: %s" \ - % ingress_rule["id"] - ) - - self.virtual_machine.stop(self.apiclient) - - # Sleep to ensure that VM is in stopped state - time.sleep(self.services["sleep"]) - - self.virtual_machine.start(self.apiclient) - - # Sleep to ensure that VM is in running state - time.sleep(self.services["sleep"]) - - # SSH should be allowed on 22 port after restart - try: - self.debug("Trying to SSH into VM %s" % self.virtual_machine.ssh_ip) - self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH access failed for ingress rule ID: %s" \ - % ingress_rule["id"] - ) - return \ No newline at end of file diff --git a/tools/testClient/testcase/P1-tests/test_snapshots.py b/tools/testClient/testcase/P1-tests/test_snapshots.py deleted file mode 100644 index 1e0a6cd0b07..00000000000 --- a/tools/testClient/testcase/P1-tests/test_snapshots.py +++ /dev/null @@ -1,1395 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Snapshots -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 200, # in MHz - "memory": 256, # In MBs - }, - "disk_offering": { - "displaytext": "Small Disk", - "name": "Small Disk", - "disksize": 1 - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": "root", - "password": "fr3sca", - "port": 22, - }, - "recurring_snapshot": { - "intervaltype": 'HOURLY', - # Frequency of snapshots - "maxsnaps": 1, # Should be min 2 - "schedule": 1, - "timezone": 'US/Arizona', - # Timezone Formats - http://cloud.mindtouch.us/CloudStack_Documentation/Developer's_Guide%3A_CloudStack - }, - "templates": { - "displaytext": 'Template', - "name": 'Template', - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - "templatefilter": 'self', - }, - "diskdevice": "/dev/xvda", - "diskname": "TestDiskServ", - "size": 1, # GBs - - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode" : 'advanced', # Networking mode: Advanced, Basic - } - - -class TestCreateVMsnapshotTemplate(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestCreateVMsnapshotTemplate, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["domainid"] = cls.domain.id - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = cls.template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_createVM_snapshotTemplate(self): - """Test create VM, Snapshot and Template - """ - - # Validate the following - # 1. Deploy VM using default template, small service offering - # and small data disk offering. - # 2. Perform snapshot on the root disk of this VM. - # 3. Create a template from snapshot. - # 4. Create a instance from above created template. - # 5. listSnapshots should list the snapshot that was created. - # 6. verify that secondary storage NFS share contains the reqd - # volume under /secondary/snapshots/$accountid/$volumeid/$snapshot_uuid - # 7. verify backup_snap_id was non null in the `snapshots` table - # 8. listTemplates() should return the newly created Template, - # and check for template state as READY" - # 9. listVirtualMachines() command should return the deployed VM. - # State of this VM should be Running. - - #Create Virtual Machine - self.virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Created VM with ID: %s" % self.virtual_machine.id) - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - volume = volumes[0] - - # Create a snapshot from the ROOTDISK - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - self.debug("Snapshot created: ID - %s" % snapshot.id) - self.cleanup.append(snapshot) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - self.debug("select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % snapshot.id) - # Verify backup_snap_id is not NULL - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % snapshot.id - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - # Generate template from the snapshot - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["templates"] - ) - self.debug("Created template from snapshot: %s" % template.id) - self.cleanup.append(template) - - templates = list_templates( - self.apiclient, - templatefilter=\ - self.services["templates"]["templatefilter"], - id=template.id - ) - - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].isready, - True, - "Check new template state in list templates call" - ) - - # Deploy new virtual machine using template - new_virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["server"], - templateid=template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id - ) - self.debug("Created VM with ID: %s from template: %s" % ( - new_virtual_machine.id, - template.id - )) - self.cleanup.append(new_virtual_machine) - - # Newly deployed VM should be 'Running' - virtual_machines = list_virtual_machines( - self.apiclient, - id=new_virtual_machine.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - # Sleep to ensure that snapshot is reflected in sec storage - time.sleep(self.services["sleep"]) - try: - # Login to VM to check snapshot present on sec disk - ssh_client = remoteSSHClient.remoteSSHClient( - self.services["mgmt_server"]["ipaddress"], - self.services["mgmt_server"]["port"], - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["password"], - ) - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - for c in cmds: - self.debug("command: %s" % c) - result = ssh_client.execute(c) - self.debug("Result: %s" % result) - - except Exception as e: - self.fail("SSH failed for Management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - try: - for c in cmds: - self.debug("command: %s" % c) - result = ssh_client.execute(c) - self.debug("Result: %s" % result) - - except Exception as e: - self.fail("SSH failed for Management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - - res = str(uuids) - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - - return - - -class TestAccountSnapshotClean(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAccountSnapshotClean, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - # Get the Root disk of VM - volumes = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - volume = volumes[0] - - # Create a snapshot from the ROOTDISK - cls.snapshot = Snapshot.create(cls.api_client, volumes[0].id) - - cls._cleanup = [ - cls.service_offering, - ] - 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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_02_accountSnapshotClean(self): - """Test snapshot cleanup after account deletion - """ - - # Validate the following - # 1. listAccounts API should list out the newly created account - # 2. listVirtualMachines() command should return the deployed VM. - # State of this VM should be "Running" - # 3. a)listSnapshots should list the snapshot that was created. - # b)verify that secondary storage NFS share contains the reqd volume - # under /secondary/snapshots/$accountid/$volumeid/$snapshot_uuid - # 4. a)listAccounts should not list account that is deleted - # b) snapshot image($snapshot_uuid) should be deleted from the - # /secondary/snapshots/$accountid/$volumeid/ - - accounts = list_accounts( - self.apiclient, - id=self.account.account.id - ) - self.assertEqual( - isinstance(accounts, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(accounts), - 0, - "Check list Accounts response" - ) - - # VM should be in 'Running' state - virtual_machines = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id - ) - self.assertEqual( - isinstance(virtual_machines, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(virtual_machines), - 0, - "Check list virtual machines response" - ) - for virtual_machine in virtual_machines: - self.debug("VM ID: %s, VM state: %s" % ( - virtual_machine.id, - virtual_machine.state - )) - self.assertEqual( - virtual_machine.state, - 'Running', - "Check list VM response for Running state" - ) - - # Verify the snapshot was created or not - snapshots = list_snapshots( - self.apiclient, - id=self.snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - self.snapshot.id, - "Check snapshot id in list resources call" - ) - - # Fetch values from database - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % self.snapshot.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB response returns a valid list" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - # Sleep to ensure that snapshot is reflected in sec storage - time.sleep(self.services["sleep"]) - try: - # Login to Secondary storage VM to check snapshot present on sec disk - ssh_client = remoteSSHClient.remoteSSHClient( - self.services["mgmt_server"]["ipaddress"], - self.services["mgmt_server"]["port"], - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["password"], - ) - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - self.debug("command: %s" % c) - result = ssh_client.execute(c) - self.debug("Result: %s" % result) - - uuids.append(result) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - result = ssh_client.execute(c) - except Exception: - self.fail("SSH failed for management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - - res = str(uuids) - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - - self.debug("Deleting account: %s" % self.account.account.name) - # Delete account - self.account.delete(self.apiclient) - - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - self.assertEqual( - isinstance(interval, list), - True, - "Check list response returns a valid list" - ) - self.debug("account.cleanup.interval: %s" % interval[0].value) - - # Wait for account cleanup interval - time.sleep(int(interval[0].value) * 2) - - accounts = list_accounts( - self.apiclient, - id=self.account.account.id - ) - - self.assertEqual( - accounts, - None, - "List accounts should return empty list after account deletion" - ) - - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - try: - cmds = [ - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - self.debug("command: %s" % c) - result = ssh_client.execute(c) - self.debug("Result: %s" % result) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - self.debug("command: %s" % c) - result = ssh_client.execute(c) - self.debug("Result: %s" % result) - - except Exception: - self.fail("SSH failed for management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - - res = str(uuids) - self.assertNotEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - return - - -class TestSnapshotDetachedDisk(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshotDetachedDisk, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["server"]["diskoffering"] = cls.disk_offering.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_03_snapshot_detachedDisk(self): - """Test snapshot from detached disk - """ - - # Validate the following - # 1. login in VM and write some data on data disk(use fdisk to - # partition datadisk,fdisk /dev/sdb, and make filesystem using - # mkfs.ext3) - # 2. Detach the data disk and write some data on data disk - # 3. perform the snapshot on the detached volume - # 4. listvolumes with VM id shouldn't show the detached volume - # 5. listSnapshots should list the snapshot that was created - # 6. verify that secondary storage NFS share contains the reqd volume - # under /secondary/snapshots/$accountid/$volumeid/$snapshot_uuid - # 7. verify backup_snap_id was non null in the `snapshots` table - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - volume = volumes[0] - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - try: - ssh_client = self.virtual_machine.get_ssh_client() - - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] - ), - "pushd %s" % self.services["mount_dir"], - "mkdir -p %s/{%s,%s} " % ( - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s" % ( - random_data_0, - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), - "echo %s > %s/%s/%s" % ( - random_data_1, - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), - "sync", - ] - for c in cmds: - self.debug(ssh_client.execute(c)) - - #detach volume from VM - cmd = detachVolume.detachVolumeCmd() - cmd.id = volume.id - self.apiclient.detachVolume(cmd) - - #Create snapshot from detached volume - snapshot = Snapshot.create(self.apiclient, volume.id) - self.cleanup.append(snapshot) - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - - self.assertEqual( - volumes, - None, - "Check Volume is detached" - ) - - # Verify the snapshot was created or not - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - - # Fetch values from database - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % snapshot.id - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - self.assertNotEqual( - str(qresult[0]), - 'NULL', - "Check if backup_snap_id is not null" - ) - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - - # Sleep to ensure that snapshot is reflected in sec storage - time.sleep(self.services["sleep"]) - try: - # Login to Management server to check snapshot present on - # sec disk - ssh_client = remoteSSHClient.remoteSSHClient( - self.services["mgmt_server"]["ipaddress"], - self.services["mgmt_server"]["port"], - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["password"], - ) - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - result = ssh_client.execute(c) - - uuids.append(result) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - result = ssh_client.execute(c) - except Exception as e: - self.fail("SSH failed for management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - - res = str(uuids) - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - return - - -class TestSnapshotLimit(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshotLimit, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_04_snapshot_limit(self): - """Test snapshot limit in snapshot policies - """ - - # Validate the following - # 1. Perform hourly recurring snapshot on the root disk of VM and keep - # the maxsnapshots as 1 - # 2. listSnapshots should list the snapshot that was created - # snapshot folder in secondary storage should contain only one - # snapshot image(/secondary/snapshots/$accountid/$volumeid/) - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - volume = volumes[0] - - # Create a snapshot policy - recurring_snapshot = SnapshotPolicy.create( - self.apiclient, - volume.id, - self.services["recurring_snapshot"] - ) - self.cleanup.append(recurring_snapshot) - - snapshot_policy = list_snapshot_policy( - self.apiclient, - id=recurring_snapshot.id, - volumeid=volume.id - ) - self.assertEqual( - isinstance(snapshot_policy, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - snapshot_policy, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - snapshot_policy[0].id, - recurring_snapshot.id, - "Check recurring snapshot id in list resources call" - ) - self.assertEqual( - snapshot_policy[0].maxsnaps, - self.services["recurring_snapshot"]["maxsnaps"], - "Check interval type in list resources call" - ) - # Sleep for (maxsnaps+1) hours to verify - # only maxsnaps snapshots are retained - time.sleep( - (self.services["recurring_snapshot"]["maxsnaps"]) * 3600 - ) - - # Verify the snapshot was created or not - snapshots = list_snapshots( - self.apiclient, - volumeid=volume.id, - intervaltype=\ - self.services["recurring_snapshot"]["intervaltype"], - snapshottype='RECURRING', - listall=True - ) - - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(snapshots), - self.services["recurring_snapshot"]["maxsnaps"], - "Check maximum number of recurring snapshots retained" - ) - snapshot = snapshots[0] - # Sleep to ensure that snapshot is reflected in sec storage - time.sleep(self.services["sleep"]) - - # Fetch values from database - qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ - % snapshot.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DBQuery returns a valid list" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = qresultset[0] - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - try: - # Login to VM to check snapshot present on sec disk - ssh_client = remoteSSHClient.remoteSSHClient( - self.services["mgmt_server"]["ipaddress"], - self.services["mgmt_server"]["port"], - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["password"], - ) - - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], - "mount %s/%s %s" % ( - sec_storage_ip, - export_path, - self.services["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - result = ssh_client.execute(c) - - uuids.append(result) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["mount_dir"]), - ] - for c in cmds: - result = ssh_client.execute(c) - except Exception as e: - raise Exception( - "SSH access failed for management server: %s" % - self.services["mgmt_server"]["ipaddress"]) - - res = str(uuids) - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) - return - - -class TestSnapshotEvents(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshotEvents, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - - cls._cleanup = [ - cls.service_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_05_snapshot_events(self): - """Test snapshot events - """ - - # Validate the following - # 1. Perform snapshot on the root disk of this VM and check the events/alerts. - # 2. delete the snapshots and check the events/alerts - # 3. listEvents() shows created/deleted snapshot events - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - volume = volumes[0] - - # Create a snapshot from the ROOTDISK - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - self.debug("Snapshot created with ID: %s" % snapshot.id) - - snapshots = list_snapshots( - self.apiclient, - id=snapshot.id - ) - self.assertEqual( - isinstance(snapshots, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - snapshots, - None, - "Check if result exists in list snapshots call" - ) - self.assertEqual( - snapshots[0].id, - snapshot.id, - "Check snapshot id in list resources call" - ) - snapshot.delete(self.apiclient) - - # Sleep to ensure that snapshot is deleted properly - time.sleep(self.services["sleep"]) - events = list_events( - self.apiclient, - account=self.account.account.name, - domainid=self.account.account.domainid, - type='SNAPSHOT.DELETE' - ) - self.assertEqual( - isinstance(events, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - events, - None, - "Check if event exists in list events call" - ) - self.assertIn( - events[0].state, - ['Completed', 'Scheduled'], - "Check events state in list events call" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_templates.py b/tools/testClient/testcase/P1-tests/test_templates.py deleted file mode 100644 index 3d4fe01f554..00000000000 --- a/tools/testClient/testcase/P1-tests/test_templates.py +++ /dev/null @@ -1,611 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Templates -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import urllib -from random import random -#Import System modules -import time - - -class Services: - """Test Templates Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "virtual_machine": { - "displayname": "testVM", - "hypervisor": 'XenServer', - "protocol": 'TCP', - "ssh_port": 22, - "username": "root", - "password": "password", - "privateport": 22, - "publicport": 22, - }, - "volume": { - "diskname": "Test Volume", - }, - "templates": { - # Configs for different Template formats - # For Eg. raw image, zip etc - 0:{ - "displaytext": "Public Template", - "name": "Public template", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2", - "hypervisor": 'XenServer', - "format" : 'VHD', - "isfeatured": True, - "ispublic": True, - "isextractable": True, - }, - }, - "template": { - "displaytext": "Cent OS Template", - "name": "Cent OS Template", - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "templatefilter": 'self', - }, - "templatefilter": 'self', - "destzoneid": 2, # For Copy template (Destination zone) - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "sleep": 60, - "timeout": 10, - "mode": 'advanced', # Networking mode: Advanced, basic - } - - -@unittest.skip("Open questions") -class TestCreateTemplate(cloudstackTestCase): - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - self.dbclient.close() - #Clean up, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @classmethod - def setUpClass(cls): - cls.services = Services().services - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls._cleanup = [ - cls.account, - cls.service_offering - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient() - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_create_template(self): - """Test create public & private template - """ - - # Validate the following: - # 1. Upload a templates in raw img format. Create a Vm instances from - # raw img template. - # 2. Upload a templates in zip file format. Create a Vm instances from - # zip template. - # 3. Upload a templates in tar format.Create a Vm instances from tar - # template. - # 4. Upload a templates in tar gzip format.Create a Vm instances from - # tar gzip template. - # 5. Upload a templates in tar bzip format. Create a Vm instances from - # tar bzip template. - # 6. Verify VMs & Templates is up and in ready state - - for k, v in self.services["templates"].items(): - - # Register new template - template = Template.register( - self.apiclient, - v, - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug( - "Registered a template of format: %s with ID: %s" % ( - v["format"], - template.id - )) - # Wait for template to download - template.download(self.apiclient) - self.cleanup.append(template) - - # Wait for template status to be changed across - time.sleep(self.services["sleep"]) - timeout = self.services["timeout"] - while True: - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=template.id, - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - if isinstance(list_template_response, list): - break - elif timeout == 0: - raise Exception("List template failed!") - - time.sleep(5) - timeout = timeout - 1 - #Verify template response to check whether template added successfully - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check for list template response return valid data" - ) - - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - - template_response = list_template_response[0] - self.assertEqual( - template_response.isready, - True, - "Check display text of newly created template" - ) - - # Deploy new virtual machine using template - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - mode=self.services["mode"] - ) - self.debug("creating an instance with template ID: %s" % template.id) - vm_response = list_virtual_machines( - self.apiclient, - id=virtual_machine.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check for list VMs response after VM deployment" - ) - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM created from Template" - ) - return - - -class TestTemplates(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - - cls.services = Services().services - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - - # Get Zone, templates etc - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - - # create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - timeout = cls.services["timeout"] - #Wait before server has be successfully stopped - time.sleep(cls.services["sleep"]) - - while True: - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - break - elif timeout == 0: - raise Exception("List volumes failed.") - - time.sleep(5) - timeout = timeout -1 - - cls.volume = list_volume[0] - - #Create template from volume - cls.template = Template.create( - cls.api_client, - cls.services["template"], - cls.volume.id - ) - cls._cleanup = [ - cls.service_offering, - cls.account, - ] - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient() - #Cleanup created resources such as templates and VMs - 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, terminate the created templates - cleanup_resources(self.apiclient, self.cleanup) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - return - - def test_01_create_template_volume(self): - """Test Create template from volume - """ - - # Validate the following: - # 1. Deploy new VM using the template created from Volume - # 2. VM should be in Up and Running state - - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - ) - - self.debug("creating an instance with template ID: %s" % self.template.id) - self.cleanup.append(virtual_machine) - vm_response = list_virtual_machines( - self.apiclient, - id=virtual_machine.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM created from Template" - ) - return - - def test_02_copy_template(self): - """Test for copy template from one zone to another""" - - # Validate the following - # 1. copy template should be successful and - # secondary storage should contain new copied template. - - self.debug( - "Copying template from zone: %s to %s" % ( - self.template.id, - self.services["destzoneid"] - )) - cmd = copyTemplate.copyTemplateCmd() - cmd.id = self.template.id - cmd.destzoneid = self.services["destzoneid"] - cmd.sourcezoneid = self.zone.id - self.apiclient.copyTemplate(cmd) - - # Verify template is copied to another zone using ListTemplates - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["templatefilter"], - id=self.template.id, - zoneid=self.services["destzoneid"] - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check for list template response return valid list" - ) - - self.assertNotEqual( - len(list_template_response), - 0, - "Check template extracted in List Templates" - ) - - template_response = list_template_response[0] - self.assertEqual( - template_response.id, - self.template.id, - "Check ID of the downloaded template" - ) - self.assertEqual( - template_response.zoneid, - self.services["destzoneid"], - "Check zone ID of the copied template" - ) - - # Cleanup- Delete the copied template - cmd = deleteTemplate.deleteTemplateCmd() - cmd.id = self.template.id - cmd.zoneid = self.services["destzoneid"] - self.apiclient.deleteTemplate(cmd) - return - - def test_03_delete_template(self): - """Test Delete template - """ - - # Validate the following: - # 1. Create a template and verify it is shown in list templates response - # 2. Delete the created template and again verify list template response - - # Verify template response for updated attributes - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["template"]["templatefilter"], - id=self.template.id, - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_template_response, list), - True, - "Check for list template response return valid list" - ) - - self.assertNotEqual( - len(list_template_response), - 0, - "Check template available in List Templates" - ) - template_response = list_template_response[0] - - self.assertEqual( - template_response.id, - self.template.id, - "Check display text of updated template" - ) - - self.debug("Deleting template: %s" % self.template) - # Delete the template - self.template.delete(self.apiclient) - self.debug("Delete template: %s successful" % self.template) - - list_template_response = list_templates( - self.apiclient, - templatefilter=\ - self.services["template"]["templatefilter"], - id=self.template.id, - zoneid=self.zone.id - ) - self.assertEqual( - list_template_response, - None, - "Check template available in List Templates" - ) - return - - def test_04_template_from_snapshot(self): - """Create Template from snapshot - """ - - # Validate the following - # 2. Snapshot the Root disk - # 3. Create Template from snapshot - # 4. Deploy Virtual machine using this template - # 5. VM should be in running state - - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - volume = volumes[0] - - self.debug("Creating a snapshot from volume: %s" % volume.id) - #Create a snapshot of volume - snapshot = Snapshot.create( - self.apiclient, - volume.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.debug("Creating a template from snapshot: %s" % snapshot.id) - # Generate template from the snapshot - template = Template.create_from_snapshot( - self.apiclient, - snapshot, - self.services["template"] - ) - self.cleanup.append(template) - # Verify created template - templates = list_templates( - self.apiclient, - templatefilter=\ - self.services["template"]["templatefilter"], - id=template.id - ) - self.assertNotEqual( - templates, - None, - "Check if result exists in list item call" - ) - - self.assertEqual( - templates[0].id, - template.id, - "Check new template id in list resources call" - ) - self.debug("Deploying a VM from template: %s" % template.id) - # Deploy new virtual machine using template - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=template.id, - accountid=self.account.account.name, - domainid=self.account.account.domainid, - serviceofferingid=self.service_offering.id, - ) - self.cleanup.append(virtual_machine) - - vm_response = list_virtual_machines( - self.apiclient, - id=virtual_machine.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check for list VM response return valid list" - ) - - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM created from Template" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_usage.py b/tools/testClient/testcase/P1-tests/test_usage.py deleted file mode 100644 index 08cee5f17d2..00000000000 --- a/tools/testClient/testcase/P1-tests/test_usage.py +++ /dev/null @@ -1,1573 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Snapshots -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -import datetime - -class Services: - """Test Snapshots Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "volume": { - "diskname": "TestDiskServ", - }, - "server": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'XenServer', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "templates": { - "displaytext": 'Template', - "name": 'Template', - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - "templatefilter": 'self', - "url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.qcow2.bz2" - }, - "iso": { - "displaytext": "Test ISO", - "name": "Test ISO", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", - # Source URL where ISO is located - "isextractable": True, - "isfeatured": True, - "ispublic": True, - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - }, - "lbrule": { - "name": "SSH", - "alg": "roundrobin", - # Algorithm used for load balancing - "privateport": 22, - "publicport": 2222, - }, - "natrule": { - "privateport": 22, - "publicport": 22, - "protocol": "TCP" - }, - "vpn_user": { - "username": "test", - "password": "test", - }, - "ostypeid": '144f66aa-7f74-4cfe-9799-80cc21439cb3', - # Cent OS 5.3 (64 bit) - "sleep": 60, - "timeout": 10, - "mode":'advanced' - } - - -class TestVmUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestVmUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vm_usage(self): - """Test Create/Destroy VM and verify usage calculation - """ - - # Validate the following - # 1. Create a VM. Verify usage_events table contains VM .create, - # VM.start , Network.offering.assign , Volume.create events - # 2. Stop the VM. Verify usage_events table contains - # network.offerings.remove ,VM .stop Events for the created account. - # 3. Destroy the VM after some time. Verify usage_events table contains - # VM.Destroy and volume .delete Event for the created account - # 4. Delete the account - - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop the VM - self.virtual_machine.stop(self.apiclient) - - time.sleep(self.services["sleep"]) - # Destroy the VM - self.debug("Destroying the VM: %s" % self.virtual_machine.id) - self.virtual_machine.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - # Check if VM.CREATE, VM.DESTROY events present in usage_event table - self.assertEqual( - qresult.count('VM.START'), - 1, - "Check VM.START event in events table" - ) - - self.assertEqual( - qresult.count('NETWORK.OFFERING.ASSIGN'), - 1, - "Check NETWORK.OFFERING.ASSIGN in events table" - ) - self.assertEqual( - qresult.count('VM.CREATE'), - 1, - "Check VM.CREATE in list events" - ) - - self.assertEqual( - qresult.count('VOLUME.CREATE'), - 1, - "Check VOLUME.CREATE in events table" - ) - - self.assertEqual( - qresult.count('VM.STOP'), - 1, - "Check VM.STOP in events table" - ) - - self.assertEqual( - qresult.count('NETWORK.OFFERING.REMOVE'), - 1, - "Check NETWORK.OFFERING.REMOVE in list events" - ) - - self.assertEqual( - qresult.count('VM.DESTROY'), - 1, - "Check VM.DESTROY in events table" - ) - - self.assertEqual( - qresult.count('VOLUME.DELETE'), - 1, - "Check VOLUME.DELETE in events table" - ) - return - - -class TestPublicIPUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestPublicIPUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, Assign Public IP etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - - cls.public_ip = PublicIPAddress.create( - cls.api_client, - cls.virtual_machine.account, - cls.virtual_machine.zoneid, - cls.virtual_machine.domainid, - cls.services["server"] - ) - cls._cleanup = [ - cls.service_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, terminate the created instance - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_public_ip_usage(self): - """Test Assign new IP and verify usage calculation - """ - - # Validate the following - # 1. Aquire a IP for the network of this account. Verify usage_event - # table has Acquire IP event for the IP for this account - # 2. Release one of the IP of this account. Verify usage_event table - # has IP.Release event for released IP for this account - # 3. Delete the newly created account - - self.debug("Deleting public IP: %s" % - self.public_ip.ipaddress.ipaddress) - - # Release one of the IP - self.public_ip.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - # Check if NET.IPASSIGN, NET.IPRELEASE events present in usage_event - # table - self.assertEqual( - qresult.count('NET.IPASSIGN') > 0, - True, - "Check NET.IPASSIGN event in events table" - ) - - self.assertEqual( - qresult.count('NET.IPRELEASE') > 0, - True, - "Check NET.IPRELEASE in events table" - ) - return - - -class TestVolumeUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestVolumeUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["server"]["diskoffering"] = cls.disk_offering.id - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_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, terminate the created instance, volumes - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_volume_usage(self): - """Test Create/delete a volume and verify correct usage is recorded - """ - - # Validate the following - # 1. Volume.create event for both root and data disk is there for the - # created account in cloud.usage_event table - # 2. Stop the VM - # 3. Detach the data disk from this VM - # 4. Destroy the Data disk. Volume.delete event is generated for data - # disk of the destroyed VM - - # Stop VM - self.debug("Stopping VM with ID: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - - volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(volume_response, list), - True, - "Check for valid list volumes response" - ) - data_volume = volume_response[0] - - # Detach data Disk - self.debug("Detaching volume ID: %s VM with ID: %s" % ( - data_volume.id, - self.virtual_machine.id - )) - self.virtual_machine.detach_volume(self.apiclient, data_volume) - - # Delete Data disk - self.debug("Delete volume ID: %s" % data_volume.id) - cmd = deleteVolume.deleteVolumeCmd() - cmd.id = data_volume.id - self.apiclient.deleteVolume(cmd) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - # Check VOLUME.CREATE, VOLUME.DESTROY events in cloud.usage_event table - self.assertEqual( - qresult.count('VOLUME.CREATE'), - 2, - "Check VOLUME.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('VOLUME.DELETE'), - 1, - "Check VOLUME.DELETE in events table" - ) - return - - -class TestTemplateUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestTemplateUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["server"]["zoneid"] = cls.zone.id - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - #create virtual machine - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - #Stop virtual machine - cls.virtual_machine.stop(cls.api_client) - - #Wait before server has be successfully stopped - time.sleep(30) - list_volume = list_volumes( - cls.api_client, - virtualmachineid=cls.virtual_machine.id, - type='ROOT', - listall=True - ) - if isinstance(list_volume, list): - cls.volume = list_volume[0] - else: - raise Exception("List Volumes failed!") - 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, terminate the created instance, templates - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_template_usage(self): - """Test Upload/ delete a template and verify correct usage is generated - for the template uploaded - """ - - # Validate the following - # 1. Create a account - # 2. Upload a template from this account. template.create event is - # recorded in cloud.usage_event table for this account - # 3. Delete the template. template.delete event is recorded in - # cloud.usage_event tables for this account - # 4. Destroy the account - - #Create template from Virtual machine and Volume ID - self.template = Template.create( - self.apiclient, - self.services["templates"], - self.volume.id - ) - self.debug("Created template with ID: %s" % self.template.id) - # Delete template - self.template.delete(self.apiclient) - self.debug("Deleted template with ID: %s" % self.template.id) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for TEMPLATE.CREATE, TEMPLATE.DELETE in cloud.usage_event table - self.assertEqual( - qresult.count('TEMPLATE.CREATE'), - 1, - "Check TEMPLATE.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('TEMPLATE.DELETE'), - 1, - "Check TEMPLATE.DELETE in events table" - ) - return - - -class TestISOUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestISOUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services["server"]["zoneid"] = cls.zone.id - cls.services["iso"]["zoneid"] = cls.zone.id - # Create Account, ISO image etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.account.name - cls.iso = Iso.create( - cls.api_client, - cls.services["iso"], - account=cls.account.account.name, - domainid=cls.account.account.domainid - ) - try: - # Wait till ISO gets downloaded - cls.iso.download(cls.api_client) - except Exception as e: - raise Exception("%s: Failed to download ISO: %s" % ( - e, - cls.iso.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, terminate the created ISO images - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_ISO_usage(self): - """Test Create/Delete a ISO and verify its usage is generated correctly - """ - - # Validate the following - # 1. Create a account - # 2. Upload a ISO from this account. ISO.create event is recorded in - # cloud.usage_event table for this account - # 3. Delete the ISO. ISO.delete event is recorded in cloud.usage_event - # tables for this account - # 4. Destroy the account - - # Delete the ISO - self.debug("Deleting ISO with ID: %s" % self.iso.id) - self.iso.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for ISO.CREATE, ISO.DELETE events in cloud.usage_event table - self.assertEqual( - qresult.count('ISO.CREATE'), - 1, - "Check ISO.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('ISO.DELETE'), - 1, - "Check ISO.DELETE in events table" - ) - return - - -class TestLBRuleUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestLBRuleUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, LB Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.public_ip_1 = PublicIPAddress.create( - cls.api_client, - cls.virtual_machine.account, - cls.virtual_machine.zoneid, - cls.virtual_machine.domainid, - cls.services["server"] - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, LB rules - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_lb_usage(self): - """Test Create/Delete a LB rule and verify correct usage is recorded - """ - - # Validate the following - # 1. Acquire a IP for this account. lb.rule.create event is registered - # for this account in cloud.usage_event table - # 2. Create a LB rule on the IP associated with this account - # 3. Delete the created LB rule from the account. lb.rule.delete event - # is registered for this account in cloud.usage_event table - # 4. Delete this account. - - self.debug( - "Creating load balancer rule for public IP: %s" % - self.public_ip_1.ipaddress.id) - #Create Load Balancer rule and assign VMs to rule - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - self.public_ip_1.ipaddress.id, - accountid=self.account.account.name - ) - # Delete LB Rule - self.debug("Deleting LB rule with ID: %s" % lb_rule.id) - lb_rule.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for LB.CREATE, LB.DELETE in cloud.usage_event table - self.assertEqual( - qresult.count('LB.CREATE'), - 1, - "Check LB.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('LB.DELETE'), - 1, - "Check LB.DELETE in events table" - ) - return - - -class TestSnapshotUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshotUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Account, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls._cleanup = [ - cls.service_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, terminate the created instance and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_snapshot_usage(self): - """Test Create/Delete a manual snap shot and verify - correct usage is recorded - """ - - # Validate the following - # 1. Create snapshot of the root disk for this account.Snapshot.create - # event is there for the created account in cloud.usage_event table - # 2. Destroy the snapshot after some time. Snapshot.delete event is - # generated for the destroyed Snapshot - # 3. Delete the account - - # Get the Root disk of VM - volumes = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='ROOT', - listall=True - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check if list volumes return a valid data" - ) - - volume = volumes[0] - - # Create a snapshot from the ROOTDISK - self.debug("Creating snapshot from volume: %s" % volumes[0].id) - snapshot = Snapshot.create(self.apiclient, volumes[0].id) - - # Delete snapshot Rule - self.debug("Deleting snapshot: %s" % snapshot.id) - snapshot.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check if database query returns a valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query Result: %s" % qresult) - - # Check for SNAPSHOT.CREATE, SNAPSHOT.DELETE events in cloud.usage_event - # table - self.assertEqual( - qresult.count('SNAPSHOT.CREATE'), - 1, - "Check SNAPSHOT.CREATE event in events table" - ) - - self.assertEqual( - qresult.count('SNAPSHOT.DELETE'), - 1, - "Check SNAPSHOT.DELETE in events table" - ) - return - - -class TestNatRuleUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestNatRuleUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.public_ip_1 = PublicIPAddress.create( - cls.api_client, - cls.virtual_machine.account, - cls.virtual_machine.zoneid, - cls.virtual_machine.domainid, - cls.services["server"] - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, NAT rules - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_nat_usage(self): - """Test Create/Delete a PF rule and verify correct usage is recorded - """ - - # Validate the following - # 1. Acquire a IP for this account - # 2. Create a PF rule on the IP associated with this account. - # NET.RULEADD event is registered for this account in - # cloud.usage_event table - # 3. Delete the created PF rule from the account. NET.RULEDelete event - # is registered for this account in cloud.usage_event table - # 4. Delete this account. - - self.debug("Creating NAT rule with public IP: %s" % - self.public_ip_1.ipaddress.id) - #Create NAT rule - nat_rule = NATRule.create( - self.apiclient, - self.virtual_machine, - self.services["natrule"], - self.public_ip_1.ipaddress.id - ) - - # Delete NAT Rule - self.debug("Deleting NAT rule: %s" % nat_rule.id) - nat_rule.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for NET.RULEADD, NET.RULEDELETE in cloud.usage_event table - self.assertEqual( - qresult.count('NET.RULEADD'), - 1, - "Check NET.RULEADD event in events table" - ) - - self.assertEqual( - qresult.count('NET.RULEDELETE'), - 1, - "Check NET.RULEDELETE in events table" - ) - return - - -class TestVpnUsage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestVpnUsage, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create Service offerings, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id - ) - cls.public_ip = PublicIPAddress.create( - cls.api_client, - cls.virtual_machine.account, - cls.virtual_machine.zoneid, - cls.virtual_machine.domainid, - cls.services["server"] - ) - cls._cleanup = [ - cls.service_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, terminate the created instance, VPN users - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_vpn_usage(self): - """Test Create/Delete a VPN and verify correct usage is recorded - """ - - # Validate the following - # 1. Enable VPN for this IP. vpn.add.user event is registered for this - # account in cloud.usage_event table - # 2. Add user to this vpn - # 3. Delete user for this VPN. vpn.user.delete event is registered for - # this account in cloud.usage_event table - # 4. Delete this account. - - self.debug("Created VPN with public IP: %s" % - self.public_ip.ipaddress.id) - #Assign VPN to Public IP - vpn = Vpn.create( - self.apiclient, - self.public_ip.ipaddress.id, - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - self.debug("Created VPN user for account: %s" % - self.account.account.name) - - vpnuser = VpnUser.create( - self.apiclient, - self.services["vpn_user"]["username"], - self.services["vpn_user"]["password"], - account=self.account.account.name, - domainid=self.account.account.domainid - ) - - # Remove VPN user - self.debug("Deleting VPN user: %s" % vpnuser.id) - vpnuser.delete(self.apiclient) - - # Delete VPN access - self.debug("Deleting VPN: %s" % vpn.publicipid) - vpn.delete(self.apiclient) - - # Fetch account ID from account_uuid - self.debug("select id from account where uuid = '%s';" \ - % self.account.account.id) - - qresultset = self.dbclient.execute( - "select id from account where uuid = '%s';" \ - % self.account.account.id - ) - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - qresult = qresultset[0] - - account_id = qresult[0] - self.debug("select type from usage_event where account_id = '%s';" \ - % account_id) - - qresultset = self.dbclient.execute( - "select type from usage_event where account_id = '%s';" \ - % account_id - ) - - self.assertEqual( - isinstance(qresultset, list), - True, - "Check DB query result set for valid data" - ) - self.assertNotEqual( - len(qresultset), - 0, - "Check DB Query result set" - ) - - qresult = str(qresultset) - self.debug("Query result: %s" % qresult) - - # Check for VPN user related events - self.assertEqual( - qresult.count('VPN.USER.ADD'), - 1, - "Check VPN.USER.ADD event in events table" - ) - - self.assertEqual( - qresult.count('VPN.USER.ADD'), - 1, - "Check VPN.USER.ADD in events table" - ) - return diff --git a/tools/testClient/testcase/P1-tests/test_volumes.py b/tools/testClient/testcase/P1-tests/test_volumes.py deleted file mode 100644 index 94ca64337d0..00000000000 --- a/tools/testClient/testcase/P1-tests/test_volumes.py +++ /dev/null @@ -1,1018 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -""" P1 tests for Volumes -""" -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -from testcase.libs.utils import * -from testcase.libs.base import * -from testcase.libs.common import * -import remoteSSHClient -#Import System modules -import os -import urllib -import time -import tempfile - - -class Services: - """Test Volume Services - """ - - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 64, # In MBs - }, - "disk_offering": { - "displaytext": "Small", - "name": "Small", - "disksize": 1 - }, - "volume": { - "diskname": "TestDiskServ", - "max": 6, - }, - "virtual_machine": { - "displayname": "testVM", - "hypervisor": 'XenServer', - "protocol": 'TCP', - "ssh_port": 22, - "username": "root", - "password": "password", - "privateport": 22, - "publicport": 22, - }, - "iso": # ISO settings for Attach/Detach ISO tests - { - "displaytext": "Test ISO", - "name": "testISO", - "url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso", - # Source URL where ISO is located - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - }, - "sleep": 50, - "ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9', - "mode": 'advanced', - } - - -class TestAttachVolume(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAttachVolume, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account - ] - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def test_01_volume_attach(self): - """Test Attach volumes (max capacity) - """ - - # Validate the following - # 1. Deploy a vm and create 5 data disk - # 2. Attach all the created Volume to the vm. - # 3. Reboot the VM. VM should be successfully rebooted - # 4. Stop the VM. Stop VM should be successful - # 5. Start The VM. Start VM should be successful - - # Create 5 volumes and attach to VM - for i in range(self.services["volume"]["max"]): - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.account.name - )) - # Check List Volume response for newly created volume - list_volume_response = list_volumes( - self.apiclient, - id=volume.id - ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - # Attach volume to VM - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - self.debug("Attach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - # Check all volumes attached to same VM - list_volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.assertEqual( - len(list_volume_response), - self.services["volume"]["max"], - "Check number of data volumes attached to VM" - ) - self.debug("Rebooting the VM: %s" % self.virtual_machine.id) - # Reboot VM - self.virtual_machine.reboot(self.apiclient) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM" - ) - - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - # Stop VM - self.virtual_machine.stop(self.apiclient) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Stopped', - "Check the state of VM" - ) - - self.debug("Starting the VM: %s" % self.virtual_machine.id) - # Start VM - self.virtual_machine.start(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - - #Verify VM response to check whether VM deployment was successful - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM" - ) - return - - def test_02_volume_attach_max(self): - """Test attach volumes (more than max) to an instance - """ - - # Validate the following - # 1. Attach one more data volume to VM (Already 5 attached) - # 2. Attach volume should fail - - # Create a volume and attach to VM - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.account.name - )) - # Check List Volume response for newly created volume - list_volume_response = list_volumes( - self.apiclient, - id=volume.id - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - # Attach volume to VM - with self.assertRaises(Exception): - self.debug("Trying to Attach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - return - - def tearDown(self): - #Clean up, terminate the created volumes - cleanup_resources(self.apiclient, self.cleanup) - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestAttachVolume, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - -class TestAttachDetachVolume(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAttachDetachVolume, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account - ] - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def tearDown(self): - #Clean up, terminate the created volumes - cleanup_resources(self.apiclient, self.cleanup) - return - - @classmethod - def tearDownClass(cls): - try: - cls.api_client = super(TestAttachDetachVolume, cls).getClsTestClient().getApiClient() - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def test_01_volume_attach_detach(self): - """Test Volume attach/detach to VM (5 data volumes) - """ - - # Validate the following - # 1. Deploy a vm and create 5 data disk - # 2. Attach all the created Volume to the vm. - # 3. Detach all the volumes attached. - # 4. Reboot the VM. VM should be successfully rebooted - # 5. Stop the VM. Stop VM should be successful - # 6. Start The VM. Start VM should be successful - - volumes = [] - # Create 5 volumes and attach to VM - for i in range(self.services["volume"]["max"]): - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.account.name - )) - self.cleanup.append(volume) - volumes.append(volume) - - # Check List Volume response for newly created volume - list_volume_response = list_volumes( - self.apiclient, - id=volume.id - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.debug("Attach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - # Attach volume to VM - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - - # Check all volumes attached to same VM - list_volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.assertEqual( - len(list_volume_response), - self.services["volume"]["max"], - "Check number of data volumes attached to VM" - ) - - # Detach all volumes from VM - for volume in volumes: - self.debug("Detach volume: %s to VM: %s" % ( - volume.id, - self.virtual_machine.id - )) - self.virtual_machine.detach_volume( - self.apiclient, - volume - ) - # Reboot VM - self.debug("Rebooting the VM: %s" % self.virtual_machine.id) - self.virtual_machine.reboot(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM" - ) - - # Stop VM - self.debug("Stopping the VM: %s" % self.virtual_machine.id) - self.virtual_machine.stop(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Stopped', - "Check the state of VM" - ) - - # Start VM - self.debug("Starting the VM: %s" % self.virtual_machine.id) - self.virtual_machine.start(self.apiclient) - # Sleep to ensure that VM is in ready state - time.sleep(self.services["sleep"]) - - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.state, - 'Running', - "Check the state of VM" - ) - return - - -class TestAttachVolumeISO(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestAttachVolumeISO, cls).getClsTestClient().getApiClient() - cls.services = Services().services - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["iso"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account - ] - - @classmethod - def tearDownClass(cls): - try: - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def tearDown(self): - try: - #Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def test_01_volume_iso_attach(self): - """Test Volumes and ISO attach - """ - - # Validate the following - # 1. Create and attach 5 data volumes to VM - # 2. Create an ISO. Attach it to VM instance - # 3. Verify that attach ISO is successful - - # Create 5 volumes and attach to VM - for i in range(self.services["volume"]["max"]): - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.account.name, - domainid=self.account.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume: %s for account: %s" % ( - volume.id, - self.account.account.name - )) - # Check List Volume response for newly created volume - list_volume_response = list_volumes( - self.apiclient, - id=volume.id - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - # Attach volume to VM - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - - # Check all volumes attached to same VM - list_volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - self.assertEqual( - len(list_volume_response), - self.services["volume"]["max"], - "Check number of data volumes attached to VM" - ) - # Create an ISO and attach it to VM - iso = Iso.create( - self.apiclient, - self.services["iso"], - account=self.account.account.name, - domainid=self.account.account.domainid, - ) - self.debug("Created ISO with ID: %s for account: %s" % ( - iso.id, - self.account.account.name - )) - self.cleanup.append(iso) - try: - self.debug("Downloading ISO with ID: %s" % iso.id) - iso.download(self.apiclient) - except Exception as e: - self.fail("Exception while downloading ISO %s: %s"\ - % (iso.id, e)) - - #Attach ISO to virtual machine - self.debug("Attach ISO ID: %s to VM: %s" % ( - iso.id, - self.virtual_machine.id - )) - cmd = attachIso.attachIsoCmd() - cmd.id = iso.id - cmd.virtualmachineid = self.virtual_machine.id - self.apiclient.attachIso(cmd) - - # Verify ISO is attached to VM - vm_response = list_virtual_machines( - self.apiclient, - id=self.virtual_machine.id, - ) - #Verify VM response to check whether VM deployment was successful - self.assertEqual( - isinstance(vm_response, list), - True, - "Check list VM response for valid list" - ) - - self.assertNotEqual( - len(vm_response), - 0, - "Check VMs available in List VMs response" - ) - vm = vm_response[0] - self.assertEqual( - vm.isoid, - iso.id, - "Check ISO is attached to VM or not" - ) - return - - -class TestVolumes(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestVolumes, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostypeid"] - ) - cls.services["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = template.id - cls.services["virtual_machine"]["diskofferingid"] = cls.disk_offering.id - - # Create VMs, VMs etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.account.name - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.account.name, - domainid=cls.account.account.domainid, - serviceofferingid=cls.service_offering.id, - ) - - cls.volume = Volume.create( - cls.api_client, - cls.services["volume"], - zoneid=cls.zone.id, - account=cls.account.account.name, - domainid=cls.account.account.domainid, - diskofferingid=cls.disk_offering.id - ) - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account - ] - - @classmethod - def tearDownClass(cls): - try: - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def tearDown(self): - #Clean up, terminate the created volumes - cleanup_resources(self.apiclient, self.cleanup) - return - - def test_01_attach_volume(self): - """Attach a created Volume to a Running VM - """ - # Validate the following - # 1. Create a data volume. - # 2. List Volumes should not have vmname and virtualmachineid fields in - # response before volume attach (to VM) - # 3. Attch volume to VM. Attach volume should be successful. - # 4. List Volumes should have vmname and virtualmachineid fields in - # response before volume attach (to VM) - - # Check the list volumes response for vmname and virtualmachineid - list_volume_response = list_volumes( - self.apiclient, - id=self.volume.id - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - - volume = list_volume_response[0] - - self.assertEqual( - volume.type, - 'DATADISK', - "Check volume type from list volume response" - ) - - self.assertEqual( - hasattr(volume, 'vmname'), - True, - "Check whether volume has vmname field" - ) - self.assertEqual( - hasattr(volume, 'virtualmachineid'), - True, - "Check whether volume has virtualmachineid field" - ) - - # Attach volume to VM - self.debug("Attach volume: %s to VM: %s" % ( - self.volume.id, - self.virtual_machine.id - )) - self.virtual_machine.attach_volume(self.apiclient, self.volume) - - # Check all volumes attached to same VM - list_volume_response = list_volumes( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - volume = list_volume_response[0] - self.assertEqual( - volume.vmname, - self.virtual_machine.name, - "Check virtual machine name in list volumes response" - ) - self.assertEqual( - volume.virtualmachineid, - self.virtual_machine.id, - "Check VM ID in list Volume response" - ) - return - - def test_02_detach_volume(self): - """Detach a Volume attached to a VM - """ - - # Validate the following - # 1. Data disk should be detached from instance - # 2. Listvolumes should not have vmname and virtualmachineid fields for - # that volume. - - self.debug("Detach volume: %s to VM: %s" % ( - self.volume.id, - self.virtual_machine.id - )) - self.virtual_machine.detach_volume(self.apiclient, self.volume) - - #Sleep to ensure the current state will reflected in other calls - time.sleep(self.services["sleep"]) - - list_volume_response = list_volumes( - self.apiclient, - id=self.volume.id - ) - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volumes response for valid list" - ) - - self.assertNotEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - volume = list_volume_response[0] - self.assertEqual( - volume.virtualmachineid, - None, - "Check if volume state (detached) is reflected" - ) - - self.assertEqual( - volume.vmname, - None, - "Check if volume state (detached) is reflected" - ) - return - - def test_03_delete_detached_volume(self): - """Delete a Volume unattached to an VM - """ - # Validate the following - # 1. volume should be deleted successfully and listVolume should not - # contain the deleted volume details. - - self.debug("Deleting volume: %s" % self.volume.id) - cmd = deleteVolume.deleteVolumeCmd() - cmd.id = self.volume.id - self.apiclient.deleteVolume(cmd) - - #Sleep to ensure the current state will reflected in other calls - time.sleep(self.services["sleep"]) - - list_volume_response = list_volumes( - self.apiclient, - id=self.volume.id, - type='DATADISK' - ) - self.assertEqual( - list_volume_response, - None, - "Check if volume exists in ListVolumes" - ) - return diff --git a/tools/testClient/testcase/__init__.py b/tools/testClient/testcase/__init__.py deleted file mode 100644 index 37f96cecb27..00000000000 --- a/tools/testClient/testcase/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 diff --git a/tools/testClient/testcase/libs/__init__.py b/tools/testClient/testcase/libs/__init__.py deleted file mode 100644 index d65b5e89b69..00000000000 --- a/tools/testClient/testcase/libs/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 \ No newline at end of file diff --git a/tools/testClient/testcase/libs/base.py b/tools/testClient/testcase/libs/base.py deleted file mode 100644 index 638ff8cd577..00000000000 --- a/tools/testClient/testcase/libs/base.py +++ /dev/null @@ -1,1861 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -""" Base class for all Cloudstack resources - -Virtual machine, Volume, Snapshot etc -""" - -from utils import is_server_ssh_ready, random_gen -from cloudstackAPI import * -#Import System modules -import time -import hashlib -import base64 -import types - - -class Domain: - """ Domain Life Cycle """ - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, name=None, networkdomain=None, - parentdomainid=None): - """Creates an domain""" - - cmd = createDomain.createDomainCmd() - - if name: - cmd.name = "-".join([name, random_gen()]) - elif "name" in services: - cmd.name = "-".join([services["name"], random_gen()]) - - if networkdomain: - cmd.networkdomain = networkdomain - elif "networkdomain" in services: - cmd.networkdomain = services["networkdomain"] - - if parentdomainid: - cmd.parentdomainid = parentdomainid - elif "parentdomainid" in services: - cmd.parentdomainid = services["parentdomainid"] - - return Domain(apiclient.createDomain(cmd).__dict__) - - def delete(self, apiclient, cleanup=None): - """Delete an domain""" - cmd = deleteDomain.deleteDomainCmd() - cmd.id = self.id - if cleanup: - cmd.cleanup = cleanup - apiclient.deleteDomain(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists domains""" - cmd = listDomains.listDomainsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDomains(cmd)) - - -class Account: - """ Account Life Cycle """ - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, admin=False, domainid=None): - """Creates an account""" - cmd = createAccount.createAccountCmd() - - #0 - User, 1 - Root Admin, 2 - Domain Admin - cmd.accounttype = 2 if (admin and domainid) else int(admin) - - cmd.email = services["email"] - cmd.firstname = services["firstname"] - cmd.lastname = services["lastname"] - - # Password Encoding - mdf = hashlib.md5() - mdf.update(services["password"]) - cmd.password = mdf.hexdigest() - cmd.username = "-".join([services["username"], random_gen()]) - - if domainid: - cmd.domainid = domainid - account = apiclient.createAccount(cmd) - - return Account(account.__dict__) - - def delete(self, apiclient): - """Delete an account""" - cmd = deleteAccount.deleteAccountCmd() - cmd.id = self.account.id - apiclient.deleteAccount(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists accounts and provides detailed account information for - listed accounts""" - - cmd = listAccounts.listAccountsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listAccounts(cmd)) - - -class User: - """ User Life Cycle """ - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, account, domainid): - cmd = createUser.createUserCmd() - """Creates an user""" - - cmd.account = account - cmd.domainid = domainid - cmd.email = services["email"] - cmd.firstname = services["firstname"] - cmd.lastname = services["lastname"] - - # Password Encoding - mdf = hashlib.md5() - mdf.update(services["password"]) - cmd.password = mdf.hexdigest() - cmd.username = "-".join([services["username"], random_gen()]) - user = apiclient.createUser(cmd) - - return User(user.__dict__) - - def delete(self, apiclient): - """Delete an account""" - cmd = deleteUser.deleteUserCmd() - cmd.id = self.id - apiclient.deleteUser(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists users and provides detailed account information for - listed users""" - - cmd = listUsers.listUsersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listUsers(cmd)) - - -class VirtualMachine: - """Manage virtual machine lifecycle""" - - def __init__(self, items, services): - self.__dict__.update(items) - self.username = services["username"] - self.password = services["password"] - self.ssh_port = services["ssh_port"] - self.ssh_client = None - #extract out the ipaddress - self.ipaddress = self.nic[0].ipaddress - - @classmethod - def create(cls, apiclient, services, templateid=None, accountid=None, - domainid=None, networkids=None, serviceofferingid=None, - securitygroupids=None, projectid=None, mode='basic'): - """Create the instance""" - - cmd = deployVirtualMachine.deployVirtualMachineCmd() - - if serviceofferingid: - cmd.serviceofferingid = serviceofferingid - elif "serviceoffering" in services: - cmd.serviceofferingid = services["serviceoffering"] - - cmd.zoneid = services["zoneid"] - cmd.hypervisor = services["hypervisor"] - - if accountid: - cmd.account = accountid - elif "account" in services: - cmd.account = services["account"] - - if domainid: - cmd.domainid = domainid - elif "domainid" in services: - cmd.domainid = services["domainid"] - - if networkids: - cmd.networkids = networkids - elif "networkids" in services: - cmd.networkids = services["networkids"] - - if templateid: - cmd.templateid = templateid - elif "template" in services: - cmd.templateid = services["template"] - - if "diskoffering" in services: - cmd.diskofferingid = services["diskoffering"] - - if securitygroupids: - cmd.securitygroupids = [str(sg_id) for sg_id in securitygroupids] - - if "userdata" in services: - cmd.userdata = base64.b64encode(services["userdata"]) - - if projectid: - cmd.projectid = projectid - - virtual_machine = apiclient.deployVirtualMachine(cmd) - - # VM should be in Running state after deploy - timeout = 10 - while True: - vm_status = VirtualMachine.list( - apiclient, - id=virtual_machine.id - ) - if isinstance(vm_status, list): - if vm_status[0].state == 'Running': - break - elif timeout == 0: - raise Exception( - "TimeOutException: Failed to start VM (ID: %s)" % - virtual_machine.id) - - time.sleep(10) - timeout = timeout -1 - - if mode.lower() == 'advanced': - public_ip = PublicIPAddress.create( - apiclient, - virtual_machine.account, - virtual_machine.zoneid, - virtual_machine.domainid, - services - ) - nat_rule = NATRule.create( - apiclient, - virtual_machine, - services, - ipaddressid=public_ip.ipaddress.id - ) - virtual_machine.ssh_ip = nat_rule.ipaddress - virtual_machine.public_ip = nat_rule.ipaddress - else: - virtual_machine.ssh_ip = virtual_machine.nic[0].ipaddress - virtual_machine.public_ip = virtual_machine.nic[0].ipaddress - - return VirtualMachine(virtual_machine.__dict__, services) - - def start(self, apiclient): - """Start the instance""" - cmd = startVirtualMachine.startVirtualMachineCmd() - cmd.id = self.id - apiclient.startVirtualMachine(cmd) - - def stop(self, apiclient): - """Stop the instance""" - cmd = stopVirtualMachine.stopVirtualMachineCmd() - cmd.id = self.id - apiclient.stopVirtualMachine(cmd) - - def reboot(self, apiclient): - """Reboot the instance""" - cmd = rebootVirtualMachine.rebootVirtualMachineCmd() - cmd.id = self.id - apiclient.rebootVirtualMachine(cmd) - - def get_ssh_client(self, ipaddress=None, reconnect=False, port=None): - """Get SSH object of VM""" - - # If NAT Rules are not created while VM deployment in Advanced mode - # then, IP address must be passed - if ipaddress != None: - self.ssh_ip = ipaddress - if port: - self.ssh_port = port - - if reconnect: - self.ssh_client = is_server_ssh_ready( - self.ssh_ip, - self.ssh_port, - self.username, - self.password - ) - self.ssh_client = self.ssh_client or is_server_ssh_ready( - self.ssh_ip, - self.ssh_port, - self.username, - self.password - ) - return self.ssh_client - - def delete(self, apiclient): - """Destroy an Instance""" - cmd = destroyVirtualMachine.destroyVirtualMachineCmd() - cmd.id = self.id - apiclient.destroyVirtualMachine(cmd) - - def attach_volume(self, apiclient, volume): - """Attach volume to instance""" - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume.id - cmd.virtualmachineid = self.id - return apiclient.attachVolume(cmd) - - def detach_volume(self, apiclient, volume): - """Detach volume to instance""" - cmd = detachVolume.detachVolumeCmd() - cmd.id = volume.id - return apiclient.detachVolume(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all VMs matching criteria""" - - cmd = listVirtualMachines.listVirtualMachinesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVirtualMachines(cmd)) - - -class Volume: - """Manage Volume Lifecycle - """ - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, zoneid=None, account=None, domainid=None, - diskofferingid=None, projectid=None): - """Create Volume""" - cmd = createVolume.createVolumeCmd() - cmd.name = services["diskname"] - - if diskofferingid: - cmd.diskofferingid = diskofferingid - elif "diskofferingid" in services: - cmd.diskofferingid = services["diskofferingid"] - - if zoneid: - cmd.zoneid = zoneid - elif "zoneid" in services: - cmd.zoneid = services["zoneid"] - - if account: - cmd.account = account - elif "account" in services: - cmd.account = services["account"] - - if domainid: - cmd.domainid = domainid - elif "domainid" in services: - cmd.domainid = services["domainid"] - - if projectid: - cmd.projectid = projectid - return Volume(apiclient.createVolume(cmd).__dict__) - - @classmethod - def create_custom_disk(cls, apiclient, services, account=None, domainid=None): - """Create Volume from Custom disk offering""" - cmd = createVolume.createVolumeCmd() - cmd.name = services["diskname"] - cmd.diskofferingid = services["customdiskofferingid"] - cmd.size = services["customdisksize"] - cmd.zoneid = services["zoneid"] - - if account: - cmd.account = account - else: - cmd.account = services["account"] - - if domainid: - cmd.domainid = domainid - else: - cmd.domainid = services["domainid"] - - return Volume(apiclient.createVolume(cmd).__dict__) - - @classmethod - def create_from_snapshot(cls, apiclient, snapshot_id, services, - account=None, domainid=None): - """Create Volume from snapshot""" - cmd = createVolume.createVolumeCmd() - cmd.name = "-".join([services["diskname"], random_gen()]) - cmd.snapshotid = snapshot_id - cmd.zoneid = services["zoneid"] - cmd.size = services["size"] - if account: - cmd.account = account - else: - cmd.account = services["account"] - if domainid: - cmd.domainid = domainid - else: - cmd.domainid = services["domainid"] - return Volume(apiclient.createVolume(cmd).__dict__) - - def delete(self, apiclient): - """Delete Volume""" - cmd = deleteVolume.deleteVolumeCmd() - cmd.id = self.id - apiclient.deleteVolume(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all volumes matching criteria""" - - cmd = listVolumes.listVolumesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVolumes(cmd)) - - -class Snapshot: - """Manage Snapshot Lifecycle - """ - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, volume_id, account=None, domainid=None, projectid=None): - """Create Snapshot""" - cmd = createSnapshot.createSnapshotCmd() - cmd.volumeid = volume_id - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if projectid: - cmd.projectid = projectid - return Snapshot(apiclient.createSnapshot(cmd).__dict__) - - def delete(self, apiclient): - """Delete Snapshot""" - cmd = deleteSnapshot.deleteSnapshotCmd() - cmd.id = self.id - apiclient.deleteSnapshot(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all snapshots matching criteria""" - - cmd = listSnapshots.listSnapshotsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshots(cmd)) - - -class Template: - """Manage template life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, volumeid=None, - account=None, domainid=None, projectid=None): - """Create template from Volume""" - #Create template from Virtual machine and Volume ID - cmd = createTemplate.createTemplateCmd() - cmd.displaytext = services["displaytext"] - cmd.name = "-".join([services["name"], random_gen()]) - cmd.ostypeid = services["ostypeid"] - - cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False - cmd.ispublic = services["ispublic"] if "ispublic" in services else False - cmd.isextractable = services["isextractable"] if "isextractable" in services else False - cmd.passwordenabled = services["passwordenabled"] if "passwordenabled" in services else False - - if volumeid: - cmd.volumeid = volumeid - - if account: - cmd.account = account - - if domainid: - cmd.domainid = domainid - - if projectid: - cmd.projectid = projectid - return Template(apiclient.createTemplate(cmd).__dict__) - - @classmethod - def register(cls, apiclient, services, zoneid=None, account=None, domainid=None): - """Create template from URL""" - - #Create template from Virtual machine and Volume ID - cmd = registerTemplate.registerTemplateCmd() - cmd.displaytext = services["displaytext"] - cmd.name = "-".join([services["name"], random_gen()]) - cmd.format = services["format"] - cmd.hypervisor = services["hypervisor"] - cmd.ostypeid = services["ostypeid"] - cmd.url = services["url"] - - if zoneid: - cmd.zoneid = zoneid - else: - cmd.zoneid = services["zoneid"] - - cmd.isfeatured = services["isfeatured"] if "isfeatured" in services else False - cmd.ispublic = services["ispublic"] if "ispublic" in services else False - cmd.isextractable = services["isextractable"] if "isextractable" in services else False - - if account: - cmd.account = account - - if domainid: - cmd.domainid = domainid - - # Register Template - template = apiclient.registerTemplate(cmd) - - if isinstance(template, list): - return Template(template[0].__dict__) - - @classmethod - def create_from_snapshot(cls, apiclient, snapshot, services, random_name=True): - """Create Template from snapshot""" - #Create template from Virtual machine and Snapshot ID - cmd = createTemplate.createTemplateCmd() - cmd.displaytext = services["displaytext"] - cmd.name = "-".join([ - services["name"], - random_gen() - ]) if random_name else services["name"] - cmd.ostypeid = services["ostypeid"] - cmd.snapshotid = snapshot.id - return Template(apiclient.createTemplate(cmd).__dict__) - - def delete(self, apiclient): - """Delete Template""" - - cmd = deleteTemplate.deleteTemplateCmd() - cmd.id = self.id - apiclient.deleteTemplate(cmd) - - def download(self, apiclient, timeout=5, interval=60): - """Download Template""" - #Sleep to ensure template is in proper state before download - time.sleep(interval) - - while True: - template_response = Template.list( - apiclient, - id=self.id, - zoneid=self.zoneid, - templatefilter='self' - ) - if isinstance(template_response, list): - - template = template_response[0] - # If template is ready, - # template.status = Download Complete - # Downloading - x% Downloaded - # Error - Any other string - if template.status == 'Download Complete': - break - - elif 'Downloaded' in template.status: - time.sleep(interval) - - elif 'Installing' not in template.status: - raise Exception("ErrorInDownload") - - elif timeout == 0: - break - - else: - time.sleep(interval) - timeout = timeout - 1 - return - - def updatePermissions(self, apiclient, **kwargs): - """Updates the template permissions""" - - cmd = updateTemplatePermissions.updateTemplatePermissionsCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.updateTemplatePermissions(cmd)) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all templates matching criteria""" - - cmd = listTemplates.listTemplatesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listTemplates(cmd)) - - -class Iso: - """Manage ISO life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, account=None, domainid=None, - projectid=None): - """Create an ISO""" - #Create ISO from URL - cmd = registerIso.registerIsoCmd() - cmd.displaytext = services["displaytext"] - cmd.name = services["name"] - cmd.ostypeid = services["ostypeid"] - cmd.url = services["url"] - cmd.zoneid = services["zoneid"] - - if "isextractable" in services: - cmd.isextractable = services["isextractable"] - if "isfeatured" in services: - cmd.isfeatured = services["isfeatured"] - if "ispublic" in services: - cmd.ispublic = services["ispublic"] - - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if projectid: - cmd.projectid = projectid - # Register ISO - iso = apiclient.registerIso(cmd) - - if iso: - return Iso(iso[0].__dict__) - - def delete(self, apiclient): - """Delete an ISO""" - cmd = deleteIso.deleteIsoCmd() - cmd.id = self.id - apiclient.deleteIso(cmd) - return - - def download(self, apiclient, timeout=5, interval=60): - """Download an ISO""" - #Ensuring ISO is successfully downloaded - while True: - time.sleep(interval) - - cmd = listIsos.listIsosCmd() - cmd.id = self.id - iso_response = apiclient.listIsos(cmd) - - if isinstance(iso_response, list): - response = iso_response[0] - # Again initialize timeout to avoid listISO failure - timeout = 5 - - # Check whether download is in progress(for Ex:10% Downloaded) - # or ISO is 'Successfully Installed' - if response.status == 'Successfully Installed': - return - elif 'Downloaded' not in response.status: - raise Exception("ErrorInDownload") - - elif timeout == 0: - raise Exception("TimeoutException") - else: - timeout = timeout - 1 - return - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all available ISO files.""" - - cmd = listIsos.listIsosCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listIsos(cmd)) - - -class PublicIPAddress: - """Manage Public IP Addresses""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, accountid=None, zoneid=None, domainid=None, - services=None, networkid=None, projectid=None): - """Associate Public IP address""" - cmd = associateIpAddress.associateIpAddressCmd() - - if accountid: - cmd.account = accountid - - if zoneid: - cmd.zoneid = zoneid - elif "zoneid" in services: - services["zoneid"] - - if domainid: - cmd.domainid = domainid - elif "domainid" in services: - services["domainid"] - - if networkid: - cmd.networkid = networkid - - if projectid: - cmd.projectid = projectid - return PublicIPAddress(apiclient.associateIpAddress(cmd).__dict__) - - def delete(self, apiclient): - """Dissociate Public IP address""" - cmd = disassociateIpAddress.disassociateIpAddressCmd() - cmd.id = self.ipaddress.id - apiclient.disassociateIpAddress(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Public IPs matching criteria""" - - cmd = listPublicIpAddresses.listPublicIpAddressesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPublicIpAddresses(cmd)) - -class NATRule: - """Manage port forwarding rule""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, virtual_machine, services, ipaddressid=None, - projectid=None): - """Create Port forwarding rule""" - cmd = createPortForwardingRule.createPortForwardingRuleCmd() - - if ipaddressid: - cmd.ipaddressid = ipaddressid - elif "ipaddressid" in services: - cmd.ipaddressid = services["ipaddressid"] - - cmd.privateport = services["privateport"] - cmd.publicport = services["publicport"] - cmd.protocol = services["protocol"] - cmd.virtualmachineid = virtual_machine.id - - if projectid: - cmd.projectid = projectid - - return NATRule(apiclient.createPortForwardingRule(cmd).__dict__) - - def delete(self, apiclient): - """Delete port forwarding""" - cmd = deletePortForwardingRule.deletePortForwardingRuleCmd() - cmd.id = self.id - apiclient.deletePortForwardingRule(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all NAT rules matching criteria""" - - cmd = listPortForwardingRules.listPortForwardingRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPortForwardingRules(cmd)) - - -class StaticNATRule: - """Manage Static NAT rule""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, ipaddressid=None): - """Creates static ip forwarding rule""" - - cmd = createIpForwardingRule.createIpForwardingRuleCmd() - cmd.protocol = services["protocol"] - cmd.startport = services["startport"] - - if "endport" in services: - cmd.endport = services["endport"] - - if "cidrlist" in services: - cmd.cidrlist = services["cidrlist"] - - if ipaddressid: - cmd.ipaddressid = ipaddressid - elif "ipaddressid" in services: - cmd.ipaddressid = services["ipaddressid"] - - return StaticNATRule(apiclient.createIpForwardingRule(cmd).__dict__) - - def delete(self, apiclient): - """Delete IP forwarding rule""" - cmd = deleteIpForwardingRule.deleteIpForwardingRuleCmd() - cmd.id = self.id - apiclient.deleteIpForwardingRule(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all IP forwarding rules matching criteria""" - - cmd = listIpForwardingRules.listIpForwardingRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listIpForwardingRules(cmd)) - - @classmethod - def enable(cls, apiclient, ipaddressid, virtualmachineid): - """Enables Static NAT rule""" - - cmd = enableStaticNat.enableStaticNatCmd() - cmd.ipaddressid = ipaddressid - cmd.virtualmachineid = virtualmachineid - apiclient.enableStaticNat(cmd) - return - - @classmethod - def disable(cls, apiclient, ipaddressid, virtualmachineid): - """Disables Static NAT rule""" - - cmd = disableStaticNat.disableStaticNatCmd() - cmd.ipaddressid = ipaddressid - apiclient.disableStaticNat(cmd) - return - - -class FireWallRule: - """Manage Firewall rule""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, ipaddressid, protocol, cidrlist=None, - startport=None, endport=None, projectid=None): - """Create Firewall Rule""" - cmd = createFirewallRule.createFirewallRuleCmd() - cmd.ipaddressid = ipaddressid - cmd.protocol = protocol - if cidrlist: - cmd.cidrlist = cidrlist - if startport: - cmd.startport = startport - if endport: - cmd.endport = endport - - if projectid: - cmd.projectid = projectid - - return FireWallRule(apiclient.createFirewallRule(cmd).__dict__) - - def delete(self, apiclient): - """Delete Firewall rule""" - cmd = deleteFirewallRule.deleteFirewallRuleCmd() - cmd.id = self.id - apiclient.deleteFirewallRule(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Firewall Rules matching criteria""" - - cmd = listFirewallRules.listFirewallRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listFirewallRules(cmd)) - - -class ServiceOffering: - """Manage service offerings cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, domainid=None, **kwargs): - """Create Service offering""" - cmd = createServiceOffering.createServiceOfferingCmd() - cmd.cpunumber = services["cpunumber"] - cmd.cpuspeed = services["cpuspeed"] - cmd.displaytext = services["displaytext"] - cmd.memory = services["memory"] - cmd.name = services["name"] - - # Service Offering private to that domain - if domainid: - cmd.domainid = domainid - - [setattr(cmd, k, v) for k, v in kwargs.items()] - return ServiceOffering(apiclient.createServiceOffering(cmd).__dict__) - - def delete(self, apiclient): - """Delete Service offering""" - cmd = deleteServiceOffering.deleteServiceOfferingCmd() - cmd.id = self.id - apiclient.deleteServiceOffering(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all available service offerings.""" - - cmd = listServiceOfferings.listServiceOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listServiceOfferings(cmd)) - -class DiskOffering: - """Manage disk offerings cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, custom=False, domainid=None): - """Create Disk offering""" - cmd = createDiskOffering.createDiskOfferingCmd() - cmd.displaytext = services["displaytext"] - cmd.name = services["name"] - if custom: - cmd.customized = True - else: - cmd.disksize = services["disksize"] - - if domainid: - cmd.domainid = domainid - - return DiskOffering(apiclient.createDiskOffering(cmd).__dict__) - - def delete(self, apiclient): - """Delete Disk offering""" - cmd = deleteDiskOffering.deleteDiskOfferingCmd() - cmd.id = self.id - apiclient.deleteDiskOffering(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all available disk offerings.""" - - cmd = listDiskOfferings.listDiskOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDiskOfferings(cmd)) - - -class NetworkOffering: - """Manage network offerings cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, **kwargs): - """Create network offering""" - - cmd = createNetworkOffering.createNetworkOfferingCmd() - cmd.displaytext = "-".join([services["displaytext"], random_gen()]) - cmd.name = "-".join([services["name"], random_gen()]) - cmd.guestiptype = services["guestiptype"] - cmd.supportedservices = services["supportedservices"] - cmd.traffictype = services["traffictype"] - - cmd.serviceProviderList = [] - for service, provider in services["serviceProviderList"].items(): - cmd.serviceProviderList.append({ - 'service' : service, - 'provider': provider - }) - - [setattr(cmd, k, v) for k, v in kwargs.items()] - - return NetworkOffering(apiclient.createNetworkOffering(cmd).__dict__) - - def delete(self, apiclient): - """Delete network offering""" - cmd = deleteNetworkOffering.deleteNetworkOfferingCmd() - cmd.id = self.id - apiclient.deleteNetworkOffering(cmd) - return - - def update(self, apiclient, **kwargs): - """Lists all available network offerings.""" - - cmd = updateNetworkOffering.updateNetworkOfferingCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.updateNetworkOffering(cmd)) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all available network offerings.""" - - cmd = listNetworkOfferings.listNetworkOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworkOfferings(cmd)) - - -class SnapshotPolicy: - """Manage snapshot policies""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, volumeid, services): - """Create Snapshot policy""" - cmd = createSnapshotPolicy.createSnapshotPolicyCmd() - cmd.intervaltype = services["intervaltype"] - cmd.maxsnaps = services["maxsnaps"] - cmd.schedule = services["schedule"] - cmd.timezone = services["timezone"] - cmd.volumeid = volumeid - return SnapshotPolicy(apiclient.createSnapshotPolicy(cmd).__dict__) - - def delete(self, apiclient): - """Delete Snapshot policy""" - cmd = deleteSnapshotPolicies.deleteSnapshotPoliciesCmd() - cmd.id = self.id - apiclient.deleteSnapshotPolicies(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists snapshot policies.""" - - cmd = listSnapshotPolicies.listSnapshotPoliciesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshotPolicies(cmd)) - - -class LoadBalancerRule: - """Manage Load Balancer rule""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, ipaddressid, accountid=None, - networkid=None, projectid=None): - """Create Load balancing Rule""" - - cmd = createLoadBalancerRule.createLoadBalancerRuleCmd() - cmd.publicipid = ipaddressid or services["ipaddressid"] - - if accountid: - cmd.account = accountid - elif "account" in services: - cmd.account = services["account"] - - cmd.name = services["name"] - cmd.algorithm = services["alg"] - cmd.privateport = services["privateport"] - cmd.publicport = services["publicport"] - - if "openfirewall" in services: - cmd.openfirewall = services["openfirewall"] - - if projectid: - cmd.projectid = projectid - - if networkid: - cmd.networkid = networkid - return LoadBalancerRule(apiclient.createLoadBalancerRule(cmd).__dict__) - - def delete(self, apiclient): - """Delete load balancing rule""" - cmd = deleteLoadBalancerRule.deleteLoadBalancerRuleCmd() - cmd.id = self.id - apiclient.deleteLoadBalancerRule(cmd) - return - - def assign(self, apiclient, vms): - """Assign virtual machines to load balancing rule""" - cmd = assignToLoadBalancerRule.assignToLoadBalancerRuleCmd() - cmd.id = self.id - cmd.virtualmachineids = [str(vm.id) for vm in vms] - apiclient.assignToLoadBalancerRule(cmd) - return - - def remove(self, apiclient, vms): - """Remove virtual machines from load balancing rule""" - cmd = removeFromLoadBalancerRule.removeFromLoadBalancerRuleCmd() - cmd.id = self.id - cmd.virtualmachineids = [str(vm.id) for vm in vms] - apiclient.removeFromLoadBalancerRule(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Load balancing rules matching criteria""" - - cmd = listLoadBalancerRules.listLoadBalancerRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listLoadBalancerRules(cmd)) - - -class Cluster: - """Manage Cluster life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, zoneid=None, podid=None): - """Create Cluster""" - cmd = addCluster.addClusterCmd() - cmd.clustertype = services["clustertype"] - cmd.hypervisor = services["hypervisor"] - - if zoneid: - cmd.zoneid = zoneid - else: - cmd.zoneid = services["zoneid"] - - if podid: - cmd.podid = podid - else: - cmd.podid = services["podid"] - - if "username" in services: - cmd.username = services["username"] - if "password" in services: - cmd.password = services["password"] - if "url" in services: - cmd.url = services["url"] - if "clustername" in services: - cmd.clustername = services["clustername"] - - return Cluster(apiclient.addCluster(cmd)[0].__dict__) - - def delete(self, apiclient): - """Delete Cluster""" - cmd = deleteCluster.deleteClusterCmd() - cmd.id = self.id - apiclient.deleteCluster(cmd) - return - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Clusters matching criteria""" - - cmd = listClusters.listClustersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listClusters(cmd)) - - -class Host: - """Manage Host life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, cluster, services, zoneid=None, podid=None): - """Create Host in cluster""" - - cmd = addHost.addHostCmd() - cmd.hypervisor = services["hypervisor"] - cmd.url = services["url"] - cmd.clusterid = cluster.id - - if zoneid: - cmd.zoneid = zoneid - else: - cmd.zoneid = services["zoneid"] - - if podid: - cmd.podid = podid - else: - cmd.podid = services["podid"] - - if "clustertype" in services: - cmd.clustertype = services["clustertype"] - if "username" in services: - cmd.username = services["username"] - if "password" in services: - cmd.password = services["password"] - - # Add host - host = apiclient.addHost(cmd) - - if isinstance(host, list): - return Host(host[0].__dict__) - - def delete(self, apiclient): - """Delete Host""" - # Host must be in maintenance mode before deletion - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = self.id - apiclient.prepareHostForMaintenance(cmd) - time.sleep(30) - - cmd = deleteHost.deleteHostCmd() - cmd.id = self.id - apiclient.deleteHost(cmd) - return - - def enableMaintenance(self, apiclient): - """enables maintainance mode Host""" - - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = self.id - return apiclient.prepareHostForMaintenance(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Hosts matching criteria""" - - cmd = listHosts.listHostsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listHosts(cmd)) - - -class StoragePool: - """Manage Storage pools (Primary Storage)""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, clusterid=None, zoneid=None, podid=None): - """Create Storage pool (Primary Storage)""" - - cmd = createStoragePool.createStoragePoolCmd() - cmd.name = services["name"] - - if podid: - cmd.podid = podid - else: - cmd.podid = services["podid"] - - cmd.url = services["url"] - if clusterid: - cmd.clusterid = clusterid - elif "clusterid" in services: - cmd.clusterid = services["clusterid"] - - if zoneid: - cmd.zoneid = zoneid - else: - cmd.zoneid = services["zoneid"] - - return StoragePool(apiclient.createStoragePool(cmd).__dict__) - - def delete(self, apiclient): - """Delete Storage pool (Primary Storage)""" - - # Storage pool must be in maintenance mode before deletion - cmd = enableStorageMaintenance.enableStorageMaintenanceCmd() - cmd.id = self.id - apiclient.enableStorageMaintenance(cmd) - time.sleep(30) - cmd = deleteStoragePool.deleteStoragePoolCmd() - cmd.id = self.id - apiclient.deleteStoragePool(cmd) - return - - def enableMaintenance(self, apiclient): - """enables maintainance mode Storage pool""" - - cmd = enableStorageMaintenance.enableStorageMaintenanceCmd() - cmd.id = self.id - return apiclient.enableStorageMaintenance(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all storage pools matching criteria""" - - cmd = listStoragePools.listStoragePoolsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listStoragePools(cmd)) - - -class Network: - """Manage Network pools""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, accountid=None, domainid=None, - networkofferingid=None, projectid=None, zoneid=None): - """Create Network for account""" - cmd = createNetwork.createNetworkCmd() - cmd.name = services["name"] - cmd.displaytext = services["displaytext"] - - if networkofferingid: - cmd.networkofferingid = networkofferingid - elif "networkoffering" in services: - cmd.networkofferingid = services["networkoffering"] - - if zoneid: - cmd.zoneid = zoneid - elif "zoneid" in services: - cmd.zoneid = services["zoneid"] - - if "gateway" in services: - cmd.gateway = services["gateway"] - if "netmask" in services: - cmd.netmask = services["netmask"] - if "startip" in services: - cmd.startip = services["startip"] - if "endip" in services: - cmd.endip = services["endip"] - if "vlan" in services: - cmd.vlan = services["vlan"] - if "acltype" in services: - cmd.acltype = services["acltype"] - - if accountid: - cmd.account = accountid - if domainid: - cmd.domainid = domainid - if projectid: - cmd.projectid = projectid - - return Network(apiclient.createNetwork(cmd).__dict__) - - def delete(self, apiclient): - """Delete Account""" - - cmd = deleteNetwork.deleteNetworkCmd() - cmd.id = self.id - apiclient.deleteNetwork(cmd) - - def update(self, apiclient, **kwargs): - """Updates network with parameters passed""" - - cmd = updateNetwork.updateNetworkCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.updateNetwork(cmd)) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Networks matching criteria""" - - cmd = listNetworks.listNetworksCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworks(cmd)) - - -class Vpn: - """Manage VPN life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, publicipid, account=None, domainid=None, - projectid=None): - """Create VPN for Public IP address""" - cmd = createRemoteAccessVpn.createRemoteAccessVpnCmd() - cmd.publicipid = publicipid - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if projectid: - cmd.projectid = projectid - return Vpn(apiclient.createRemoteAccessVpn(cmd).__dict__) - - def delete(self, apiclient): - """Delete remote VPN access""" - - cmd = deleteRemoteAccessVpn.deleteRemoteAccessVpnCmd() - cmd.publicipid = self.publicipid - apiclient.deleteRemoteAccessVpn(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all VPN matching criteria""" - - cmd = listRemoteAccessVpns.listRemoteAccessVpnsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listRemoteAccessVpns(cmd)) - - -class VpnUser: - """Manage VPN user""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, username, password, account=None, domainid=None, - projectid=None): - """Create VPN user""" - cmd = addVpnUser.addVpnUserCmd() - cmd.username = username - cmd.password = password - - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if projectid: - cmd.projectid = projectid - return VpnUser(apiclient.addVpnUser(cmd).__dict__) - - def delete(self, apiclient): - """Remove VPN user""" - - cmd = removeVpnUser.removeVpnUserCmd() - cmd.username = self.username - cmd.account = self.account - cmd.domainid = self.domainid - apiclient.removeVpnUser(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """List all VPN Users matching criteria""" - - cmd = listVpnUsers.listVpnUsersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVpnUsers(cmd)) - - -class Zone: - """Manage Zone""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, domainid=None): - """Create zone""" - cmd = createZone.createZoneCmd() - cmd.dns1 = services["dns1"] - cmd.internaldns1 = services["internaldns1"] - cmd.name = services["name"] - cmd.networktype = services["networktype"] - - if "dns2" in services: - cmd.dns2 = services["dns2"] - if "internaldns2" in services: - cmd.internaldns2 = services["internaldns2"] - if domainid: - cmd.domainid = domainid - - return Zone(apiclient.createZone(cmd).__dict__) - - def delete(self, apiclient): - """Delete Zone""" - - cmd = deleteZone.deleteZoneCmd() - cmd.id = self.id - apiclient.deleteZone(cmd) - - def update(self, apiclient, **kwargs): - """Update the zone""" - - cmd = updateZone.updateZoneCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.updateZone(cmd) - - - @classmethod - def list(cls, apiclient, **kwargs): - """List all Zones matching criteria""" - - cmd = listZones.listZonesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listZones(cmd)) - - -class Pod: - """Manage Pod""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services): - """Create Pod""" - cmd = createPod.createPodCmd() - cmd.gateway = services["gateway"] - cmd.netmask = services["netmask"] - cmd.name = services["name"] - cmd.startip = services["startip"] - cmd.endip = services["endip"] - cmd.zoneid = services["zoneid"] - - return Pod(apiclient.createPod(cmd).__dict__) - - def delete(self, apiclient): - """Delete Pod""" - - cmd = deletePod.deletePodCmd() - cmd.id = self.id - apiclient.deletePod(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - "Returns a default pod for specified zone" - - cmd = listPods.listPodsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.listPods(cmd) - - -class PublicIpRange: - """Manage VlanIpRange""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services): - """Create VlanIpRange""" - - cmd = createVlanIpRange.createVlanIpRangeCmd() - cmd.gateway = services["gateway"] - cmd.netmask = services["netmask"] - cmd.forvirtualnetwork = services["forvirtualnetwork"] - cmd.startip = services["startip"] - cmd.endip = services["endip"] - cmd.zoneid = services["zoneid"] - cmd.podid = services["podid"] - cmd.vlan = services["vlan"] - - return PublicIpRange(apiclient.createVlanIpRange(cmd).__dict__) - - def delete(self, apiclient): - """Delete VlanIpRange""" - - cmd = deleteVlanIpRange.deleteVlanIpRangeCmd() - cmd.id = self.id - apiclient.deleteVlanIpRange(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all VLAN IP ranges.""" - - cmd = listVlanIpRanges.listVlanIpRangesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVlanIpRanges(cmd)) - - -class SecondaryStorage: - """Manage Secondary storage""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services): - """Create Secondary Storage""" - cmd = addSecondaryStorage.addSecondaryStorageCmd() - - cmd.url = services["url"] - if "zoneid" in services: - cmd.zoneid = services["zoneid"] - return SecondaryStorage(apiclient.addSecondaryStorage(cmd).__dict__) - - def delete(self, apiclient): - """Delete Secondary Storage""" - - cmd = deleteHost.deleteHostCmd() - cmd.id = self.id - apiclient.deleteHost(cmd) - - -class PhysicalNetwork: - """Manage physical network storage""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, zoneid, domainid=None): - """Create physical network""" - cmd = createPhysicalNetwork.createPhysicalNetworkCmd() - - cmd.name = services["name"] - cmd.zoneid = zoneid - if domainid: - cmd.domainid = domainid - return PhysicalNetwork(apiclient.createPhysicalNetwork(cmd).__dict__) - - def delete(self, apiclient): - """Delete Physical Network""" - - cmd = deletePhysicalNetwork.deletePhysicalNetworkCmd() - cmd.id = self.id - apiclient.deletePhysicalNetwork(cmd) - - def update(self, apiclient, **kwargs): - """Update Physical network state""" - - cmd = updatePhysicalNetwork.updatePhysicalNetworkCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.updatePhysicalNetwork(cmd) - - def addTrafficType(self, apiclient, type): - """Add Traffic type to Physical network""" - - cmd = addTrafficType.addTrafficTypeCmd() - cmd.physicalnetworkid = self.id - cmd.traffictype = type - return apiclient.addTrafficType(cmd) - -class SecurityGroup: - """Manage Security Groups""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, account=None, domainid=None, - description=None, projectid=None): - """Create security group""" - cmd = createSecurityGroup.createSecurityGroupCmd() - - cmd.name = services["name"] - if account: - cmd.account = account - if domainid: - cmd.domainid=domainid - if description: - cmd.description=description - if projectid: - cmd.projectid = projectid - - return SecurityGroup(apiclient.createSecurityGroup(cmd).__dict__) - - def delete(self, apiclient): - """Delete Security Group""" - - cmd = deleteSecurityGroup.deleteSecurityGroupCmd() - cmd.id = self.id - apiclient.deleteSecurityGroup(cmd) - - def authorize(self, apiclient, services, - account=None, domainid=None, projectid=None): - """Authorize Ingress Rule""" - - cmd=authorizeSecurityGroupIngress.authorizeSecurityGroupIngressCmd() - - if domainid: - cmd.domainid = domainid - if account: - cmd.account = account - - if projectid: - cmd.projectid = projectid - cmd.securitygroupid=self.id - cmd.protocol=services["protocol"] - - if services["protocol"] == 'ICMP': - cmd.icmptype = -1 - cmd.icmpcode = -1 - else: - cmd.startport = services["startport"] - cmd.endport = services["endport"] - - cmd.cidrlist = services["cidrlist"] - return (apiclient.authorizeSecurityGroupIngress(cmd).__dict__) - - def revoke(self, apiclient, id): - """Revoke ingress rule""" - - cmd=revokeSecurityGroupIngress.revokeSecurityGroupIngressCmd() - cmd.id=id - return apiclient.revokeSecurityGroupIngress(cmd) - - def authorizeEgress(self, apiclient, services, account=None, domainid=None, - projectid=None, user_secgrp_list = {}): - """Authorize Egress Rule""" - - cmd=authorizeSecurityGroupEgress.authorizeSecurityGroupEgressCmd() - - if domainid: - cmd.domainid = domainid - if account: - cmd.account = account - - if projectid: - cmd.projectid = projectid - cmd.securitygroupid=self.id - cmd.protocol=services["protocol"] - - if services["protocol"] == 'ICMP': - cmd.icmptype = -1 - cmd.icmpcode = -1 - else: - cmd.startport = services["startport"] - cmd.endport = services["endport"] - - cmd.cidrlist = services["cidrlist"] - - cmd.usersecuritygrouplist = [] - for account, group in user_secgrp_list.items(): - cmd.usersecuritygrouplist.append({ - 'account' : account, - 'group': group - }) - - return (apiclient.authorizeSecurityGroupEgress(cmd).__dict__) - - def revokeEgress(self, apiclient, id): - """Revoke Egress rule""" - - cmd=revokeSecurityGroupEgress.revokeSecurityGroupEgressCmd() - cmd.id=id - return apiclient.revokeSecurityGroupEgress(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all security groups.""" - - cmd = listSecurityGroups.listSecurityGroupsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSecurityGroups(cmd)) - -class Project: - """Manage Project life cycle""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def create(cls, apiclient, services, account=None, domainid=None): - """Create project""" - - cmd = createProject.createProjectCmd() - cmd.displaytext = services["displaytext"] - cmd.name = "-".join([services["name"], random_gen()]) - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - - return Project(apiclient.createProject(cmd).__dict__) - - def delete(self, apiclient): - """Delete Project""" - - cmd = deleteProject.deleteProjectCmd() - cmd.id = self.id - apiclient.deleteProject(cmd) - - def update(self, apiclient, **kwargs): - """Updates the project""" - - cmd = updateProject.updateProjectCmd() - cmd.id = self.id - [setattr(cmd, k, v) for k, v in kwargs.items()] - return apiclient.updateProject(cmd) - - def activate(self, apiclient): - """Activates the suspended project""" - - cmd = activateProject.activateProjectCmd() - cmd.id = self.id - return apiclient.activateProject(cmd) - - def suspend(self, apiclient): - """Suspend the active project""" - - cmd = suspendProject.suspendProjectCmd() - cmd.id = self.id - return apiclient.suspendProject(cmd) - - def addAccount(self, apiclient, account=None, email=None): - """Add account to project""" - - cmd = addAccountToProject.addAccountToProjectCmd() - cmd.projectid = self.id - if account: - cmd.account = account - if email: - cmd.email = email - return apiclient.addAccountToProject(cmd) - - def deleteAccount(self, apiclient, account): - """Delete account from project""" - - cmd = deleteAccountFromProject.deleteAccountFromProjectCmd() - cmd.projectid = self.id - cmd.account = account - return apiclient.deleteAccountFromProject(cmd) - - @classmethod - def listAccounts(cls, apiclient, **kwargs): - """Lists all accounts associated with projects.""" - - cmd = listProjectAccounts.listProjectAccountsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listProjectAccounts(cmd)) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists all projects.""" - - cmd = listProjects.listProjectsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listProjects(cmd)) - -class ProjectInvitation: - """Manage project invitations""" - - def __init__(self, items): - self.__dict__.update(items) - - @classmethod - def update(cls, apiclient, projectid, accept, account=None, token=None): - """Updates the project invitation for that account""" - - cmd = updateProjectInvitation.updateProjectInvitationCmd() - cmd.projectid = projectid - cmd.accept = accept - if account: - cmd.account = account - if token: - cmd.token = token - - return (apiclient.updateProjectInvitation(cmd).__dict__) - - def delete(self, apiclient, id): - """Deletes the project invitation""" - - cmd = deleteProjectInvitation.deleteProjectInvitationCmd() - cmd.id = id - return apiclient.deleteProjectInvitation(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists project invitations""" - - cmd = listProjectInvitations.listProjectInvitationsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listProjectInvitations(cmd)) - - -class Configurations: - """Manage Configuration""" - - @classmethod - def update(cls, apiclient, name, value=None): - """Updates the specified configuration""" - - cmd = updateConfiguration.updateConfigurationCmd() - cmd.name = name - cmd.value = value - apiclient.updateConfiguration(cmd) - - @classmethod - def list(cls, apiclient, **kwargs): - """Lists configurations""" - - cmd = listConfigurations.listConfigurationsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listConfigurations(cmd)) diff --git a/tools/testClient/testcase/libs/common.py b/tools/testClient/testcase/libs/common.py deleted file mode 100644 index 23da3122cf0..00000000000 --- a/tools/testClient/testcase/libs/common.py +++ /dev/null @@ -1,471 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -"""Common functions -""" - -#Import Local Modules -from cloudstackTestCase import * -from cloudstackAPI import * -import remoteSSHClient -from utils import * -from base import * - -#Import System modules -import time - -def get_domain(apiclient, services=None): - "Returns a default domain" - - cmd = listDomains.listDomainsCmd() - if services: - if "domainid" in services: - cmd.id = services["domainid"] - - domains = apiclient.listDomains(cmd) - - if isinstance(domains, list): - return domains[0] - else: - raise Exception("Failed to find specified domain.") - -def get_zone(apiclient, services=None): - "Returns a default zone" - - cmd = listZones.listZonesCmd() - if services: - if "zoneid" in services: - cmd.id = services["zoneid"] - - zones = apiclient.listZones(cmd) - - if isinstance(zones, list): - return zones[0] - else: - raise Exception("Failed to find specified zone.") - -def get_pod(apiclient, zoneid, services=None): - "Returns a default pod for specified zone" - - cmd = listPods.listPodsCmd() - cmd.zoneid = zoneid - - if services: - if "podid" in services: - cmd.id = services["podid"] - - pods = apiclient.listPods(cmd) - - if isinstance(pods, list): - return pods[0] - else: - raise Exception("Exception: Failed to find specified pod.") - -def get_template(apiclient, zoneid, ostypeid=12, services=None): - "Returns a template" - - cmd = listTemplates.listTemplatesCmd() - cmd.templatefilter = 'featured' - cmd.zoneid = zoneid - - if services: - if "template" in services: - cmd.id = services["template"] - - list_templates = apiclient.listTemplates(cmd) - - for template in list_templates: - if template.ostypeid == ostypeid: - return template - - raise Exception("Exception: Failed to find template with OSTypeID: %s" % - ostypeid) - return - -def download_systemplates_sec_storage(server, services): - """Download System templates on sec storage""" - - try: - # Login to management server - ssh = remoteSSHClient.remoteSSHClient( - server["ipaddress"], - server["port"], - server["username"], - server["password"] - ) - except Exception as e: - raise Exception("SSH access failted for server with IP address: %s" % - server["ipaddess"]) - # Mount Secondary Storage on Management Server - cmds = [ - "mkdir -p %s" % services["mnt_dir"], - "mount -t nfs %s:/%s %s" % ( - services["sec_storage"], - services["path"], - services["mnt_dir"] - ), - "%s -m %s -u %s -h %s -F" % ( - services["command"], - services["mnt_dir"], - services["download_url"], - services["hypervisor"] - ) - ] - for c in cmds: - result = ssh.execute(c) - - res = str(result) - - # Unmount the Secondary storage - ssh.execute("umount %s" % (services["mnt_dir"])) - - if res.count("Successfully installed system VM template") == 1: - return - else: - raise Exception("Failed to download System Templates on Sec Storage") - return - -def wait_for_ssvms(apiclient, zoneid, podid, interval=60): - """After setup wait for SSVMs to come Up""" - - time.sleep(interval) - timeout = 40 - while True: - list_ssvm_response = list_ssvms( - apiclient, - systemvmtype='secondarystoragevm', - zoneid=zoneid, - podid=podid - ) - ssvm = list_ssvm_response[0] - if ssvm.state != 'Running': - # Sleep to ensure SSVMs are Up and Running - time.sleep(interval) - timeout = timeout - 1 - elif ssvm.state == 'Running': - break - elif timeout == 0: - raise Exception("SSVM failed to come up") - break - - timeout = 40 - while True: - list_ssvm_response = list_ssvms( - apiclient, - systemvmtype='consoleproxy', - zoneid=zoneid, - podid=podid - ) - cpvm = list_ssvm_response[0] - if cpvm.state != 'Running': - # Sleep to ensure SSVMs are Up and Running - time.sleep(interval) - timeout = timeout - 1 - elif cpvm.state == 'Running': - break - elif timeout == 0: - raise Exception("CPVM failed to come up") - break - return - -def download_builtin_templates(apiclient, zoneid, hypervisor, host, linklocalip, interval=60): - """After setup wait till builtin templates are downloaded""" - - # Change IPTABLES Rules - result = get_process_status( - host["ipaddress"], - host["port"], - host["username"], - host["password"], - linklocalip, - "iptables -P INPUT ACCEPT" - ) - time.sleep(interval) - # Find the BUILTIN Templates for given Zone, Hypervisor - list_template_response = list_templates( - apiclient, - hypervisor=hypervisor, - zoneid=zoneid, - templatefilter='self' - ) - - if not isinstance(list_template_response, list): - raise Exception("Failed to download BUILTIN templates") - - # Ensure all BUILTIN templates are downloaded - templateid = None - for template in list_template_response: - if template.templatetype == "BUILTIN": - templateid = template.id - - # Sleep to ensure that template is in downloading state after adding - # Sec storage - time.sleep(interval) - while True: - template_response = list_templates( - apiclient, - id=templateid, - zoneid=zoneid, - templatefilter='self' - ) - template = template_response[0] - # If template is ready, - # template.status = Download Complete - # Downloading - x% Downloaded - # Error - Any other string - if template.status == 'Download Complete': - break - - elif 'Downloaded' in template.status: - time.sleep(interval) - - elif 'Installing' not in template.status: - raise Exception("ErrorInDownload") - - return - -def update_resource_limit(apiclient, resourcetype, account=None, domainid=None, - max=None, projectid=None): - """Updates the resource limit to 'max' for given account""" - - cmd = updateResourceLimit.updateResourceLimitCmd() - cmd.resourcetype = resourcetype - if account: - cmd.account = account - if domainid: - cmd.domainid = domainid - if max: - cmd.max = max - if projectid: - cmd.projectid = projectid - apiclient.updateResourceLimit(cmd) - return - -def list_routers(apiclient, **kwargs): - """List all Routers matching criteria""" - - cmd = listRouters.listRoutersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listRouters(cmd)) - -def list_zones(apiclient, **kwargs): - """List all Zones matching criteria""" - - cmd = listZones.listZonesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listZones(cmd)) - -def list_networks(apiclient, **kwargs): - """List all Networks matching criteria""" - - cmd = listNetworks.listNetworksCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworks(cmd)) - -def list_clusters(apiclient, **kwargs): - """List all Clusters matching criteria""" - - cmd = listClusters.listClustersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listClusters(cmd)) - -def list_ssvms(apiclient, **kwargs): - """List all SSVMs matching criteria""" - - cmd = listSystemVms.listSystemVmsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSystemVms(cmd)) - -def list_storage_pools(apiclient, **kwargs): - """List all storage pools matching criteria""" - - cmd = listStoragePools.listStoragePoolsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listStoragePools(cmd)) - -def list_virtual_machines(apiclient, **kwargs): - """List all VMs matching criteria""" - - cmd = listVirtualMachines.listVirtualMachinesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVirtualMachines(cmd)) - -def list_hosts(apiclient, **kwargs): - """List all Hosts matching criteria""" - - cmd = listHosts.listHostsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listHosts(cmd)) - -def list_configurations(apiclient, **kwargs): - """List configuration with specified name""" - - cmd = listConfigurations.listConfigurationsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listConfigurations(cmd)) - -def list_publicIP(apiclient, **kwargs): - """List all Public IPs matching criteria""" - - cmd = listPublicIpAddresses.listPublicIpAddressesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPublicIpAddresses(cmd)) - -def list_nat_rules(apiclient, **kwargs): - """List all NAT rules matching criteria""" - - cmd = listPortForwardingRules.listPortForwardingRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listPortForwardingRules(cmd)) - -def list_lb_rules(apiclient, **kwargs): - """List all Load balancing rules matching criteria""" - - cmd = listLoadBalancerRules.listLoadBalancerRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listLoadBalancerRules(cmd)) - -def list_lb_instances(apiclient, **kwargs): - """List all Load balancing instances matching criteria""" - - cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listLoadBalancerRuleInstances(cmd)) - -def list_firewall_rules(apiclient, **kwargs): - """List all Firewall Rules matching criteria""" - - cmd = listFirewallRules.listFirewallRulesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listFirewallRules(cmd)) - -def list_volumes(apiclient, **kwargs): - """List all volumes matching criteria""" - - cmd = listVolumes.listVolumesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVolumes(cmd)) - -def list_isos(apiclient, **kwargs): - """Lists all available ISO files.""" - - cmd = listIsos.listIsosCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listIsos(cmd)) - -def list_snapshots(apiclient, **kwargs): - """List all snapshots matching criteria""" - - cmd = listSnapshots.listSnapshotsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshots(cmd)) - -def list_templates(apiclient, **kwargs): - """List all templates matching criteria""" - - cmd = listTemplates.listTemplatesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listTemplates(cmd)) - -def list_domains(apiclient, **kwargs): - """Lists domains""" - - cmd = listDomains.listDomainsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDomains(cmd)) - -def list_accounts(apiclient, **kwargs): - """Lists accounts and provides detailed account information for - listed accounts""" - - cmd = listAccounts.listAccountsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listAccounts(cmd)) - -def list_users(apiclient, **kwargs): - """Lists users and provides detailed account information for - listed users""" - - cmd = listUsers.listUsersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listUsers(cmd)) - -def list_snapshot_policy(apiclient, **kwargs): - """Lists snapshot policies.""" - - cmd = listSnapshotPolicies.listSnapshotPoliciesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listSnapshotPolicies(cmd)) - -def list_events(apiclient, **kwargs): - """Lists events""" - - cmd = listEvents.listEventsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listEvents(cmd)) - -def list_disk_offering(apiclient, **kwargs): - """Lists all available disk offerings.""" - - cmd = listDiskOfferings.listDiskOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listDiskOfferings(cmd)) - -def list_service_offering(apiclient, **kwargs): - """Lists all available service offerings.""" - - cmd = listServiceOfferings.listServiceOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listServiceOfferings(cmd)) - -def list_vlan_ipranges(apiclient, **kwargs): - """Lists all VLAN IP ranges.""" - - cmd = listVlanIpRanges.listVlanIpRangesCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVlanIpRanges(cmd)) - -def list_usage_records(apiclient, **kwargs): - """Lists usage records for accounts""" - - cmd = listUsageRecords.listUsageRecordsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listUsageRecords(cmd)) - -def list_nw_service_prividers(apiclient, **kwargs): - """Lists Network service providers""" - - cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworkServiceProviders(cmd)) - -def list_virtual_router_elements(apiclient, **kwargs): - """Lists Virtual Router elements""" - - cmd = listVirtualRouterElements.listVirtualRouterElementsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listVirtualRouterElements(cmd)) - -def list_network_offerings(apiclient, **kwargs): - """Lists network offerings""" - - cmd = listNetworkOfferings.listNetworkOfferingsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listNetworkOfferings(cmd)) - -def list_resource_limits(apiclient, **kwargs): - """Lists resource limits""" - - cmd = listResourceLimits.listResourceLimitsCmd() - [setattr(cmd, k, v) for k, v in kwargs.items()] - return(apiclient.listResourceLimits(cmd)) \ No newline at end of file diff --git a/tools/testClient/testcase/libs/utils.py b/tools/testClient/testcase/libs/utils.py deleted file mode 100644 index 2a33450f822..00000000000 --- a/tools/testClient/testcase/libs/utils.py +++ /dev/null @@ -1,175 +0,0 @@ -# -*- encoding: utf-8 -*- -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -"""Utilities functions -""" - -import time -import remoteSSHClient -from cloudstackAPI import * -import cloudstackConnection -#from cloudstackConnection import cloudConnection -import configGenerator -import logging -import string -import random -import imaplib -import email -import datetime - -def restart_mgmt_server(server): - """Restarts the management server""" - - try: - # Get the SSH client - ssh = is_server_ssh_ready( - server["ipaddress"], - server["port"], - server["username"], - server["password"], - ) - result = ssh.execute("/etc/init.d/cloud-management restart") - res = str(result) - # Server Stop - OK - # Server Start - OK - if res.count("OK") != 2: - raise ("ErrorInReboot!") - except Exception as e: - raise e - return - -def fetch_latest_mail(services, from_mail): - """Fetch mail""" - - # Login to mail server to verify email - mail = imaplib.IMAP4_SSL(services["server"]) - mail.login( - services["email"], - services["password"] - ) - mail.list() - mail.select(services["folder"]) - date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y") - - result, data = mail.uid( - 'search', - None, - '(SENTSINCE {date} HEADER FROM "{mail}")'.format( - date=date, - mail=from_mail - ) - ) - # Return False if email is not present - if data == []: - return False - - latest_email_uid = data[0].split()[-1] - result, data = mail.uid('fetch', latest_email_uid, '(RFC822)') - raw_email = data[0][1] - email_message = email.message_from_string(raw_email) - result = get_first_text_block(email_message) - return result - -def get_first_text_block(email_message_instance): - """fetches first text block from the mail""" - maintype = email_message_instance.get_content_maintype() - if maintype == 'multipart': - for part in email_message_instance.get_payload(): - if part.get_content_maintype() == 'text': - return part.get_payload() - elif maintype == 'text': - return email_message_instance.get_payload() - -def random_gen(size=6, chars=string.ascii_uppercase + string.digits): - """Generate Random Strings of variable length""" - return ''.join(random.choice(chars) for x in range(size)) - -def cleanup_resources(api_client, resources): - """Delete resources""" - for obj in resources: - obj.delete(api_client) - -def is_server_ssh_ready(ipaddress, port, username, password, retries=50): - """Return ssh handle else wait till sshd is running""" - loop_cnt = retries - while True: - try: - ssh = remoteSSHClient.remoteSSHClient( - ipaddress, - port, - username, - password - ) - except Exception as e: - if loop_cnt == 0: - raise e - loop_cnt = loop_cnt - 1 - time.sleep(30) - else: - return ssh - - -def format_volume_to_ext3(ssh_client, device="/dev/sda"): - """Format attached storage to ext3 fs""" - cmds = [ - "echo -e 'n\np\n1\n\n\nw' | fdisk %s" % device, - "mkfs.ext3 %s1" % device, - ] - for c in cmds: - ssh_client.execute(c) - -def fetch_api_client(config_file='datacenterCfg'): - """Fetch the Cloudstack API Client""" - config = configGenerator.get_setup_config(config_file) - mgt = config.mgtSvr[0] - testClientLogger = logging.getLogger("testClient") - asyncTimeout = 3600 - return cloudstackAPIClient.CloudStackAPIClient( - cloudstackConnection.cloudConnection( - mgt.mgtSvrIp, - mgt.port, - mgt.apiKey, - mgt.securityKey, - asyncTimeout, - testClientLogger - ) - ) - -def get_process_status(hostip, port, username, password, linklocalip, process): - """Double hop and returns a process status""" - - #SSH to the machine - ssh = remoteSSHClient.remoteSSHClient( - hostip, - port, - username, - password - ) - ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no " - ssh_command = ssh_command + "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" \ - % (linklocalip, process) - - # Double hop into router - timeout = 5 - # Ensure the SSH login is successful - while True: - res = ssh.execute(ssh_command) - - if res[0] != "Host key verification failed.": - break - elif timeout == 0: - break - - time.sleep(5) - timeout = timeout - 1 - return res \ No newline at end of file diff --git a/tools/testClient/testcase/test_1.py b/tools/testClient/testcase/test_1.py deleted file mode 100644 index f440a6e445c..00000000000 --- a/tools/testClient/testcase/test_1.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackTestCase import * - -@UserName("edison", "edison", "0") -class TestCase1(cloudstackTestCase): - - def test_cloudstackapi(self): - apiClient = self.testClient.getApiClient() - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.id = 10 - listtmcmd.zoneid = 1 - listtmcmd.templatefilter = "featured" - listtmresponse = apiClient.listTemplates(listtmcmd) - if listtmresponse is not None and len(listtmresponse) > 0: - self.debug(listtmresponse) - self.debug("we are here") - else: - self.debug("we are there") - - diff --git a/tools/testClient/testcase/test_2.py b/tools/testClient/testcase/test_2.py deleted file mode 100644 index cf5bcfbadb4..00000000000 --- a/tools/testClient/testcase/test_2.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackTestCase import * -class TestCase2(cloudstackTestCase): - - def test_cloudstackapi1(self): - apiClient = self.testClient.getApiClient() - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.id = 10 - listtmcmd.zoneid = 1 - listtmcmd.templatefilter = "featured" - #listtmresponse = apiClient.listTemplates(listtmcmd) - #self.debug(listtmresponse[0].isready) - - listhostcmd=listHosts.listHostsCmd() - listhostcmd.zoneid=1 - listhostcmd.type="Routing" - - asyncJobResult=self.testClient.submitCmdsAndWait([listhostcmd],1) - listVMresponse = asyncJobResult[0].result - self.debug("Total Number of Hosts: " + str(len(listVMresponse))) - - for i in listVMresponse: - self.debug("id: " + str(i.id) +" pod id: " + str(i.podid) +" host tag: " + str(i.hosttags)) - \ No newline at end of file diff --git a/tools/testClient/testcase/test_3.py b/tools/testClient/testcase/test_3.py deleted file mode 100644 index 35e179de931..00000000000 --- a/tools/testClient/testcase/test_3.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackTestCase import * -import uuid -class TestCase1(cloudstackTestCase): - def setUp(self): - '''get a small service offering id''' - listsocmd = listServiceOfferings.listServiceOfferingsCmd() - listsocmd.name = "Small Instance" - listsocmd.issystem = "false" - sos = self.testClient.getApiClient().listServiceOfferings(listsocmd) - if sos is not None and len(sos) > 0: - self.svid = sos[0].id - listdiskovcmd = listDiskOfferings.listDiskOfferingsCmd() - listdiskovcmd.name = "Small" - disoov = self.testClient.getApiClient().listDiskOfferings(listdiskovcmd) - if disoov is not None and len(disoov) > 0: - self.diskov = disoov[0].id - - '''get user vm template id''' - listtmplcmd = listTemplates.listTemplatesCmd() - listtmplcmd.templatefilter = "featured" - tmpls = self.testClient.getApiClient().listTemplates(listtmplcmd) - if tmpls is not None: - for tmpl in tmpls: - if tmpl.isready: - self.templateId = tmpl.id - self.zoneId = tmpl.zoneid - break - - def test_cloudstackapi(self): - apiClient = self.testClient.getApiClient() - - getzone = listZones.listZonesCmd() - getzone.id = self.zoneId - zone = apiClient.listZones(getzone) - if zone[0].networktype == "Basic": - '''create a security group for admin''' - admincmd = listUsers.listUsersCmd() - admincmd.account = "admin" - admin = apiClient.listUsers(admincmd) - domainId = admin[0].domainid - - securitygroup = authorizeSecurityGroupIngress.authorizeSecurityGroupIngressCmd() - securitygroup.domainid = admin[0].domainid - securitygroup.account = admin[0].account - securitygroup.securitygroupid = 1 - securitygroup.protocol = "TCP" - securitygroup.startport = "22" - securitygroup.endport = "22" - ''' - groups = [{"account":"a","group":"default"}, {"account":"b", "group":"default"}] - securitygroup.usersecuritygrouplist = groups - ''' - cidrlist = ["192.168.1.1/24", "10.1.1.1/24"] - securitygroup.cidrlist = cidrlist - try: - apiClient.authorizeSecurityGroupIngress(securitygroup) - except: - pass - ''' - createvm = deployVirtualMachine.deployVirtualMachineCmd() - createvm.serviceofferingid = self.svid - createvm.templateid = self.templateId - createvm.zoneid = self.zoneId - vm = apiClient.deployVirtualMachine(createvm) - vmId = vm.id - ''' - vmId = 1 - vmcmds = [] - for i in range(10): - createvm = deployVirtualMachine.deployVirtualMachineCmd() - createvm.serviceofferingid = self.svid - createvm.templateid = self.templateId - createvm.zoneid = self.zoneId - vmcmds.append(createvm) - - result = self.testClient.submitCmdsAndWait(vmcmds, 5) - for jobstatus in result: - if jobstatus.status == 1: - self.debug(jobstatus.result.id) - self.debug(jobstatus.result.displayname) - else: - self.debug(jobstatus.result) - - creatvolume = createVolume.createVolumeCmd() - creatvolume.name = "tetst" + str(uuid.uuid4()) - creatvolume.diskofferingid = self.diskov - creatvolume.zoneid = self.zoneId - createvolumeresponse = apiClient.createVolume(creatvolume) - volumeId = createvolumeresponse.id - attach = attachVolume.attachVolumeCmd() - - attach.id = volumeId - attach.virtualmachineid = vmId - apiClient.attachVolume(attach) - - detach = detachVolume.detachVolumeCmd() - detach.id = volumeId - detach.virtualmachineid = vmId - apiClient.detachVolume(detach) - - snapshotcmd = createSnapshot.createSnapshotCmd() - snapshotcmd.volumeid = volumeId - snapshotrespose = apiClient.createSnapshot(snapshotcmd) - snapshotId = snapshotrespose.id - - createvolume = createVolume.createVolumeCmd() - createvolume.snapshotid = snapshotId - createvolume.name = "volumefrom_snapshot"+ str(snapshotId) - apiClient.createVolume(createvolume) - \ No newline at end of file diff --git a/tools/testClient/testcase/test_userDecorator.py b/tools/testClient/testcase/test_userDecorator.py deleted file mode 100644 index 437700c559e..00000000000 --- a/tools/testClient/testcase/test_userDecorator.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackTestCase import * - -#@UserName('user', 'LEAF', 0) -#@UserName('user0', 'LEAF', 0) -#@UserName('user', 'LEAF0', 0) -#@UserName('admin', 'ROOT', 1) -@UserName('domadmin', 'LEAF0', 2) -class TestUserDecorator(cloudstackTestCase): - - def test_listUserTemplates(self): - apiClient = self.testClient.getApiClient() - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.zoneid = 1 - listtmcmd.templatefilter = "self" - listtmresponse = apiClient.listTemplates(listtmcmd) - if listtmresponse is not None: - self.assertEqual(len(listtmresponse), 0, "there should be no user created templates") - self.debug("%d user templates found"%len(listtmresponse)) - - def test_listFeaturedTemplates(self): - apiClient = self.testClient.getApiClient() - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.zoneid = 1 - listtmcmd.templatefilter = "featured" - listtmresponse = apiClient.listTemplates(listtmcmd) - if listtmresponse is not None: - self.assertNotEqual(len(listtmresponse), 0, "there should default featured templates") - self.debug("%d featured templates found"%len(listtmresponse)) - return listtmresponse[0].id - - def test_listVirtualMachines(self): - apiClient = self.testClient.getApiClient() - listvmcmd = listVirtualMachines.listVirtualMachinesCmd() - listvmcmd.zoneid = 1 - listvmcmd.state = "Running" - listvmresponse = apiClient.listVirtualMachines(listvmcmd) - if listvmresponse is not None and len(listvmresponse) > 0: - self.debug("%d running VMs found"%len(listvmresponse)) - else: - self.debug("No Vms Found") - - def test_deployVM(self): - apiClient = self.testClient.getApiClient() - listzones = listZones.listZonesCmd() - listzoneres = apiClient.listZones(listzones) - zoneid = listzoneres[0].id - - listservice = listServiceOfferings.listServiceOfferingsCmd() - listserviceres = apiClient.listServiceOfferings(listservice) - serviceofferingid = listserviceres[0].id - - deploycmd = deployVirtualMachine.deployVirtualMachineCmd() - deploycmd.displayname = "testVm" - deploycmd.templateid = self.test_listFeaturedTemplates() - deploycmd.zoneid = zoneid - deploycmd.serviceofferingid = serviceofferingid - apiClient.deployVirtualMachine(deploycmd) diff --git a/tools/testClient/translator.py b/tools/testClient/translator.py deleted file mode 100644 index 5b3375bebce..00000000000 --- a/tools/testClient/translator.py +++ /dev/null @@ -1,212 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import xml.dom.minidom -import datetime -from optparse import OptionParser -import random -import os -import sys - -# Constants -INDENT = " " -INDENT2 = INDENT + INDENT - -class xml_to_python(object): - def __init__(self, debug): - ''' - constructor - ''' - self.debug = debug - self._output = False - self.out_buffer = [] - - self.cmd_name = None - self.cmd_name_var = None - self.cmd_name_resp = None - - self.glos = [] - - def _write(self, output_string): - ''' - internal print function - ''' - self.out_buffer.append("%s\n" % output_string) - - def parse_parameters(self, dom): - ''' - process parameters of command - ''' - for param in dom.getElementsByTagName("parameters"): - for item in param.getElementsByTagName("item"): - itemName = item.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() - itemParam = None - itemValue = None - - # this could be handled much cleaner - try: - itemValue = item.getElementsByTagName("value")[0].childNodes[0].nodeValue.strip() - except: - itemValue = None - try: - itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() - except: - itemParam = None - - # handle getparam and setparam and random attributes here... - if item.getAttribute("getparam") == "true" and itemParam is not None: - self._write("%s%s.%s = %s" % (INDENT, self.cmd_name_var, itemName, itemParam)) - self.glos.append(itemParam) - elif item.getAttribute("random") == "true" or item.getAttribute("randomnumber") == "true": - # we should do this in the resulting python file. - randValue = int(random.random() * 10000000) - self._write("%s%s.%s = '%s-randomName'" % (INDENT, self.cmd_name_var, itemName, str(randValue))) - if item.getAttribute("setparam") == "true" and itemParam is not None: - self._write("%s%s = '%s-randomName'" % (INDENT, itemParam, str(randValue))) - self.glos.append(itemParam) - else: - try: - val = int(itemValue) - except: - val = "'%s'" % itemValue - self._write("%s%s.%s = %s" % (INDENT, self.cmd_name_var, itemName, val)) - - - def parse_returnvalue(self, dom): - ''' - process returnvalue section of command - ''' - for return_val in dom.getElementsByTagName("returnvalue"): - for item in return_val.getElementsByTagName("item"): - #if item.getAttribute("list") == "true": - - itemName = item.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() - try: - itemParam = item.getElementsByTagName("param")[0].childNodes[0].nodeValue.strip() - except: - print "parse_returnvalue: No 'param' found in : '" + item.toprettyxml() + "'" - itemParam = None - - if item.getAttribute("setparam") == "true": - self._write("%s%s = %s.%s" % (INDENT, itemParam, self.cmd_name_resp, itemName)) - else: - self._write("%sif %s != %s.%s:" % (INDENT, itemParam, self.cmd_name_resp, itemName)) - self._write("%sprint %s.%s + \" does not match \" + %s" % ( - INDENT2, self.cmd_name_resp, itemName, itemParam)) - - - def parse_command(self, dom): - ''' - process command elements and their children - ''' - for cmd in dom.getElementsByTagName("command"): - self.cmd_name = cmd.getElementsByTagName("name")[0].childNodes[0].nodeValue.strip() - self.cmd_name_var = "_%s" % self.cmd_name - self.cmd_name_resp = "resp_%s" % self.cmd_name - - try: - testCaseName = cmd.getElementsByTagName("testcase")[0].childNodes[0].nodeValue.strip() - except: - print "parse_command: No 'testcase' found in: " + cmd.toprettyxml() - testCaseName = None - self._write("\n%s# %s" % (INDENT, testCaseName)) - - self._write("%s%s = %s.%sCmd()" % (INDENT, self.cmd_name_var, self.cmd_name, self.cmd_name)) - - self.parse_parameters(cmd) - # now we execute command - self._write("%s%s = apiClient.%s(%s)" % (INDENT, self.cmd_name_resp, self.cmd_name, self.cmd_name_var)) - self._write("%sif %s is None:" % (INDENT, self.cmd_name_resp)) - self._write("%sprint 'test [%s] failed'" % (INDENT2, testCaseName)) - self._write("%selse:" % INDENT) - self._write("%sprint 'test [%s] succeeded'" % (INDENT2, testCaseName)) - self.parse_returnvalue(cmd) - - def generate_python_header(self, outfile): - ''' - generates python file header - - the basic stuff to bootstrap the script - ''' - now = datetime.datetime.now() - - outfile.write("# Generated by translator.py\n") - outfile.write("# from %s\n" % options.xmlfile) - outfile.write("# on %s\n\n" % str(now)) - outfile.write("from cloudstackTestCase import *\n") - outfile.write("import cloudstackTestClient\n") - outfile.write("import time\n\n") - outfile.write("# These are global variables used in the script below\n") - for key in set(self.glos): - outfile.write("%s = None\n" % key) - outfile.write("# End of globals\n\n") - outfile.write("if __name__ == \"__main__\":\n") - outfile.write("%s# Possible initialization parameters:\n" % INDENT) - outfile.write("%s# cloudstackTestClient(mgtSvr=None, port=8096, apiKey = None, securityKey = None,\n" % INDENT) - outfile.write("%s# asyncTimeout=3600, defaultWorkerThreads=10, logging=None)\n" % INDENT) - outfile.write("%stestClient = cloudstackTestClient.cloudstackTestClient(\"localhost\")\n" % INDENT) - outfile.write("%sapiClient = testClient.getApiClient()\n" % INDENT) - - def output_python(self, outfile): - self.generate_python_header(outfile) - for line in self.out_buffer: - outfile.write(line) - outfile.close() - - - def parse_xmlFile(self, xmlFile, outfile): - ''' - parse_xmlFile, this is the main function of the translator - ''' - dom = xml.dom.minidom.parse(xmlFile) - - self.parse_command(dom) - self.output_python(outfile) - - -if __name__ == "__main__": - opts = OptionParser() - - opts.add_option("-i", "--inputfile", dest="xmlfile", help="The XML file and it's path containing tests.", - default="../../test/metadata/func/portforwarding.xml") - opts.add_option("-o", "--output_file_path", dest="outpath", help="The path where we create the python file.") - opts.add_option("-d", action="store_true", dest="debug", - help="Don't create output file, but send output to stderr", default=False) - - (options, args) = opts.parse_args() - - if options.xmlfile is None or not os.path.exists(options.xmlfile): - print "The input file MUST be specified and exist: %s" % options.xmlfile - exit(1) - - if options.debug == False: - if options.outpath is None: - options.outpath = "%s.py" % (os.path.basename(options.xmlfile)) - else: - if options.outpath.endswith('/'): - options.outpath = "%s%s.py" % (options.outpath, os.path.basename(options.xmlfile)) - else: - options.outpath = "%s/%s.py" % (options.outpath, os.path.basename(options.xmlfile)) - - if os.path.exists(options.outpath): - print "The output file already exists: %s" % options.outpath - exit(1) - - outFile = open(options.outpath, "w") - else: - outFile = sys.stderr - - print("[Processing: %s Output: %s]" % (options.xmlfile, outFile.name)) - - processor = xml_to_python(options.debug) - - processor.parse_xmlFile(options.xmlfile, outFile) diff --git a/tools/testClient/unitTest/test_advanced.py b/tools/testClient/unitTest/test_advanced.py deleted file mode 100644 index a4ff26fd650..00000000000 --- a/tools/testClient/unitTest/test_advanced.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import xml.dom.minidom -import inspect -import uuid -import time -from cloudstackAPI import * -import cloudstackTestClient -if __name__ == "__main__": - randomName = str(uuid.uuid4()) - testClient = cloudstackTestClient.cloudstackTestClient("localhost") - api = testClient.getApiClient() - - czcmd = createZone.createZoneCmd() - czcmd.dns1 = "8.8.8.8" - czcmd.internaldns1 = "192.168.110.254" - czcmd.name = "test" + randomName - czcmd.networktype = "Advanced" - czcmd.guestcidraddress = "10.1.1.0/24" - czcmd.vlan = "1160-1200" - czresponse = api.createZone(czcmd) - zoneId = czresponse.id - - cvlancmd = createVlanIpRange.createVlanIpRangeCmd() - cvlancmd.zoneid = zoneId - cvlancmd.vlan = "2020" - cvlancmd.gateway = "172.16.112.1" - cvlancmd.netmask = "255.255.0.0" - cvlancmd.startip = "172.16.112.2" - cvlancmd.endip = "172.16.112.100" - api.createVlanIpRange(cvlancmd) - - cpodcmd = createPod.createPodCmd() - cpodcmd.zoneid = zoneId - cpodcmd.gateway = "192.168.137.1" - cpodcmd.name = "testpod"+ randomName - cpodcmd.netmask = "255.255.255.0" - cpodcmd.startip = "192.168.137.200" - cpodcmd.endip = "192.168.137.220" - cpodresponse = api.createPod(cpodcmd) - podId = cpodresponse.id - - aclustercmd = addCluster.addClusterCmd() - aclustercmd.clustername = "testcluster"+ randomName - aclustercmd.hypervisor = "KVM" - aclustercmd.podid = podId - aclustercmd.zoneid = zoneId - aclustercmd.clustertype = "CloudManaged" - clusterresponse = api.addCluster(aclustercmd) - clusterId = clusterresponse[0].id - ''' - for i in range(1): - addhostcmd = addHost.addHostCmd() - addhostcmd.zoneid = zoneId - addhostcmd.podid = podId - addhostcmd.clusterid = clusterId - addhostcmd.hypervisor = "KVM" - addhostcmd.username = "root" - addhostcmd.password = "password" - addhostcmd.url = "http://192.168.137.2" - addhostresponse = api.addHost(addhostcmd) - print addhostresponse[0].id, addhostresponse[0].ipaddress - ''' - createspcmd = createStoragePool.createStoragePoolCmd() - createspcmd.zoneid = zoneId - createspcmd.podid = podId - createspcmd.clusterid = clusterId - createspcmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/kvm2" - createspcmd.name = "storage pool" + randomName - createspresponse = api.createStoragePool(createspcmd) - - addsscmd = addSecondaryStorage.addSecondaryStorageCmd() - addsscmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/xen/secondary" - addsscmd.zoneid = zoneId - api.addSecondaryStorage(addsscmd) - - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.id = 4 - listtmcmd.zoneid = zoneId - listtmcmd.templatefilter = "featured" - listtmresponse = api.listTemplates(listtmcmd) - while True: - if listtmresponse is not None and listtmresponse[0].isready == "true": - break - time.sleep(30) - listtmresponse = api.listTemplates(listtmcmd) - - vmId = [] - for i in range(2): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = zoneId - cmd.hypervisor = "KVM" - cmd.serviceofferingid = "1" - cmd.templateid = listtmresponse[0].id - res = api.deployVirtualMachine(cmd) - - vmId.append(res.id) diff --git a/tools/testClient/unitTest/test_async.py b/tools/testClient/unitTest/test_async.py deleted file mode 100644 index 14aed9bc4a8..00000000000 --- a/tools/testClient/unitTest/test_async.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -from cloudstackAPI import * -import cloudstackException -import cloudstackTestClient -import sys -import uuid - -class jobs(): - def __init__(self, zoneId): - self.zoneId = zoneId - - def run(self): - try: - cmd = destroyVirtualMachine.destroyVirtualMachineCmd() - cmd.id = 4 - self.apiClient.destroyVirtualMachine(cmd) - except cloudstackException.cloudstackAPIException, e: - print str(e) - except : - print sys.exc_info() - -if __name__ == "__main__": - ''' to logging the testclient - logger = logging.getLogger("test_async") - fh = logging.FileHandler("test.log") - logger.addHandler(fh) - logger.setLevel(logging.DEBUG) - testclient = cloudstackTestClient.cloudstackTestClient(mgtSvr="localhost", logging=logger) - ''' - testclient = cloudstackTestClient.cloudstackTestClient(mgtSvr="localhost", port=8080, apiKey="rUJI62HcbyhAXpRgqERZHXlrJz9GiC55fmAm7j4WobLUTFkJyupBm87sbMki1-aRFox7TDs436xYvNW9fTHcew", securityKey="2_SIz9HULx5guCLypSoRoePCBFnTZGIrA3gQ0qhy__oca6dDacJwibMSQh-kVeJivJHeA55AwJZPJAu4U3V5KQ") - testclient.dbConfigure() - api = testclient.getApiClient() - ''' - testclient.submitJob(jobs(1), 10, 10, 1) - - js = [] - for i in range(10): - js.append(jobs(1)) - - testclient.submitJobs(js, 10, 1) - ''' - cmds = [] - for i in range(20): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid =1 - cmd.templateid = 10 - cmd.serviceofferingid = 16 - cmd.displayname = str(uuid.uuid4()) - cmds.append(cmd) - - asyncJobResult = testclient.submitCmdsAndWait(cmds, 6) - - for jobStatus in asyncJobResult: - if jobStatus.status: - print jobStatus.result[0].id, jobStatus.result[0].templatename, jobStatus.startTime, jobStatus.endTime - else: - print jobStatus.result, jobStatus.startTime, jobStatus.endTime - - print jobStatus.duration diff --git a/tools/testClient/unitTest/test_basic_zone.py b/tools/testClient/unitTest/test_basic_zone.py deleted file mode 100644 index 9a1edf8f9f5..00000000000 --- a/tools/testClient/unitTest/test_basic_zone.py +++ /dev/null @@ -1,227 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import uuid -from cloudstackAPI import * -import cloudstackException -import cloudstackTestClient -import time -if __name__ == "__main__": - hypervisor = "KVM" - hostNum = 30 - templateId = 10 - vmNum = 10 - - randomName = str(uuid.uuid4()) - - testClient = cloudstackTestClient.cloudstackTestClient("localhost") - api = testClient.getApiClient() - - - czcmd = createZone.createZoneCmd() - czcmd.dns1 = "8.8.8.8" - czcmd.internaldns1 = "192.168.110.254" - czcmd.name = "test" + randomName - czcmd.networktype = "Basic" - - czresponse = api.createZone(czcmd) - zoneId = czresponse.id - - cpodcmd = createPod.createPodCmd() - cpodcmd.zoneid = zoneId - cpodcmd.gateway = "192.168.137.1" - cpodcmd.name = "testpod"+ randomName - cpodcmd.netmask = "255.255.255.0" - cpodcmd.startip = "192.168.137.200" - cpodcmd.endip = "192.168.137.230" - cpodresponse = api.createPod(cpodcmd) - podId = cpodresponse.id - - cvlancmd = createVlanIpRange.createVlanIpRangeCmd() - cvlancmd.zoneid = zoneId - cvlancmd.podid = podId - cvlancmd.gateway = "192.168.137.1" - cvlancmd.netmask = "255.255.255.0" - cvlancmd.startip = "192.168.137.100" - cvlancmd.endip = "192.168.137.190" - cvlancmd.forvirtualnetwork = "false" - cvlancmd.vlan = "untagged" - - api.createVlanIpRange(cvlancmd) - - aclustercmd = addCluster.addClusterCmd() - aclustercmd.clustername = "testcluster"+ randomName - aclustercmd.hypervisor = hypervisor - aclustercmd.podid = podId - aclustercmd.zoneid = zoneId - aclustercmd.clustertype = "CloudManaged" - clusterresponse = api.addCluster(aclustercmd) - clusterId = clusterresponse[0].id - ''' - for i in range(hostNum): - addhostcmd = addHost.addHostCmd() - addhostcmd.zoneid = zoneId - addhostcmd.podid = podId - addhostcmd.clusterid = clusterId - addhostcmd.hypervisor = hypervisor - addhostcmd.username = "root" - addhostcmd.password = "password" - if hypervisor == "Simulator": - addhostcmd.url = "http://sim" - else: - addhostcmd.url = "http://192.168.137.4" - addhostresponse = api.addHost(addhostcmd) - print addhostresponse[0].id, addhostresponse[0].ipaddress - - createspcmd = createStoragePool.createStoragePoolCmd() - createspcmd.zoneid = zoneId - createspcmd.podid = podId - createspcmd.clusterid = clusterId - createspcmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/primary" - createspcmd.name = "storage pool" + randomName - createspresponse = api.createStoragePool(createspcmd) - - addsscmd = addSecondaryStorage.addSecondaryStorageCmd() - addsscmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/xen/secondary" - addsscmd.zoneid = zoneId - api.addSecondaryStorage(addsscmd) - - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.id = templateId - listtmcmd.zoneid = zoneId - listtmcmd.templatefilter = "featured" - listtmresponse = api.listTemplates(listtmcmd) - while True: - if listtmresponse is not None and listtmresponse[0].isready == "true": - break - time.sleep(30) - listtmresponse = api.listTemplates(listtmcmd) - - vmId = [] - for i in range(vmNum): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = zoneId - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - cmd.templateid = listtmresponse[0].id - res = api.deployVirtualMachine(cmd) - - vmId.append(res.id) - - - registerTempl = registerTemplate.registerTemplateCmd() - registerTempl.displaytext = "test template4" - registerTempl.format = "QCOW2" - registerTempl.hypervisor = "Simulator" - registerTempl.name = "test template4" - registerTempl.ostypeid = "100" - registerTempl.url = "http://www.google.com/template.qcow2" - registerTempl.zoneid = 1 - registerTemlResponse = api.registerTemplate(registerTempl) - newtemplateId = registerTemlResponse[0].id - - listtempl = listTemplates.listTemplatesCmd() - listtempl.id = newtemplateId - listtempl.templatefilter = "self" - listemplResponse = api.listTemplates(listtempl) - while True: - if listemplResponse is not None: - - if listemplResponse[0].isready == "true": - break - else: - print listemplResponse[0].status - - time.sleep(30) - listemplResponse = api.listTemplates(listtempl) - - - - for i in range(10): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = 1 - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - #cmd.templateid = listemplResponse[0].id - cmd.templateid = 200 - res = api.deployVirtualMachine(cmd) - - - createvolume = createVolume.createVolumeCmd() - createvolume.zoneid = 1 - createvolume.diskofferingid = 9 - createvolume.name = "test" - - createvolumeresponse = api.createVolume(createvolume) - volumeId = createvolumeresponse.id - - attachvolume = attachVolume.attachVolumeCmd() - attachvolume.id = volumeId - attachvolume.virtualmachineid = 9 - attachvolumeresponse = api.attachVolume(attachvolume) - - deattachevolume = detachVolume.detachVolumeCmd() - deattachevolume.id = volumeId - deattachvolumeresponse = api.detachVolume(deattachevolume) - - createsnapshot = createSnapshot.createSnapshotCmd() - createsnapshot.volumeid = volumeId - createsnapshotresponse = api.createSnapshot(createsnapshot) - snapshotId = createsnapshotresponse.id - - createtmpl = createTemplate.createTemplateCmd() - createtmpl.snapshotid = snapshotId - createtmpl.name = randomName[:10] - createtmpl.displaytext = randomName[:10] - createtmpl.ostypeid = 100 - createtmpl.ispublic = "false" - createtmpl.passwordenabled = "false" - createtmpl.isfeatured = "false" - createtmplresponse = api.createTemplate(createtmpl) - templateId = createtmplresponse.id - - createvolume = createVolume.createVolumeCmd() - createvolume.snapshotid = snapshotId - createvolume.name = "test" - createvolumeresponse = api.createVolume(createvolume) - volumeId = createvolumeresponse.id - - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = 1 - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - cmd.templateid = templateId - cmd.name = "fdf" - res = api.deployVirtualMachine(cmd) - - attachvolume = attachVolume.attachVolumeCmd() - attachvolume.id = volumeId - attachvolume.virtualmachineid = 1 - attachvolumeresponse = api.attachVolume(attachvolume) - - deattachevolume = detachVolume.detachVolumeCmd() - deattachevolume.id = volumeId - deattachvolumeresponse = api.detachVolume(deattachevolume) - - deletetmpl = deleteTemplate.deleteTemplateCmd() - deletetmpl.id = templateId - deletetmpl.zoneid = 1 - api.deleteTemplate(deletetmpl) - - deletevolume = deleteVolume.deleteVolumeCmd() - deletevolume.id = volumeId - api.deleteVolume(deletevolume) - - deletesnapshot = deleteSnapshot.deleteSnapshotCmd() - deletesnapshot.id = snapshotId - - ''' \ No newline at end of file diff --git a/tools/testClient/unitTest/test_local_storage.py b/tools/testClient/unitTest/test_local_storage.py deleted file mode 100644 index 539025fdbbc..00000000000 --- a/tools/testClient/unitTest/test_local_storage.py +++ /dev/null @@ -1,255 +0,0 @@ -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by 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. -# -# Automatically generated by addcopyright.py at 04/03/2012 -import uuid -import time -import cloudstackAPIException -import cloudstackTestClient -from cloudstackAPI import * -if __name__ == "__main__": - hypervisor = "Simulator" - hostNum = 100 - clusterNum = hostNum/10 - templateId = 10 - vmNum = 10 - - randomName = str(uuid.uuid4()) - - testclient = cloudstackTestClient.cloudstackTestClient("localhost") - api = testclient.getApiClient() - - - updatecfg = updateConfiguration.updateConfigurationCmd() - updatecfg.name = "expunge.delay" - updatecfg.value = "100" - ret = api.updateConfiguration(updatecfg) - - updatecfg.name = "expunge.interval" - updatecfg.value = "100" - ret = api.updateConfiguration(updatecfg) - - updatecfg.name = "ping.interval" - updatecfg.value = "180" - ret = api.updateConfiguration(updatecfg) - - updatecfg.name = "system.vm.use.local.storage" - updatecfg.value = "true" - ret = api.updateConfiguration(updatecfg) - - updatecfg.name = "use.local.storage" - updatecfg.value = "true" - ret = api.updateConfiguration(updatecfg) - - - - czcmd = createZone.createZoneCmd() - czcmd.dns1 = "8.8.8.8" - czcmd.internaldns1 = "192.168.110.254" - czcmd.name = "test" + randomName - czcmd.networktype = "Basic" - - czresponse = api.createZone(czcmd) - zoneId = czresponse.id - - cpodcmd = createPod.createPodCmd() - cpodcmd.zoneid = zoneId - cpodcmd.gateway = "192.168.137.1" - cpodcmd.name = "testpod"+ randomName - cpodcmd.netmask = "255.255.255.0" - cpodcmd.startip = "192.168.137.200" - cpodcmd.endip = "192.168.137.230" - cpodresponse = api.createPod(cpodcmd) - podId = cpodresponse.id - - cvlancmd = createVlanIpRange.createVlanIpRangeCmd() - cvlancmd.zoneid = zoneId - cvlancmd.podid = podId - cvlancmd.gateway = "192.168.137.1" - cvlancmd.netmask = "255.255.255.0" - cvlancmd.startip = "192.168.137.100" - cvlancmd.endip = "192.168.137.190" - cvlancmd.forvirtualnetwork = "false" - cvlancmd.vlan = "untagged" - - api.createVlanIpRange(cvlancmd) - - aclustercmd = addCluster.addClusterCmd() - aclustercmd.clustername = "testcluster"+ randomName - aclustercmd.hypervisor = hypervisor - aclustercmd.podid = podId - aclustercmd.zoneid = zoneId - aclustercmd.clustertype = "CloudManaged" - clusterresponse = api.addCluster(aclustercmd) - clusterId = clusterresponse[0].id - - for i in range(hostNum): - addhostcmd = addHost.addHostCmd() - addhostcmd.zoneid = zoneId - addhostcmd.podid = podId - addhostcmd.clusterid = clusterId - addhostcmd.hypervisor = hypervisor - addhostcmd.username = "root" - addhostcmd.password = "password" - if hypervisor == "Simulator": - addhostcmd.url = "http://sim" - else: - addhostcmd.url = "http://192.168.137.4" - addhostresponse = api.addHost(addhostcmd) - print addhostresponse[0].id, addhostresponse[0].ipaddress - - - createspcmd = createStoragePool.createStoragePoolCmd() - createspcmd.zoneid = zoneId - createspcmd.podid = podId - createspcmd.clusterid = clusterId - createspcmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/primary" - createspcmd.name = "storage pool" + randomName - createspresponse = api.createStoragePool(createspcmd) - - - - addsscmd = addSecondaryStorage.addSecondaryStorageCmd() - addsscmd.url = "nfs://nfs2.lab.vmops.com/export/home/edison/xen/secondary" - addsscmd.zoneid = zoneId - api.addSecondaryStorage(addsscmd) - - listtmcmd = listTemplates.listTemplatesCmd() - listtmcmd.id = templateId - listtmcmd.zoneid = zoneId - listtmcmd.templatefilter = "featured" - listtmresponse = api.listTemplates(listtmcmd) - while True: - if listtmresponse is not None and listtmresponse[0].isready == "true": - break - time.sleep(30) - listtmresponse = api.listTemplates(listtmcmd) - - vmId = [] - for i in range(vmNum): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = zoneId - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - cmd.templateid = listtmresponse[0].id - res = api.deployVirtualMachine(cmd) - - vmId.append(res.id) - - registerTempl = registerTemplate.registerTemplateCmd() - registerTempl.displaytext = "test template4" - registerTempl.format = "QCOW2" - registerTempl.hypervisor = "Simulator" - registerTempl.name = "test template4" - registerTempl.ostypeid = "100" - registerTempl.url = "http://www.google.com/template.qcow2" - registerTempl.zoneid = 1 - registerTemlResponse = api.registerTemplate(registerTempl) - newtemplateId = registerTemlResponse[0].id - - listtempl = listTemplates.listTemplatesCmd() - listtempl.id = newtemplateId - listtempl.templatefilter = "self" - listemplResponse = api.listTemplates(listtempl) - while True: - if listemplResponse is not None: - - if listemplResponse[0].isready == "true": - break - else: - print listemplResponse[0].status - - time.sleep(30) - listemplResponse = api.listTemplates(listtempl) - - - - for i in range(10): - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = 1 - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - #cmd.templateid = listemplResponse[0].id - cmd.templateid = 200 - res = api.deployVirtualMachine(cmd) - - - createvolume = createVolume.createVolumeCmd() - createvolume.zoneid = 1 - createvolume.diskofferingid = 9 - createvolume.name = "test" - - createvolumeresponse = api.createVolume(createvolume) - volumeId = createvolumeresponse.id - - attachvolume = attachVolume.attachVolumeCmd() - attachvolume.id = volumeId - attachvolume.virtualmachineid = 9 - attachvolumeresponse = api.attachVolume(attachvolume) - - deattachevolume = detachVolume.detachVolumeCmd() - deattachevolume.id = volumeId - deattachvolumeresponse = api.detachVolume(deattachevolume) - - createsnapshot = createSnapshot.createSnapshotCmd() - createsnapshot.volumeid = volumeId - createsnapshotresponse = api.createSnapshot(createsnapshot) - snapshotId = createsnapshotresponse.id - - createtmpl = createTemplate.createTemplateCmd() - createtmpl.snapshotid = snapshotId - createtmpl.name = randomName[:10] - createtmpl.displaytext = randomName[:10] - createtmpl.ostypeid = 100 - createtmpl.ispublic = "false" - createtmpl.passwordenabled = "false" - createtmpl.isfeatured = "false" - createtmplresponse = api.createTemplate(createtmpl) - templateId = createtmplresponse.id - - createvolume = createVolume.createVolumeCmd() - createvolume.snapshotid = snapshotId - createvolume.name = "test" - createvolumeresponse = api.createVolume(createvolume) - volumeId = createvolumeresponse.id - - cmd = deployVirtualMachine.deployVirtualMachineCmd() - cmd.zoneid = 1 - cmd.hypervisor = hypervisor - cmd.serviceofferingid = "1" - cmd.templateid = templateId - cmd.name = "fdf" - res = api.deployVirtualMachine(cmd) - - - - attachvolume = attachVolume.attachVolumeCmd() - attachvolume.id = volumeId - attachvolume.virtualmachineid = 1 - attachvolumeresponse = api.attachVolume(attachvolume) - - deattachevolume = detachVolume.detachVolumeCmd() - deattachevolume.id = volumeId - deattachvolumeresponse = api.detachVolume(deattachevolume) - - deletetmpl = deleteTemplate.deleteTemplateCmd() - deletetmpl.id = templateId - deletetmpl.zoneid = 1 - api.deleteTemplate(deletetmpl) - - deletevolume = deleteVolume.deleteVolumeCmd() - deletevolume.id = volumeId - api.deleteVolume(deletevolume) - - deletesnapshot = deleteSnapshot.deleteSnapshotCmd() - deletesnapshot.id = snapshotId - - \ No newline at end of file diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 5e2c640de06..db77fc9a6ae 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -351,6 +351,68 @@ body.login { background: #FFFFFF; } +/*About dialog*/ +.dialog-about .ui-widget-content { + padding-left: 0; + padding-right: 0; + width: 100% !important; +} + +.dialog-about .logo { + font-size: 26px; + color: #636363; + padding-top: 20px; +} + +.dialog-about .version { + font-size: 12px; + padding-top: 10px; +} + +.dialog-about .ui-button { + float: none; + margin: 0 auto; +} + +#browser div.panel div.detail-view .toolbar { + width: 594px; +} + +div.list-view table tbody td span { + display: block; + float: left; + max-width: 210px; + word-wrap: break-word; + text-indent: 0; + margin-left: 12px; + line-height: 15px; + overflow: auto; + overflow-x: hidden; +} + +div.list-view div.toolbar div.section-switcher div.section-select label { + margin: 0 9px 0 0; +} + +.loading-overlay { + position: absolute; + width: 100%; + height: 100%; + left: 0px; + top: 0px; + background: #F2F2F2 url(../images/ajax-loader.gif) no-repeat center; + z-index: 500; + /*+opacity:70%;*/ + filter: alpha(opacity=70); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70); + -moz-opacity: 0.7; + opacity: 0.7; +} + +.detail-view .ui-tabs-panel .loading-overlay { + background-position: 50% 250px; +} + /*Install wizard*/ .install-wizard { width: 1024px; @@ -499,7 +561,7 @@ body.login { .install-wizard .button.advanced-installation, .install-wizard .button.go-back { background: #E0DEDE; - color: #7D7D7D; + color: #3B3B3B; border: 1px solid #C7C2C2; /*+text-shadow:0px 0px #FFFFFF;*/ -moz-text-shadow: 0px 0px #FFFFFF; @@ -1579,43 +1641,10 @@ div.details div.detail-group td.value input[type=text] { width: 93%; } -#browser div.panel div.detail-view .toolbar { - width: 594px; -} - -div.list-view table tbody td span { - display: block; - float: left; - max-width: 210px; - word-wrap: break-word; - text-indent: 0; - margin-left: 12px; - line-height: 15px; - overflow: auto; - overflow-x: hidden; -} - -div.list-view div.toolbar div.section-switcher div.section-select label { - margin: 0 9px 0 0; -} - -.loading-overlay { +div.details .main-groups label.error { position: absolute; - width: 100%; - height: 100%; - left: 0px; - top: 0px; - background: #F2F2F2 url(../images/ajax-loader.gif) no-repeat center; - z-index: 500; - /*+opacity:70%;*/ - filter: alpha(opacity=70); - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70); - -moz-opacity: 0.7; - opacity: 0.7; -} - -.detail-view .ui-tabs-panel .loading-overlay { - background-position: 50% 250px; + right: 10%; + top: 6px; } /*** Actions*/ @@ -2808,6 +2837,7 @@ Dialogs*/ -webkit-box-shadow: 0px -4px 15px #4C4A4A; -o-box-shadow: 0px -4px 15px #4C4A4A; box-shadow: 0px -4px 15px #4C4A4A; + position: absolute; } .ui-dialog .ui-widget-content { @@ -8806,6 +8836,419 @@ div.panel.ui-dialog div.list-view div.fixed-header { background: #DFE1E3; } +/*VPC / vApps*/ +.vpc-chart { + width: 100%; + height: 94%; + overflow: auto; + position: relative; + margin: 30px 0 0; + background: #FFFFFF 0px 24px; +} + +.vpc-chart .vpc-title { + width: 210px; + font-size: 22px; + /*+placement:shift 11px 41px;*/ + position: relative; + left: 11px; + top: 41px; + position: absolute; + color: #5F768A; +} + +.vpc-chart .vpc-title > span { + max-width: 160px; + display: block; + float: left; + overflow-y: hidden; + overflow-x: auto; +} + +.vpc-chart .vpc-title .icon { + padding: 7px 15px; + background: url(../images/sprites.png) no-repeat -145px -195px; + margin-left: 10px; + cursor: pointer; + /*+placement:shift 6px -8px;*/ + position: relative; + left: 6px; + top: -8px; + float: left; +} + +.vpc-chart .vpc-title .vpc-configure-tooltip { + width: 129px; + padding: 35px 10px 10px; + font-size: 14px; + display: none; + position: absolute; +} + +.vpc-chart .vpc-title .vpc-configure-tooltip .arrow { + width: 30px; + height: 20px; + background: #FFFFFF url(../images/sprites.png) no-repeat -589px -997px; + /*+placement:shift 13px 26px;*/ + position: relative; + left: 13px; + top: 26px; + position: absolute; + z-index: 1; +} + +.vpc-chart .vpc-title .vpc-configure-tooltip ul { + border: 1px solid #C2C2C2; + background: #FFFFFF; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + /*+placement:shift 0px -6px;*/ + position: relative; + left: 0px; + top: -6px; + margin: 10px 0; + padding: 9px; + /*+box-shadow:0px 1px 8px #CBCBCB;*/ + -moz-box-shadow: 0px 1px 8px #CBCBCB; + -webkit-box-shadow: 0px 1px 8px #CBCBCB; + -o-box-shadow: 0px 1px 8px #CBCBCB; + box-shadow: 0px 1px 8px #CBCBCB; +} + +.vpc-chart .vpc-title .vpc-configure-tooltip li { + padding: 3px 0 5px; + cursor: pointer; + font-size: 12px; +} + +.vpc-chart .vpc-title .vpc-configure-tooltip li:hover { + font-weight: bold; +} + +.vpc-chart ul.tiers { + padding: 0 0 0 26px; + margin: 79px 0 0 232px; + border-left: 3px solid #CCC; +} + +.vpc-chart li.tier { + display: block; + width: 258px; + height: 107px; + margin: -55px 0 90px; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + border: 1px solid #50545A; + background: url(../images/bg-gradients.png) 0px -2637px; + /*+placement:shift 0px 58px;*/ + position: relative; + left: 0px; + top: 58px; + position: relative; + /*+box-shadow:0px 5px 7px #DADADA;*/ + -moz-box-shadow: 0px 5px 7px #DADADA; + -webkit-box-shadow: 0px 5px 7px #DADADA; + -o-box-shadow: 0px 5px 7px #DADADA; + box-shadow: 0px 5px 7px #DADADA; +} + +.vpc-chart li.tier .loading-overlay { + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} + +.vpc-chart li.tier .connect-line { + position: absolute; + width: 28px; + height: 3px; + background: #CCCCCC 0px -8px; + /*+placement:shift -29px 49px;*/ + position: relative; + left: -29px; + top: 49px; + position: absolute; +} + +.vpc-chart li.tier span.title { + color: #FFFFFF; + /*+placement:shift 11px 13px;*/ + position: relative; + left: 11px; + top: 13px; + position: absolute; + font-size: 24px; + /*+text-shadow:1px 2px 2px #000000;*/ + -moz-text-shadow: 1px 2px 2px #000000; + -webkit-text-shadow: 1px 2px 2px #000000; + -o-text-shadow: 1px 2px 2px #000000; + text-shadow: 1px 2px 2px #000000; +} + +.vpc-chart li.tier span.cidr { + /*+placement:shift 12px 46px;*/ + position: relative; + left: 12px; + top: 46px; + position: absolute; + font-size: 14px; + /*+text-shadow:0px -1px 1px #343E4C;*/ + -moz-text-shadow: 0px -1px 1px #343E4C; + -webkit-text-shadow: 0px -1px 1px #343E4C; + -o-text-shadow: 0px -1px 1px #343E4C; + text-shadow: 0px -1px 1px #343E4C; + color: #FFFFFF; +} + +.vpc-chart li.tier .actions { + width: 258px; + height: 35px; + background: #CCC; + /*+border-radius:0 0 4px 4px;*/ + -moz-border-radius: 0 0 4px 4px; + -webkit-border-radius: 0 0 4px 4px; + -khtml-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; + /*+placement:shift -1px 71px;*/ + position: relative; + left: -1px; + top: 71px; + position: absolute; + /*+box-shadow:inset 0px 1px #FFFFFF;*/ + -moz-box-shadow: inset 0px 1px #FFFFFF; + -webkit-box-shadow: inset 0px 1px #FFFFFF; + -o-box-shadow: inset 0px 1px #FFFFFF; + box-shadow: inset 0px 1px #FFFFFF; + border: 1px solid #808080; + border-top: 1px solid #4C545E; + position: absolute; +} + +.vpc-chart li.tier .actions .action { + cursor: pointer; + float: left; + width: 50px; + height: 24px; + text-align: center; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + margin: 4px 0px 4px 4px; + border: 1px solid #909090; + color: #4B637A; + font-weight: bold; + /*+text-shadow:0px 1px 1px #FFFFFF;*/ + -moz-text-shadow: 0px 1px 1px #FFFFFF; + -webkit-text-shadow: 0px 1px 1px #FFFFFF; + -o-text-shadow: 0px 1px 1px #FFFFFF; + text-shadow: 0px 1px 1px #FFFFFF; + background: url(../images/bg-gradients.png) 0px -2533px; +} + +.vpc-chart li.tier .actions .action.disabled, +.vpc-chart li.tier .actions .action.disabled:hover { + color: #9D9D9D; + background: #CFCFCF; + /*+text-shadow:none;*/ + -moz-text-shadow: none; + -webkit-text-shadow: none; + -o-text-shadow: none; + text-shadow: none; + border-color: #B5B5B5; + cursor: not-allowed; + /*+box-shadow:none;*/ + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; +} + +.vpc-chart li.tier .actions .action:hover { + border: 1px solid #7A8B9A; + background-position: 0px -106px; + color: #5B7A96; + /*+box-shadow:inset 1px 2px 4px #808080;*/ + -moz-box-shadow: inset 1px 2px 4px #808080; + -webkit-box-shadow: inset 1px 2px 4px #808080; + -o-box-shadow: inset 1px 2px 4px #808080; + box-shadow: inset 1px 2px 4px #808080; +} + +.vpc-chart li.tier .actions .action span.label { + /*+placement:shift 1px 3px;*/ + position: relative; + left: 1px; + top: 3px; + font-size: 11px; +} + +.vpc-chart li.tier .actions .action.remove, +.vpc-chart li.tier .actions .action.remove:hover { + background: none; + width: 30px; + padding: 0; + float: right; + border: none; + /*+placement:shift -3px -2px;*/ + position: relative; + left: -3px; + top: -2px; + /*+box-shadow:none;*/ + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; +} + +.vpc-chart li.tier .action span.icon { + background-image: url(../images/sprites.png); + cursor: pointer; + width: 37px; + height: 23px; + float: left; + /*+placement:shift 1px 3px;*/ + position: relative; + left: 1px; + top: 3px; +} + +.vpc-chart li.tier .vm-count { + font-size: 23px; + left: 134px; + top: 3px; + position: absolute; + color: #FFFFFF; + /*+text-shadow:1px 2px 2px #000000;*/ + -moz-text-shadow: 1px 2px 2px #000000; + -webkit-text-shadow: 1px 2px 2px #000000; + -o-text-shadow: 1px 2px 2px #000000; + text-shadow: 1px 2px 2px #000000; + cursor: pointer; + display: block; + padding: 5px; + text-align: center; + width: 100px; + border: 1px solid transparent; + margin: 4px; +} + +.vpc-chart li.tier .vm-count:hover { + border-radius: 4px; + border: 1px solid #4C545E; + background: url(../images/bg-gradients.png) 0px -2751px; +} + +.vpc-chart li.tier .vm-count .total { + padding-right: 4px; + font-size: 24px; +} + +.vpc-chart li.tier.placeholder { + background: #ECECEC; + border: dotted #ACACAC; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + /*+box-shadow:none;*/ + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + cursor: pointer; +} + +.vpc-chart li.tier.placeholder:hover { + background: #D3D3D3; + /*+box-shadow:0px 2px 8px #A7A7A7;*/ + -moz-box-shadow: 0px 2px 8px #A7A7A7; + -webkit-box-shadow: 0px 2px 8px #A7A7A7; + -o-box-shadow: 0px 2px 8px #A7A7A7; + box-shadow: 0px 2px 8px #A7A7A7; +} + +.vpc-chart li.tier.placeholder span { + top: 40px; + left: 66px; + color: #9F9F9F; + /*+text-shadow:none;*/ + -moz-text-shadow: none; + -webkit-text-shadow: none; + -o-text-shadow: none; + text-shadow: none; +} + +.vpc-chart li.tier.placeholder:hover span { + color: #000000; + /*+text-shadow:0px 0px 7px #FFFFFF;*/ + -moz-text-shadow: 0px 0px 7px #FFFFFF; + -webkit-text-shadow: 0px 0px 7px #FFFFFF; + -o-text-shadow: 0px 0px 7px #FFFFFF; + text-shadow: 0px 0px 7px #FFFFFF; +} + +.vpc-chart li.tier.virtual-router { + margin: 0px; + width: 222px; + height: 65px; + /*+placement:shift 17px -36px;*/ + position: relative; + left: 17px; + top: -36px; + background-position: 0px -2519px; + border: 1px solid #ADADAD; +} + +.vpc-chart li.tier.virtual-router span { + color: #586E82; + font-size: 18px; + /*+text-shadow:0px 1px 3px #FFFFFF;*/ + -moz-text-shadow: 0px 1px 3px #FFFFFF; + -webkit-text-shadow: 0px 1px 3px #FFFFFF; + -o-text-shadow: 0px 1px 3px #FFFFFF; + text-shadow: 0px 1px 3px #FFFFFF; + /*+placement:shift 53px 22px;*/ + position: relative; + left: 53px; + top: 22px; +} + +.vpc-chart li.tier.virtual-router .connect-line { + /*+placement:shift -47px 14px;*/ + position: relative; + left: -47px; + top: 14px; + width: 46px; +} + +/*Configure ACL dialog*/ +.ui-dialog.configure-acl { +} + +.ui-dialog.configure-acl .ui-dialog-buttonpane { + /*+placement:shift 709px -2px;*/ + position: relative; + left: 709px; + top: -2px; +} + +.ui-dialog.configure-acl .multi-edit .data { + width: 807px; + height: 370px; + overflow: auto; +} + /*Action icons*/ .action.edit .icon { background-position: 1px -1px; @@ -8974,13 +9417,15 @@ div.panel.ui-dialog div.list-view div.fixed-header { .create .icon, .createTemplate .icon, -.enableSwift .icon { +.enableSwift .icon, +.addVM .icon { background-position: -69px -63px; } .create:hover .icon, .createTemplate:hover .icon, -.enableSwift:hover .icon { +.enableSwift:hover .icon, +.addVM:hover .icon { background-position: -69px -645px; } @@ -9042,11 +9487,13 @@ div.panel.ui-dialog div.list-view div.fixed-header { background-position: -167px -648px; } -.generateKeys .icon { +.generateKeys .icon, +.networkACL .icon { background-position: -167px -95px; } -.generateKeys:hover .icon { +.generateKeys:hover .icon, +.networkACL:hover .icon { background-position: -167px -677px; } diff --git a/ui/images/bg-gradients.png b/ui/images/bg-gradients.png index 2ef74540bbf..52016f0cf48 100644 Binary files a/ui/images/bg-gradients.png and b/ui/images/bg-gradients.png differ diff --git a/ui/images/sprites.png b/ui/images/sprites.png index 86437fc25e2..71674d13b77 100644 Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ diff --git a/ui/index.jsp b/ui/index.jsp index d36b019c922..d2381d54bdc 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -1158,6 +1158,7 @@
Alert 1

Alert 1

+

Alert 1

@@ -1628,11 +1629,14 @@ + + + diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 16a058ad400..9b565c62d90 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -86,6 +86,15 @@ password: { label: 'label.password', validation: { required: true }, + isPassword: true, + id: 'password' + }, + 'password-confirm': { + label: 'label.confirm.password', + validation: { + required: true, + equalTo: '#password' + }, isPassword: true }, email: { @@ -501,7 +510,8 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { @@ -570,7 +580,7 @@ var accountObj = json.listaccountsresponse.account[0]; $.ajax({ - url: createURL("listResourceLimits&domainid=" + accountObj.domainid + "&account=" + accountObj.name), + url: createURL("listResourceLimits&domainid=" + accountObj.domainid + "&account=" + todb(accountObj.name)), dataType: "json", success: function(json) { var limits = json.listresourcelimitsresponse.resourcelimit; @@ -639,7 +649,7 @@ var accountObj = args.context.accounts[0]; if(isAdmin() || isDomainAdmin()) { $.ajax({ - url: createURL("listUsers&domainid=" + accountObj.domainid + "&account=" + accountObj.name + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL("listUsers&domainid=" + accountObj.domainid + "&account=" + todb(accountObj.name) + "&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", success: function(json) { args.response.success({ @@ -683,7 +693,16 @@ password: { label: 'label.password', isPassword: true, - validation: { required: true } + validation: { required: true }, + id: 'password' + }, + 'password-confirm': { + label: 'label.confirm.password', + validation: { + required: true, + equalTo: '#password' + }, + isPassword: true }, email: { label: 'label.email', @@ -730,7 +749,7 @@ array1.push("&timezone=" + todb(args.data.timezone)); array1.push("&domainid=" + accountObj.domainid); - array1.push("&account=" + accountObj.name); + array1.push("&account=" + todb(accountObj.name)); array1.push("&accounttype=" + accountObj.accounttype); $.ajax({ @@ -793,8 +812,17 @@ newPassword: { label: 'label.new.password', isPassword: true, - validation: { required: true } - } + validation: { required: true }, + id: 'newPassword' + }, + 'password-confirm': { + label: 'label.confirm.password', + validation: { + required: true, + equalTo: '#newPassword' + }, + isPassword: true + } } }, action: function(args) { @@ -948,7 +976,8 @@ { username: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { @@ -966,15 +995,18 @@ domain: { label: 'label.domain' }, email: { label: 'label.email', - isEditable: true + isEditable: true, + validation: { required: true, email: true } }, firstname: { label: 'label.first.name', - isEditable: true + isEditable: true, + validation: { required: true } }, lastname: { label: 'label.last.name', - isEditable: true + isEditable: true, + validation: { required: true } }, timezone: { label: 'label.timezone', diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 1ea0b169212..809faa56971 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -62,14 +62,31 @@ dataType: 'json', cache: false, error: function(data) { - cloudStack.dialog.notice({ message: parseXMLHttpResponse(data) }); + var clickAction = false; + if (isValidJsonString(data.responseText)) { + var json = JSON.parse(data.responseText); + if (json != null) { + var property; + for(property in json) {} + var errorObj = json[property]; + if(errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature") { + clickAction = function() { + $('#user-options a').eq(0).trigger('click'); + }; + } + } + } + cloudStack.dialog.notice({ message: parseXMLHttpResponse(data), clickAction: clickAction }); }, - beforeSend: function(XMLHttpRequest) { + beforeSend: function(XMLHttpRequest) { if (g_mySession == $.cookie("JSESSIONID")) { return true; } else { - cloudStack.dialog.notice({ message: _l('label.session.expired') }); + var clickAction = function() { + $('#user-options a').eq(0).trigger('click'); + }; + cloudStack.dialog.notice({ message: _l('label.session.expired'), clickAction: clickAction }); return false; } } @@ -132,6 +149,8 @@ g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects; $.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 }); + + g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion; userValid = true; }, @@ -243,6 +262,8 @@ g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects; $.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 }); + + g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion; args.response.success({ data: { diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index fc1b3a4c3cd..7cc12ac447d 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -281,14 +281,16 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { id: { label: 'label.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, storagetype: { label: 'label.storage.type' }, cpunumber: { label: 'label.num.cpu.cores' }, @@ -611,14 +613,16 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { id: { label: 'label.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, systemvmtype: { label: 'label.system.vm.type', @@ -907,14 +911,16 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { id: { label: 'label.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, iscustomized: { label: 'label.custom.disk.size', @@ -1697,14 +1703,16 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { id: { label: 'label.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, state: { label: 'label.state' }, guestiptype: { diff --git a/ui/scripts/dashboard.js b/ui/scripts/dashboard.js index 7a7df08c4df..07581779d45 100644 --- a/ui/scripts/dashboard.js +++ b/ui/scripts/dashboard.js @@ -202,7 +202,8 @@ alerts: $.map(alerts, function(alert) { return { name: cloudStack.converters.toAlertType(alert.type), - description: alert.description + description: alert.description, + sent: cloudStack.converters.toLocalDate(alert.sent) }; }) })); diff --git a/ui/scripts/domains.js b/ui/scripts/domains.js index 7fc67003eba..bc24492aff2 100644 --- a/ui/scripts/domains.js +++ b/ui/scripts/domains.js @@ -168,6 +168,10 @@ success: function(json) { var item = json.createdomainresponse.domain; args.response.success({data: item}); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); } }); }, diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js new file mode 100644 index 00000000000..9d4a151f086 --- /dev/null +++ b/ui/scripts/instanceWizard.js @@ -0,0 +1,523 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +(function($, cloudStack) { + var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community + var selectedZoneObj, selectedTemplateObj, selectedHypervisor, selectedDiskOfferingObj; + var step5ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group' + + cloudStack.instanceWizard = { + maxDiskOfferingSize: function() { + return g_capabilities.customdiskofferingmaxsize; + }, + steps: [ + // Step 1: Setup + function(args) { + $.ajax({ + url: createURL("listZones&available=true"), + dataType: "json", + async: false, + success: function(json) { + zoneObjs = json.listzonesresponse.zone; + args.response.success({ data: {zones: zoneObjs}}); + } + }); + }, + + // Step 2: Select template + function(args) { + $(zoneObjs).each(function(){ + if(this.id == args.currentData.zoneid) { + selectedZoneObj = this; + return false; //break the $.each() loop + } + }); + if(selectedZoneObj == null) { + alert("error: can't find matched zone object"); + return; + } + + $.ajax({ + url: createURL("listHypervisors&zoneid="+args.currentData.zoneid), + dataType: "json", + async: false, + success: function(json) { + hypervisorObjs = json.listhypervisorsresponse.hypervisor; + } + }); + + //***** get templates/ISOs (begin) ***** + var selectedTemplate = args.currentData['select-template']; + if (selectedTemplate == 'select-template') { + var hypervisorArray = []; + $(hypervisorObjs).each(function(index, item) { + hypervisorArray.push(item.name); + }); + + $.ajax({ + url: createURL("listTemplates&templatefilter=featured&zoneid="+args.currentData.zoneid), + dataType: "json", + async: false, + success: function(json) { + featuredTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { + if($.inArray(item.hypervisor, hypervisorArray) > -1) + return true; + }); + } + }); + $.ajax({ + url: createURL("listTemplates&templatefilter=community&zoneid="+args.currentData.zoneid), + dataType: "json", + async: false, + success: function(json) { + communityTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { + if($.inArray(item.hypervisor, hypervisorArray) > -1) + return true; + }); + } + }); + $.ajax({ + url: createURL("listTemplates&templatefilter=selfexecutable&zoneid="+args.currentData.zoneid), + dataType: "json", + async: false, + success: function(json) { + myTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { + if($.inArray(item.hypervisor, hypervisorArray) > -1) + return true; + }); + } + }); + } else if (selectedTemplate == 'select-iso') { + $.ajax({ + url: createURL("listIsos&isofilter=featured&zoneid=" + args.currentData.zoneid + "&bootable=true"), + dataType: "json", + async: false, + success: function(json) { + featuredIsoObjs = json.listisosresponse.iso; + } + }); + $.ajax({ + url: createURL("listIsos&isofilter=community&zoneid=" + args.currentData.zoneid + "&bootable=true"), + dataType: "json", + async: false, + success: function(json) { + communityIsoObjs = json.listisosresponse.iso; + } + }); + $.ajax({ + url: createURL("listIsos&isofilter=selfexecutable&zoneid=" + args.currentData.zoneid + "&bootable=true"), + dataType: "json", + async: false, + success: function(json) { + myIsoObjs = json.listisosresponse.iso; + } + }); + } + //***** get templates/ISOs (end) ***** + + + var templatesObj = {}; + if (selectedTemplate == 'select-template') { + templatesObj = { + featuredtemplates: featuredTemplateObjs, + communitytemplates: communityTemplateObjs, + mytemplates: myTemplateObjs + } + } else if (selectedTemplate == 'select-iso') { + templatesObj = { + featuredisos: featuredIsoObjs, + communityisos: communityIsoObjs, + myisos: myIsoObjs + } + } + args.response.success({ + hypervisor: { + idField: 'name', + nameField: 'name' + }, + data: { + templates: templatesObj, + hypervisors: hypervisorObjs + } + }); + }, + + // Step 3: Service offering + function(args) { + if(args.currentData["select-template"] == "select-template") { + if(featuredTemplateObjs != null && featuredTemplateObjs.length > 0) { + for(var i=0; i < featuredTemplateObjs.length; i++) { + if(featuredTemplateObjs[i].id == args.currentData.templateid) { + selectedTemplateObj = featuredTemplateObjs[i]; + break; + } + } + } + if(selectedTemplateObj == null) { + if(communityTemplateObjs != null && communityTemplateObjs.length > 0) { + for(var i=0; i < communityTemplateObjs.length; i++) { + if(communityTemplateObjs[i].id == args.currentData.templateid) { + selectedTemplateObj = communityTemplateObjs[i]; + break; + } + } + } + } + if(selectedTemplateObj == null) { + if(myTemplateObjs != null && myTemplateObjs.length > 0) { + for(var i=0; i < myTemplateObjs.length; i++) { + if(myTemplateObjs[i].id == args.currentData.templateid) { + selectedTemplateObj = myTemplateObjs[i]; + break; + } + } + } + } + if(selectedTemplateObj == null) + alert("unable to find matched template object"); + else + selectedHypervisor = selectedTemplateObj.hypervisor; + } + else { //(args.currentData["select-template"] == "select-iso" + selectedHypervisor = args.currentData.hypervisorid; + } + + $.ajax({ + url: createURL("listServiceOfferings&issystem=false"), + dataType: "json", + async: true, + success: function(json) { + serviceOfferingObjs = json.listserviceofferingsresponse.serviceoffering; + args.response.success({ + data: {serviceOfferings: serviceOfferingObjs} + }); + } + }); + }, + + // Step 4: Data disk offering + function(args) { + var isRequred = (args.currentData["select-template"] == "select-iso"? true: false); + $.ajax({ + url: createURL("listDiskOfferings"), + dataType: "json", + async: true, + success: function(json) { + diskOfferingObjs = json.listdiskofferingsresponse.diskoffering; + args.response.success({ + required: isRequred, + customFlag: 'iscustomized', // Field determines if custom slider is shown + data: {diskOfferings: diskOfferingObjs} + }); + } + }); + }, + + // Step 5: Network + function(args) { + if(diskOfferingObjs != null && diskOfferingObjs.length > 0) { + for(var i=0; i < diskOfferingObjs.length; i++) { + if(diskOfferingObjs[i].id == args.currentData.diskofferingid) { + selectedDiskOfferingObj = diskOfferingObjs[i]; + break; + } + } + } + + if (selectedZoneObj.networktype == "Advanced") { //Advanced zone. Show network list. + step5ContainerType = 'select-network'; + } + else { //Basic zone. Show securigy group list or nothing(when no SecurityGroup service in guest network) + var includingSecurityGroupService = false; + $.ajax({ + url: createURL("listNetworks&trafficType=Guest&zoneId=" + selectedZoneObj.id), + dataType: "json", + async: false, + success: function(json) { + //basic zone should have only one guest network returned in this API call + var items = json.listnetworksresponse.network; + if(items != null && items.length > 0) { + var networkObj = items[0]; //basic zone has only one guest network + var serviceObjArray = networkObj.service; + for(var k = 0; k < serviceObjArray.length; k++) { + if(serviceObjArray[k].name == "SecurityGroup") { + includingSecurityGroupService = true; + break; + } + } + } + } + }); + + if(includingSecurityGroupService == false || selectedHypervisor == "VMware") { + step5ContainerType = 'nothing-to-select'; + } + else { + step5ContainerType = 'select-security-group'; + } + } + + //step5ContainerType = 'nothing-to-select'; //for testing only, comment it out before checking in + if(step5ContainerType == 'select-network') { + var defaultNetworkArray = [], optionalNetworkArray = []; + var networkData = { + zoneId: args.currentData.zoneid + }; + + if (!(cloudStack.context.projects && cloudStack.context.projects[0])) { + networkData.domainid = g_domainid; + networkData.account = g_account; + } + + var networkObjs; + $.ajax({ + url: createURL('listNetworks'), + data: networkData, + dataType: "json", + async: false, + success: function(json) { + networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : []; + } + }); + + + var apiCmd = "listNetworkOfferings&guestiptype=Isolated&supportedServices=sourceNat&state=Enabled&specifyvlan=false&zoneid=" + args.currentData.zoneid ; + var array1 = []; + var guestTrafficTypeTotal = 0; + + $.ajax({ + url: createURL(apiCmd + array1.join("")), //get the network offering for isolated network with sourceNat + dataType: "json", + async: false, + success: function(json) { + networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; + } + }); + //get network offerings (end) *** + + + args.response.success({ + type: 'select-network', + data: { + myNetworks: [], //not used any more + sharedNetworks: networkObjs, + securityGroups: [], + networkOfferings: networkOfferingObjs + } + }); + } + + else if(step5ContainerType == 'select-security-group') { + var securityGroupArray = []; + var data = { + domainid: g_domainid, + account: g_account + }; + + $.ajax({ + url: createURL("listSecurityGroups"), + dataType: "json", + async: false, + data: cloudStack.context.projects ? {} : data, + success: function(json) { + var items = json.listsecuritygroupsresponse.securitygroup; + if (items != null && items.length > 0) { + for (var i = 0; i < items.length; i++) { + if(items[i].name != "default") //exclude default security group because it is always applied + securityGroupArray.push(items[i]); + } + } + } + }); + args.response.success({ + type: 'select-security-group', + data: { + myNetworks: [], //not used any more + sharedNetworks: [], + securityGroups: securityGroupArray, + networkOfferings: [] + } + }); + } + + else if(step5ContainerType == 'nothing-to-select') { + args.response.success({ + type: 'nothing-to-select', + data: { + myNetworks: [], //not used any more + sharedNetworks: [], + securityGroups: [], + networkOfferings: [] + } + }); + } + + }, + + // Step 6: Review + function(args) { + return false; + } + ], + action: function(args) { +/* +var isValid = true; +isValid &= validateString("Name", $thisPopup.find("#wizard_vm_name"), $thisPopup.find("#wizard_vm_name_errormsg"), true); //optional +isValid &= validateString("Group", $thisPopup.find("#wizard_vm_group"), $thisPopup.find("#wizard_vm_group_errormsg"), true); //optional +if (!isValid) +return; +*/ + + // Create a new VM!!!! + var array1 = []; + + //step 1 : select zone + array1.push("&zoneId=" + args.data.zoneid); + + //step 2: select template + array1.push("&templateId=" + args.data.templateid); + array1.push("&hypervisor=" + selectedHypervisor); + + //step 3: select service offering + array1.push("&serviceOfferingId=" + args.data.serviceofferingid); + + //step 4: select disk offering + if(args.data.diskofferingid != null && args.data.diskofferingid != "0") { + array1.push("&diskOfferingId=" + args.data.diskofferingid); + if(selectedDiskOfferingObj.iscustomized == true) + array1.push("&size=" + args.data.size); + } + + //step 5: select network + if (step5ContainerType == 'select-network') { + var array2 = []; + var defaultNetworkId = args.data.defaultNetwork; //args.data.defaultNetwork might be equal to string "new-network" or a network ID + + var checkedNetworkIdArray; + if(typeof(args.data["my-networks"]) == "object" && args.data["my-networks"].length != null) { //args.data["my-networks"] is an array of string, e.g. ["203", "202"], + checkedNetworkIdArray = args.data["my-networks"]; + } + else if(typeof(args.data["my-networks"]) == "string" && args.data["my-networks"].length > 0) { //args.data["my-networks"] is a string, e.g. "202" + checkedNetworkIdArray = []; + checkedNetworkIdArray.push(args.data["my-networks"]); + } + else { // typeof(args.data["my-networks"]) == null + checkedNetworkIdArray = []; + } + + //create new network starts here + if(args.data["new-network"] == "create-new-network") { + var isCreateNetworkSuccessful = true; + $.ajax({ + url: createURL("createNetwork&networkOfferingId="+args.data["new-network-networkofferingid"]+"&name="+todb(args.data["new-network-name"])+"&displayText="+todb(args.data["new-network-name"])+"&zoneId="+selectedZoneObj.id), + dataType: "json", + async: false, + success: function(json) { + newNetwork = json.createnetworkresponse.network; + checkedNetworkIdArray.push(newNetwork.id); + if(defaultNetworkId == "new-network") + defaultNetworkId = newNetwork.id; + }, + error: function(XMLHttpResponse) { + isCreateNetworkSuccessful = false; + var errorMsg = "Failed to create new network, unable to proceed to deploy VM. Error: " + parseXMLHttpResponse(XMLHttpResponse); + //alert(errorMsg); + args.response.error(errorMsg); //args.response.error(errorMsg) here doesn't show errorMsg. Waiting for Brian to fix it. use alert(errorMsg) to show errorMsg for now. + } + }); + if(isCreateNetworkSuccessful == false) + return; + } + //create new network ends here + + //add default network first + if(defaultNetworkId != null && defaultNetworkId.length > 0) + array2.push(defaultNetworkId); + + //then, add other checked networks + if(checkedNetworkIdArray.length > 0) { + for(var i=0; i < checkedNetworkIdArray.length; i++) { + if(checkedNetworkIdArray[i] != defaultNetworkId) //exclude defaultNetworkId that has been added to array2 + array2.push(checkedNetworkIdArray[i]); + } + } + + array1.push("&networkIds=" + array2.join(",")); + } + else if (step5ContainerType == 'select-security-group') { + var checkedSecurityGroupIdArray; + if(typeof(args.data["security-groups"]) == "object" && args.data["security-groups"].length != null) { //args.data["security-groups"] is an array of string, e.g. ["2375f8cc-8a73-4b8d-9b26-50885a25ffe0", "27c60d2a-de7f-4bb7-96e5-a602cec681df","c6301d77-99b5-4e8a-85e2-3ea2ab31c342"], + checkedSecurityGroupIdArray = args.data["security-groups"]; + } + else if(typeof(args.data["security-groups"]) == "string" && args.data["security-groups"].length > 0) { //args.data["security-groups"] is a string, e.g. "2375f8cc-8a73-4b8d-9b26-50885a25ffe0" + checkedSecurityGroupIdArray = []; + checkedSecurityGroupIdArray.push(args.data["security-groups"]); + } + else { // typeof(args.data["security-groups"]) == null + checkedSecurityGroupIdArray = []; + } + + if(checkedSecurityGroupIdArray.length > 0) + array1.push("&securitygroupids=" + checkedSecurityGroupIdArray.join(",")); + } + + var displayname = args.data.displayname; + if(displayname != null && displayname.length > 0) { + array1.push("&displayname="+todb(displayname)); + array1.push("&name="+todb(displayname)); + } + + var group = args.data.groupname; + if (group != null && group.length > 0) + array1.push("&group="+todb(group)); + + //array1.push("&startVm=false"); //for testing only, comment it out before checking in + + $.ajax({ + url: createURL("deployVirtualMachine"+array1.join("")), + dataType: "json", + success: function(json) { + var jid = json.deployvirtualmachineresponse.jobid; + var vmid = json.deployvirtualmachineresponse.id; + args.response.success( + {_custom: + {jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.virtualmachine; + if (item.password != null) + alert("Password of new VM " + item.displayname + " is " + item.password); + return item; + }, + getActionFilter: function() { + return cloudStack.actionFilter.vmActionFilter; + }, + getUpdatedItemWhenAsyncJobFails: function() { + var item; + $.ajax({ + url: createURL("listVirtualMachines&id="+vmid), + dataType: "json", + async: false, + success: function(json) { + item = json.listvirtualmachinesresponse.virtualmachine[0]; + } + }); + return item; + } + } + } + ); + }, + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); //wait for Brian to implement + } + }); + } + }; +}(jQuery, cloudStack)); diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index c51f88977a3..4b17c4ce285 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -11,11 +11,6 @@ // // Automatically generated by addcopyright.py at 04/03/2012 (function($, cloudStack) { - - var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, communityIsoObjs, myIsoObjs, serviceOfferingObjs, diskOfferingObjs, networkOfferingObjs, physicalNetworkObjs; - var selectedZoneObj, selectedTemplateObj, selectedHypervisor, selectedDiskOfferingObj; - var step5ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group' - cloudStack.sections.instances = { title: 'label.instances', id: 'instances', @@ -65,492 +60,7 @@ label: 'label.vm.add', action: { - custom: cloudStack.instanceWizard({ - maxDiskOfferingSize: function() { - return g_capabilities.customdiskofferingmaxsize; - }, - steps: [ - // Step 1: Setup - function(args) { - $.ajax({ - url: createURL("listZones&available=true"), - dataType: "json", - async: false, - success: function(json) { - zoneObjs = json.listzonesresponse.zone; - args.response.success({ data: {zones: zoneObjs}}); - } - }); - }, - - // Step 2: Select template - function(args) { - $(zoneObjs).each(function(){ - if(this.id == args.currentData.zoneid) { - selectedZoneObj = this; - return false; //break the $.each() loop - } - }); - if(selectedZoneObj == null) { - alert("error: can't find matched zone object"); - return; - } - - $.ajax({ - url: createURL("listHypervisors&zoneid="+args.currentData.zoneid), - dataType: "json", - async: false, - success: function(json) { - hypervisorObjs = json.listhypervisorsresponse.hypervisor; - } - }); - - - //***** get templates/ISOs (begin) ***** - var hypervisorArray = []; - $(hypervisorObjs).each(function(index, item) { - hypervisorArray.push(item.name); - }); - - $.ajax({ - url: createURL("listTemplates&templatefilter=featured&zoneid="+args.currentData.zoneid), - dataType: "json", - async: false, - success: function(json) { - featuredTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { - if($.inArray(item.hypervisor, hypervisorArray) > -1) - return true; - }); - } - }); - $.ajax({ - url: createURL("listTemplates&templatefilter=community&zoneid="+args.currentData.zoneid), - dataType: "json", - async: false, - success: function(json) { - communityTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { - if($.inArray(item.hypervisor, hypervisorArray) > -1) - return true; - }); - } - }); - $.ajax({ - url: createURL("listTemplates&templatefilter=selfexecutable&zoneid="+args.currentData.zoneid), - dataType: "json", - async: false, - success: function(json) { - myTemplateObjs = $.grep(json.listtemplatesresponse.template, function(item, index) { - if($.inArray(item.hypervisor, hypervisorArray) > -1) - return true; - }); - } - }); - - $.ajax({ - url: createURL("listIsos&isofilter=featured&zoneid=" + args.currentData.zoneid + "&bootable=true"), - dataType: "json", - async: false, - success: function(json) { - featuredIsoObjs = json.listisosresponse.iso; - } - }); - $.ajax({ - url: createURL("listIsos&isofilter=community&zoneid=" + args.currentData.zoneid + "&bootable=true"), - dataType: "json", - async: false, - success: function(json) { - communityIsoObjs = json.listisosresponse.iso; - } - }); - $.ajax({ - url: createURL("listIsos&isofilter=selfexecutable&zoneid=" + args.currentData.zoneid + "&bootable=true"), - dataType: "json", - async: false, - success: function(json) { - myIsoObjs = json.listisosresponse.iso; - } - }); - //***** get templates/ISOs (end) ***** - - - args.response.success({ - hypervisor: { - idField: 'name', - nameField: 'name' - }, - data: { - templates: { - featuredtemplates: featuredTemplateObjs, - communitytemplates: communityTemplateObjs, - mytemplates: myTemplateObjs, - - featuredisos: featuredIsoObjs, - communityisos: communityIsoObjs, - myisos: myIsoObjs - }, - hypervisors: hypervisorObjs - } - }); - }, - - // Step 3: Service offering - function(args) { - if(args.currentData["select-template"] == "select-template") { - if(featuredTemplateObjs != null && featuredTemplateObjs.length > 0) { - for(var i=0; i < featuredTemplateObjs.length; i++) { - if(featuredTemplateObjs[i].id == args.currentData.templateid) { - selectedTemplateObj = featuredTemplateObjs[i]; - break; - } - } - } - if(selectedTemplateObj == null) { - if(communityTemplateObjs != null && communityTemplateObjs.length > 0) { - for(var i=0; i < communityTemplateObjs.length; i++) { - if(communityTemplateObjs[i].id == args.currentData.templateid) { - selectedTemplateObj = communityTemplateObjs[i]; - break; - } - } - } - } - if(selectedTemplateObj == null) { - if(myTemplateObjs != null && myTemplateObjs.length > 0) { - for(var i=0; i < myTemplateObjs.length; i++) { - if(myTemplateObjs[i].id == args.currentData.templateid) { - selectedTemplateObj = myTemplateObjs[i]; - break; - } - } - } - } - if(selectedTemplateObj == null) - alert("unable to find matched template object"); - else - selectedHypervisor = selectedTemplateObj.hypervisor; - } - else { //(args.currentData["select-template"] == "select-iso" - selectedHypervisor = args.currentData.hypervisorid; - } - - $.ajax({ - url: createURL("listServiceOfferings&issystem=false"), - dataType: "json", - async: true, - success: function(json) { - serviceOfferingObjs = json.listserviceofferingsresponse.serviceoffering; - args.response.success({ - data: {serviceOfferings: serviceOfferingObjs} - }); - } - }); - }, - - // Step 4: Data disk offering - function(args) { - var isRequred = (args.currentData["select-template"] == "select-iso"? true: false); - $.ajax({ - url: createURL("listDiskOfferings"), - dataType: "json", - async: true, - success: function(json) { - diskOfferingObjs = json.listdiskofferingsresponse.diskoffering; - args.response.success({ - required: isRequred, - customFlag: 'iscustomized', // Field determines if custom slider is shown - data: {diskOfferings: diskOfferingObjs} - }); - } - }); - }, - - // Step 5: Network - function(args) { - if(diskOfferingObjs != null && diskOfferingObjs.length > 0) { - for(var i=0; i < diskOfferingObjs.length; i++) { - if(diskOfferingObjs[i].id == args.currentData.diskofferingid) { - selectedDiskOfferingObj = diskOfferingObjs[i]; - break; - } - } - } - - if (selectedZoneObj.networktype == "Advanced") { //Advanced zone. Show network list. - step5ContainerType = 'select-network'; - } - else { //Basic zone. Show securigy group list or nothing(when no SecurityGroup service in guest network) - var includingSecurityGroupService = false; - $.ajax({ - url: createURL("listNetworks&trafficType=Guest&zoneId=" + selectedZoneObj.id), - dataType: "json", - async: false, - success: function(json) { - //basic zone should have only one guest network returned in this API call - var items = json.listnetworksresponse.network; - if(items != null && items.length > 0) { - var networkObj = items[0]; //basic zone has only one guest network - var serviceObjArray = networkObj.service; - for(var k = 0; k < serviceObjArray.length; k++) { - if(serviceObjArray[k].name == "SecurityGroup") { - includingSecurityGroupService = true; - break; - } - } - } - } - }); - - if(includingSecurityGroupService == false || selectedHypervisor == "VMware") { - step5ContainerType = 'nothing-to-select'; - } - else { - step5ContainerType = 'select-security-group'; - } - } - - //step5ContainerType = 'nothing-to-select'; //for testing only, comment it out before checking in - if(step5ContainerType == 'select-network') { - var defaultNetworkArray = [], optionalNetworkArray = []; - var networkData = { - zoneId: args.currentData.zoneid - }; - - if (!(cloudStack.context.projects && cloudStack.context.projects[0])) { - networkData.domainid = g_domainid; - networkData.account = g_account; - } - - var networkObjs; - $.ajax({ - url: createURL('listNetworks'), - data: networkData, - dataType: "json", - async: false, - success: function(json) { - networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : []; - } - }); - - - var apiCmd = "listNetworkOfferings&guestiptype=Isolated&supportedServices=sourceNat&state=Enabled&specifyvlan=false&zoneid=" + args.currentData.zoneid ; - var array1 = []; - var guestTrafficTypeTotal = 0; - - $.ajax({ - url: createURL(apiCmd + array1.join("")), //get the network offering for isolated network with sourceNat - dataType: "json", - async: false, - success: function(json) { - networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; - } - }); - //get network offerings (end) *** - - - args.response.success({ - type: 'select-network', - data: { - myNetworks: [], //not used any more - sharedNetworks: networkObjs, - securityGroups: [], - networkOfferings: networkOfferingObjs - } - }); - } - - else if(step5ContainerType == 'select-security-group') { - var securityGroupArray = []; - var data = { - domainid: g_domainid, - account: g_account - }; - - $.ajax({ - url: createURL("listSecurityGroups"), - dataType: "json", - async: false, - data: cloudStack.context.projects ? {} : data, - success: function(json) { - var items = json.listsecuritygroupsresponse.securitygroup; - if (items != null && items.length > 0) { - for (var i = 0; i < items.length; i++) { - if(items[i].name != "default") //exclude default security group because it is always applied - securityGroupArray.push(items[i]); - } - } - } - }); - args.response.success({ - type: 'select-security-group', - data: { - myNetworks: [], //not used any more - sharedNetworks: [], - securityGroups: securityGroupArray, - networkOfferings: [] - } - }); - } - - else if(step5ContainerType == 'nothing-to-select') { - args.response.success({ - type: 'nothing-to-select', - data: { - myNetworks: [], //not used any more - sharedNetworks: [], - securityGroups: [], - networkOfferings: [] - } - }); - } - - }, - - // Step 6: Review - function(args) { - return false; - } - ], - action: function(args) { - /* - var isValid = true; - isValid &= validateString("Name", $thisPopup.find("#wizard_vm_name"), $thisPopup.find("#wizard_vm_name_errormsg"), true); //optional - isValid &= validateString("Group", $thisPopup.find("#wizard_vm_group"), $thisPopup.find("#wizard_vm_group_errormsg"), true); //optional - if (!isValid) - return; - */ - - // Create a new VM!!!! - var array1 = []; - - //step 1 : select zone - array1.push("&zoneId=" + args.data.zoneid); - - //step 2: select template - array1.push("&templateId=" + args.data.templateid); - array1.push("&hypervisor=" + selectedHypervisor); - - //step 3: select service offering - array1.push("&serviceOfferingId=" + args.data.serviceofferingid); - - //step 4: select disk offering - if(args.data.diskofferingid != null && args.data.diskofferingid != "0") { - array1.push("&diskOfferingId=" + args.data.diskofferingid); - if(selectedDiskOfferingObj.iscustomized == true) - array1.push("&size=" + args.data.size); - } - - //step 5: select network - if (step5ContainerType == 'select-network') { - var array2 = []; - var defaultNetworkId = args.data.defaultNetwork; //args.data.defaultNetwork might be equal to string "new-network" or a network ID - - var checkedNetworkIdArray; - if(typeof(args.data["my-networks"]) == "object" && args.data["my-networks"].length != null) { //args.data["my-networks"] is an array of string, e.g. ["203", "202"], - checkedNetworkIdArray = args.data["my-networks"]; - } - else if(typeof(args.data["my-networks"]) == "string" && args.data["my-networks"].length > 0) { //args.data["my-networks"] is a string, e.g. "202" - checkedNetworkIdArray = []; - checkedNetworkIdArray.push(args.data["my-networks"]); - } - else { // typeof(args.data["my-networks"]) == null - checkedNetworkIdArray = []; - } - - //create new network starts here - if(args.data["new-network"] == "create-new-network") { - var isCreateNetworkSuccessful = true; - $.ajax({ - url: createURL("createNetwork&networkOfferingId="+args.data["new-network-networkofferingid"]+"&name="+todb(args.data["new-network-name"])+"&displayText="+todb(args.data["new-network-name"])+"&zoneId="+selectedZoneObj.id), - dataType: "json", - async: false, - success: function(json) { - newNetwork = json.createnetworkresponse.network; - checkedNetworkIdArray.push(newNetwork.id); - if(defaultNetworkId == "new-network") - defaultNetworkId = newNetwork.id; - }, - error: function(XMLHttpResponse) { - isCreateNetworkSuccessful = false; - var errorMsg = "Failed to create new network, unable to proceed to deploy VM. Error: " + parseXMLHttpResponse(XMLHttpResponse); - //alert(errorMsg); - args.response.error(errorMsg); //args.response.error(errorMsg) here doesn't show errorMsg. Waiting for Brian to fix it. use alert(errorMsg) to show errorMsg for now. - } - }); - if(isCreateNetworkSuccessful == false) - return; - } - //create new network ends here - - //add default network first - if(defaultNetworkId != null && defaultNetworkId.length > 0) - array2.push(defaultNetworkId); - - //then, add other checked networks - if(checkedNetworkIdArray.length > 0) { - for(var i=0; i < checkedNetworkIdArray.length; i++) { - if(checkedNetworkIdArray[i] != defaultNetworkId) //exclude defaultNetworkId that has been added to array2 - array2.push(checkedNetworkIdArray[i]); - } - } - - array1.push("&networkIds=" + array2.join(",")); - } - else if (step5ContainerType == 'select-security-group') { - var checkedSecurityGroupIdArray; - if(typeof(args.data["security-groups"]) == "object" && args.data["security-groups"].length != null) { //args.data["security-groups"] is an array of string, e.g. ["2375f8cc-8a73-4b8d-9b26-50885a25ffe0", "27c60d2a-de7f-4bb7-96e5-a602cec681df","c6301d77-99b5-4e8a-85e2-3ea2ab31c342"], - checkedSecurityGroupIdArray = args.data["security-groups"]; - } - else if(typeof(args.data["security-groups"]) == "string" && args.data["security-groups"].length > 0) { //args.data["security-groups"] is a string, e.g. "2375f8cc-8a73-4b8d-9b26-50885a25ffe0" - checkedSecurityGroupIdArray = []; - checkedSecurityGroupIdArray.push(args.data["security-groups"]); - } - else { // typeof(args.data["security-groups"]) == null - checkedSecurityGroupIdArray = []; - } - - if(checkedSecurityGroupIdArray.length > 0) - array1.push("&securitygroupids=" + checkedSecurityGroupIdArray.join(",")); - } - - var displayname = args.data.displayname; - if(displayname != null && displayname.length > 0) { - array1.push("&displayname="+todb(displayname)); - array1.push("&name="+todb(displayname)); - } - - var group = args.data.groupname; - if (group != null && group.length > 0) - array1.push("&group="+todb(group)); - - //array1.push("&startVm=false"); //for testing only, comment it out before checking in - - $.ajax({ - url: createURL("deployVirtualMachine"+array1.join("")), - dataType: "json", - success: function(json) { - var jid = json.deployvirtualmachineresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - var item = json.queryasyncjobresultresponse.jobresult.virtualmachine; - if (item.password != null) - alert("Password of new VM " + item.displayname + " is " + item.password); - return item; - }, - getActionFilter: function() { - return vmActionfilter; - } - } - } - ); - }, - error: function(XMLHttpResponse) { - args.response.error(parseXMLHttpResponse(XMLHttpResponse)); //wait for Brian to implement - } - }); - } - }) + custom: cloudStack.uiCustom.instanceWizard(cloudStack.instanceWizard) }, messages: { @@ -1780,7 +1290,7 @@ } }; - var vmActionfilter = function(args) { + var vmActionfilter = cloudStack.actionFilter.vmActionFilter = function(args) { var jsonObj = args.context.item; var allowedActions = []; diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 1661a8f8421..d0a77dd5ea0 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -173,7 +173,7 @@ } }); - var sectionsToShow = ['networks']; + var sectionsToShow = ['networks', 'vpc', 'siteToSiteVpn']; if(havingSecurityGroupNetwork == true) sectionsToShow.push('securityGroups'); @@ -3101,7 +3101,360 @@ } } } + }, + vpc: { + type: 'select', + title: 'VPC', + id: 'vpc', + listView: { + id: 'vpc', + label: 'VPC', + fields: { + name: { label: 'Name' }, + zone: { label: 'Zone' }, + cidr: { label: 'CIDR' } + }, + dataProvider: function(args) { + args.response.success({ + data: [ + { + name: 'VPC 1', + zone: 'San Jose', + cidr: '0.0.0.0/0', + networkdomain: 'testdomain', + accountdomain: 'testdomain' + }, + { + name: 'VPC 2', + zone: 'San Jose', + cidr: '0.0.0.0/0', + networkdomain: 'testdomain', + accountdomain: 'testdomain' + }, + { + name: 'VPC 3', + zone: 'Cupertino', + cidr: '0.0.0.0/0', + networkdomain: 'testdomain', + accountdomain: 'testdomain' + }, + { + name: 'VPC 4', + zone: 'San Jose', + cidr: '0.0.0.0/0', + networkdomain: 'testdomain', + accountdomain: 'testdomain' + } + ] + }); + }, + actions: { + add: { + label: 'Add VPC', + createForm: { + title: 'Add new VPC', + fields: { + name: { label: 'Name', validation: { required: true } }, + zone: { + label: 'Zone', + validation: { required: true }, + select: function(args) { + args.response.success({ + data: [ + { id: 'zone1', description: 'Zone 1' }, + { id: 'zone2', description: 'Zone 2' }, + { id: 'zone3', description: 'Zone 3' } + ] + }); + } + } + } + }, + messages: { + notification: function(args) { return 'Add new VPC'; } + }, + action: function(args) { + args.response.success(); + }, + notification: { poll: function(args) { args.complete(); } } + }, + editVpc: { + label: 'Edit VPC', + action: { + custom: cloudStack.uiCustom.vpc(cloudStack.vpc) + } + } + } + } + }, + + //site-to-site VPN (begin) + siteToSiteVpn: { + type: 'select', + title: 'site-to-site VPN', + listView: { + id: 'siteToSiteVpn', + label: 'site-to-site VPN', + fields: { + id: { label: 'label.id' }, + s2svpngatewayid: { label: 's2svpngatewayid' }, + s2scustomergatewayid: { label: 's2scustomergatewayid' }, + created: { label: 'label.date', converter: cloudStack.converters.toLocalDate } + }, + dataProvider: function(args) { + var array1 = []; + if(args.filterBy != null) { + if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + $.ajax({ + url: createURL("listVpnConnections&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function(json) { + var items = json.listvpnconnectionsresponse.vpnconnection; + args.response.success({data:items}); + } + }); + }, + + actions: { + add: { + label: 'add site-to-site VPN', + messages: { + notification: function(args) { + return 'add site-to-site VPN'; + } + }, + createForm: { + title: 'add site-to-site VPN', + fields: { + publicipid: { + label: 'label.ip.address', + select: function(args) { + $.ajax({ + url: createURL('listPublicIpAddresses'), + dataType: 'json', + async: true, + success: function(json) { + var items = []; + var objs = json.listpublicipaddressesresponse.publicipaddress; + if(objs != null && objs.length > 0) { + for(var i = 0; i < objs.length; i++) { + items.push({id: objs[i].id, description: objs[i].ipaddress}); + } + } + args.response.success({data: items}); + } + }); + }, + validation: { required: true } + }, + gateway: { + label: 'label.gateway', + validation: { required: true } + }, + cidrlist: { + label: 'CIDR list', + validation: { required: true } + }, + ipsecpsk: { + label: 'IPsec Preshared-Key', + validation: { required: true } + }, + ikepolicy: { + label: 'IKE policy', + select: function(args) { + var items = []; + items.push({id: '3des-md5', description: '3des-md5'}); + items.push({id: 'aes-md5', description: 'aes-md5'}); + items.push({id: 'aes128-md5', description: 'aes128-md5'}); + items.push({id: 'des-md5', description: 'des-md5'}); + items.push({id: '3des-sha1', description: '3des-sha1'}); + items.push({id: 'aes-sha1', description: 'aes-sha1'}); + items.push({id: 'aes128-sha1', description: 'aes128-sha1'}); + items.push({id: 'des-sha1', description: 'des-sha1'}); + args.response.success({data: items}); + } + }, + esppolicy: { + label: 'ESP policy', + select: function(args) { + var items = []; + items.push({id: '3des-md5', description: '3des-md5'}); + items.push({id: 'aes-md5', description: 'aes-md5'}); + items.push({id: 'aes128-md5', description: 'aes128-md5'}); + items.push({id: 'des-md5', description: 'des-md5'}); + items.push({id: '3des-sha1', description: '3des-sha1'}); + items.push({id: 'aes-sha1', description: 'aes-sha1'}); + items.push({id: 'aes128-sha1', description: 'aes128-sha1'}); + items.push({id: 'des-sha1', description: 'des-sha1'}); + args.response.success({data: items}); + } + }, + lifetime: { + label: 'Lifetime of vpn connection (second)', + defaultValue: '86400', + validation: { required: false, number: true } + } + } + }, + action: function(args) { + $.ajax({ + url: createURL('createVpnGateway'), + data: { + publicipid: args.data.publicipid + }, + dataType: 'json', + success: function(json) { + var jid = json.createvpngatewayresponse.jobid; + var createvpngatewayIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobid=" + jid), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(createvpngatewayIntervalID); + if (result.jobstatus == 1) { + var obj = result.jobresult.vpngateway; + var vpngatewayid = obj.id; + + $.ajax({ + url: createURL('createVpnCustomerGateway'), + data: { + gateway: args.data.gateway, + cidrlist: args.data.cidrlist, + ipsecpsk: args.data.ipsecpsk, + ikepolicy: args.data.ikepolicy, + esppolicy: args.data.esppolicy, + lifetime: args.data.lifetime + }, + dataType: 'json', + success: function(json) { + var jid = json.createvpncustomergatewayresponse.jobid; + var createvpncustomergatewayIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobid=" + jid), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(createvpncustomergatewayIntervalID); + if (result.jobstatus == 1) { + var obj = result.jobresult.vpncustomergateway; + var vpncustomergatewayid = obj.id; + + $.ajax({ + url: createURL('createVpnConnection'), + data: { + s2svpngatewayid: vpngatewayid, + s2scustomergatewayid: vpncustomergatewayid + }, + dataType: 'json', + success: function(json) { + var jid = json.createvpnconnectionresponse.jobid; + var createvpnconnectionIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobid=" + jid), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(createvpnconnectionIntervalID); + if (result.jobstatus == 1) { + var obj = result.jobresult.vpnconnection; + } + else if (result.jobstatus == 2) { + alert("Failed to create VPN connection. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("Failed to create VPN connection. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else if (result.jobstatus == 2) { + alert("Failed to create VPN customer gateway. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("Failed to create VPN customer gateway. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else if (result.jobstatus == 2) { + alert("Failed to create VPN gateway. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("Failed to create VPN gateway. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + } + }, + + detailView: { + name: 'label.details', + tabs: { + details: { + title: 'label.details', + fields: [ + { + id: { label: 'label.id' }, + s2svpngatewayid: { label: 's2svpngatewayid' }, + s2scustomergatewayid: { label: 's2scustomergatewayid' }, + created: { label: 'label.date', converter: cloudStack.converters.toLocalDate } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listVpnConnections&id=" + args.context.siteToSiteVpn[0].id), + dataType: "json", + async: true, + success: function(json) { + var item = json.listvpnconnectionsresponse.vpnconnection[0]; + args.response.success({data: item}); + } + }); + } + } + } + } + } } + //site-to-site VPN (end) } }; diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index c0c6f21b3db..1c95928721c 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -21,6 +21,7 @@ var g_timezoneoffset = null; var g_timezone = null; var g_supportELB = null; var g_userPublicTemplateEnabled = "true"; +var g_cloudstackversion = null; //keyboard keycode var keycode_Enter = 13; @@ -81,7 +82,14 @@ var pollAsyncJobResult = function(args) { } else if (result.jobstatus == 2) { // Failed var msg = (result.jobresult.errortext == null)? "": result.jobresult.errortext; - args.error({message: msg}); + if (args._custom.getUpdatedItemWhenAsyncJobFails != null && args._custom.getActionFilter != null) { + args.error({message: msg, updatedData: args._custom.getUpdatedItemWhenAsyncJobFails(), actionFilter: args._custom.getActionFilter()}); + } else if (args._custom.getUpdatedItemWhenAsyncJobFails != null && args._custom.getActionFilter == null) { + args.error({message: msg, updatedData: args._custom.getUpdatedItemWhenAsyncJobFails()}); + } + else { + args.error({message: msg}); + } } } }, diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 37868deaf6f..2cba42bbd5b 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -5818,8 +5818,11 @@ actionFilter: podActionfilter, data:item }); - } - }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); } }, @@ -6180,17 +6183,17 @@ validation: { required: true } }, vsmipaddress: { - label: 'Nexus dvSwitch IP Address', + label: 'Nexus 1000v IP Address', validation: { required: true }, isHidden: false }, vsmusername: { - label: 'Nexus dvSwitch Username', + label: 'Nexus 1000v Username', validation: { required: true }, isHidden: false }, vsmpassword: { - label: 'Nexus dvSwitch Password', + label: 'Nexus 1000v Password', validation: { required: true }, isPassword: true, isHidden: false @@ -7348,7 +7351,8 @@ fields: { name: { label: 'label.name' }, ipaddress: { label: 'label.server' }, - path: { label: 'label.path' } + path: { label: 'label.path' }, + clustername: { label: 'label.cluster'} }, dataProvider: function(args) { @@ -7527,7 +7531,8 @@ //$('li[input_group="nfs"]', $dialogAddPool).show(); $form.find('.form-item[rel=path]').css('display', 'inline-block'); //$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.path"]+":"); - $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:"); + var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); //$('li[input_group="iscsi"]', $dialogAddPool).hide(); $form.find('.form-item[rel=iqn]').hide(); @@ -7549,7 +7554,8 @@ //$('li[input_group="nfs"]', $dialogAddPool).show(); $form.find('.form-item[rel=path]').css('display', 'inline-block'); //$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.path"]+":"); - $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:"); + var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); //$('li[input_group="iscsi"]', $dialogAddPool).hide(); $form.find('.form-item[rel=iqn]').hide(); @@ -7570,8 +7576,9 @@ //$('li[input_group="nfs"]', $dialogAddPool).show(); $form.find('.form-item[rel=path]').css('display', 'inline-block'); - //$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.SR.name"]+":"); - $form.find('.form-item[rel=path]').find(".name").find("label").text("SR Name-Label:"); + //$dialogAddPool.find("#add_pool_path_container").find("label").text(g_dictionary["label.SR.name"]+":"); + var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); + $form.find('.form-item[rel=path]').find(".name").find("label").text("SR Name-Label:").prepend($required); //$('li[input_group="iscsi"]', $dialogAddPool).hide(); $form.find('.form-item[rel=iqn]').hide(); @@ -7652,7 +7659,8 @@ //$('li[input_group="nfs"]', $dialogAddPool).show(); $form.find('.form-item[rel=path]').css('display', 'inline-block'); - $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:"); + var $required = $form.find('.form-item[rel=path]').find(".name").find("label span"); + $form.find('.form-item[rel=path]').find(".name").find("label").text("Path:").prepend($required); //$('li[input_group="iscsi"]', $dialogAddPool).hide(); $form.find('.form-item[rel=iqn]').hide(); @@ -9157,6 +9165,8 @@ dataType: "json", async: false, success: function(json) { + nspMap = {}; //reset + var items = json.listnetworkserviceprovidersresponse.networkserviceprovider; if(items != null) { for(var i = 0; i < items.length; i++) { diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index 8ddcbed89e7..5a13af9fc6f 100644 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -365,9 +365,26 @@ }); var array2 = []; - array2.push("&ispublic=" + (args.data.ispublic=="on")); - array2.push("&isfeatured=" + (args.data.isfeatured=="on")); - array2.push("&isextractable=" + (args.data.isextractable=="on")); + + //array2.push("&ispublic=" + (args.data.ispublic=="on")); + if(args.data.ispublic == "on") + array2.push("&ispublic=true"); + else if(args.data.ispublic == "off") + array2.push("&ispublic=false"); + //if args.data.ispublic is undefined, do not pass ispublic to API call. + + if(args.data.isfeatured == "on") + array2.push("&isfeatured=true"); + else if(args.data.isfeatured == "off") + array2.push("&isfeatured=false"); + //if args.data.isfeatured is undefined, do not pass isfeatured to API call. + + if(args.data.isextractable == "on") + array2.push("&isextractable=true"); + else if(args.data.isextractable == "off") + array2.push("&isextractable=false"); + //if args.data.isextractable is undefined, do not pass isextractable to API call. + $.ajax({ url: createURL("updateTemplatePermissions&id=" + args.context.templates[0].id + "&zoneid=" + args.context.templates[0].zoneid + array2.join("")), dataType: "json", @@ -558,7 +575,8 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { @@ -567,7 +585,8 @@ zoneid: { label: 'label.zone.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, hypervisor: { label: 'label.hypervisor' }, templatetype: { label: 'label.type' }, @@ -585,7 +604,12 @@ isextractable: { label: 'extractable', isBoolean: true, - isEditable: true, + isEditable: function() { + if(isAdmin()) + return true; + else + return false; + }, converter:cloudStack.converters.toBooleanText }, passwordenabled: { @@ -597,13 +621,28 @@ ispublic: { label: 'label.public', isBoolean: true, - isEditable: true, + isEditable: function() { + if(isAdmin()) { + return true; + } + else { + if (g_userPublicTemplateEnabled == "true") + return true; + else + return false; + } + }, converter:cloudStack.converters.toBooleanText }, isfeatured: { label: 'label.featured', isBoolean: true, - isEditable: true, + isEditable: function() { + if(isAdmin()) + return true; + else + return false; + }, converter:cloudStack.converters.toBooleanText }, crossZones: { @@ -1073,7 +1112,8 @@ { name: { label: 'label.name', - isEditable: true + isEditable: true, + validation: { required: true } } }, { @@ -1082,7 +1122,8 @@ zoneid: { label: 'label.zone.id' }, displaytext: { label: 'label.description', - isEditable: true + isEditable: true, + validation: { required: true } }, isready: { label: 'state.Ready', converter:cloudStack.converters.toBooleanText }, status: { label: 'label.status' }, diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index c4980300ca3..28bd39c75b6 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -14,8 +14,10 @@ /** * Instance wizard */ - cloudStack.instanceWizard = function(args) { + cloudStack.uiCustom.instanceWizard = function(args) { return function(listViewArgs) { + var context = listViewArgs.context; + var instanceWizard = function(data) { var $wizard = $('#template').find('div.instance-wizard').clone(); var $progress = $wizard.find('div.progress ul li'); @@ -38,27 +40,32 @@ args.action({ // Populate data + context: context, data: data, response: { success: function(args) { - var $loading = $('.list-view').listView('prependItem', { - data: [ - { - name: data.displayname ? data.displayname : _l('label.new.vm'), - zonename: $wizard.find('select[name=zoneid] option').filter(function() { - return $(this).val() == data.zoneid; - }).html(), - state: 'Creating' - } - ], - actionFilter: function(args) { return []; } - }); + var $listView = $('.list-view.instances'); + + if ($listView.size()) { + var $loading = $('.list-view.instances').listView('prependItem', { + data: [ + { + name: data.displayname ? data.displayname : _l('label.new.vm'), + zonename: $wizard.find('select[name=zoneid] option').filter(function() { + return $(this).val() == data.zoneid; + }).html(), + state: 'Creating' + } + ], + actionFilter: function(args) { return []; } + }); + } listViewArgs.complete({ _custom: args._custom, messageArgs: cloudStack.serializeForm($form), - $item: $loading - }); + $item: $listView.size()? $loading : $('
') + }); close(); }, diff --git a/ui/scripts/ui-custom/vpc.js b/ui/scripts/ui-custom/vpc.js new file mode 100644 index 00000000000..c598c0880a6 --- /dev/null +++ b/ui/scripts/ui-custom/vpc.js @@ -0,0 +1,560 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +(function($, cloudStack) { + var elems = { + vpcConfigureTooltip: function(args) { + var $browser = args.$browser; + var siteToSiteVPN = args.siteToSiteVPN; + var links = { + 'ip-addresses': 'IP Addresses', + 'gateways': 'Gateways', + 'site-to-site-vpn': 'Site-to-site VPN' + }; + var $links = $('
    ').addClass('links'); + var $tooltip = $('
    ').addClass('vpc-configure-tooltip').append( + $('
    ').addClass('arrow') + ); + + // Make links + $.map(links, function(label, id) { + var $link = $('
  • ').addClass('link').addClass(id); + var $label = $('').html(label); + + $link.append($label); + $link.appendTo($links); + + // Link event + $link.click(function() { + switch (id) { + case 'site-to-site-vpn': + $browser.cloudBrowser('addPanel', { + title: 'Site-to-site VPNs', + maximizeIfSelected: true, + complete: function($panel) { + $panel.listView( + $.isFunction(siteToSiteVPN.listView) ? + siteToSiteVPN.listView() : siteToSiteVPN.listView + ); + } + }); + break; + } + }); + }); + + $tooltip.append($links); + + // Tooltip hover event + $tooltip.hover( + function() { + $tooltip.addClass('active'); + }, + function() { + $tooltip.removeClass('active'); + + setTimeout(function() { + if (!$tooltip.hasClass('active')) { + $tooltip.remove(); + } + }, 500); + } + ); + + return $tooltip; + }, + vpcConfigureArea: function(args) { + var $browser = args.$browser; + var siteToSiteVPN = args.siteToSiteVPN; + var $config = $('
    ').addClass('config-area'); + var $configIcon = $('').addClass('icon').html(' '); + + $config.append($configIcon); + + // Tooltip event + $configIcon.mouseover(function() { + var $tooltip = elems.vpcConfigureTooltip({ + $browser: $browser, + siteToSiteVPN: siteToSiteVPN + }); + + // Make sure tooltip is center aligned with icon + $tooltip.css({ left: $configIcon.position().left }); + $tooltip.appendTo($config).hide(); + $tooltip.stop().fadeIn('fast'); + }); + + return $config; + }, + router: function() { + var $router = $('
  • ').addClass('tier virtual-router'); + var $title = $('').addClass('title').html('Virtual Router'); + + $router.append($title); + + // Append horizontal chart line + $router.append($('
    ').addClass('connect-line')); + + return $router; + }, + tier: function(args) { + var name = args.name; + var cidr = args.cidr; + var context = args.context; + var vmListView = args.vmListView; + var actionPreFilter = args.actionPreFilter; + var actions = $.map( + args.actions ? args.actions : {}, function(value, key) { + return { + id: key, + action: value + }; + } + ); + var isPlaceholder = args.isPlaceholder; + var virtualMachines = args.virtualMachines; + var $tier = $('
  • ').addClass('tier'); + var $title = $('').addClass('title'); + var $cidr = $('').addClass('cidr'); + var $vmCount = $('').addClass('vm-count'); + var $actions = $('
    ').addClass('actions'); + + // Ignore special actions + // -- Add tier action is handled separately + actions = $.grep(actions, function(action) { + return action.id != 'add'; + }); + + // VM count shows instance list + $vmCount.click(function() { + var $dialog = $('
    '); + var $listView = $('
    ').listView($.extend(true, {}, vmListView, { + context: context + })); + + $dialog.append($listView); + $dialog.dialog({ + title: 'VMs in this tier', + dialogClass: 'multi-edit-add-list panel configure-acl', + width: 825, + height: 600, + buttons: { + 'Done': function() { + $(':ui-dialog').remove(); + $('.overlay').remove(); + } + } + }).closest('.ui-dialog').overlay(); + }); + + if (isPlaceholder) { + $tier.addClass('placeholder'); + $title.html('Create Tier'); + } else { + $title.html(name); + $cidr.html(cidr); + $vmCount.append( + $('').addClass('total').html(virtualMachines.length), + ' VMs' + ); + $tier.append($actions); + + // Build action buttons + $(actions).map(function(index, action) { + var $action = $('
    ').addClass('action'); + var shortLabel = action.action.shortLabel; + var label = action.action.label; + + $action.addClass(action.id); + + if (action.id != 'remove') { + $action.append($('').addClass('label').html(shortLabel)); + } else { + $action.append($('').addClass('icon').html(' ')); + } + + $actions.append($action); + $action.attr('title', label); + $action.data('vpc-tier-action-id', action.id); + + // Action event + $action.click(function() { + if ($action.hasClass('disabled')) { + return false; + } + + tierAction({ + action: action, + actionPreFilter: actionPreFilter, + context: context, + $tier: $tier, + $actions: $actions + }); + + return true; + }); + }); + } + + $tier.prepend($title); + + if (!isPlaceholder) { + $tier.append($title, $cidr, $vmCount); + } + + // Append horizontal chart line + $tier.append($('
    ').addClass('connect-line')); + + // Handle action filter + filterActions({ + $actions: $actions, + actionPreFilter: actionPreFilter, + context: context + }); + + return $tier; + }, + chart: function(args) { + var $browser = args.$browser; + var siteToSiteVPN = args.siteToSiteVPN; + var tiers = args.tiers; + var vmListView = args.vmListView; + var actions = args.actions; + var actionPreFilter = args.actionPreFilter; + var vpcName = args.vpcName; + var context = args.context; + var $tiers = $('
      ').addClass('tiers'); + var $router = elems.router(); + var $chart = $('
      ').addClass('vpc-chart'); + var $title = $('
      ').addClass('vpc-title') + .append( + $('').html(vpcName) + ) + .append( + elems.vpcConfigureArea({ + $browser: $browser, + siteToSiteVPN: siteToSiteVPN + }) + ); + + var showAddTierDialog = function() { + if ($(this).find('.loading-overlay').size()) { + return false; + } + + addTierDialog({ + $tiers: $tiers, + context: context, + actions: actions, + vmListView: vmListView, + actionPreFilter: actionPreFilter + }); + + return true; + }; + + if (tiers.length) { + $(tiers).map(function(index, tier) { + var $tier = elems.tier({ + name: tier.name, + cidr: tier.cidr, + virtualMachines: tier.virtualMachines, + vmListView: vmListView, + actions: actions, + actionPreFilter: actionPreFilter, + context: $.extend(true, {}, context, { + tiers: [tier] + }) + }); + + $tier.appendTo($tiers); + }); + + } + + elems.tier({ isPlaceholder: true }).appendTo($tiers) + .click(showAddTierDialog); + $tiers.prepend($router); + $chart.append($title, $tiers); + + if (!tiers || !tiers.length) { + showAddTierDialog(); + } + + return $chart; + } + }; + + var filterActions = function(args) { + var $actions = args.$actions; + var actionPreFilter = args.actionPreFilter; + var context = args.context; + var disabledActions, allowedActions; + + disabledActions = actionPreFilter ? actionPreFilter({ + context: context + }) : []; + + // Visual appearance for disabled actions + $actions.find('.action').map(function(index, action) { + var $action = $(action); + var actionID = $action.data('vpc-tier-action-id'); + + if ($.inArray(actionID, disabledActions) > -1) { + $action.addClass('disabled'); + } else { + $action.removeClass('disabled'); + } + }); + }; + + // Handles tier action, including UI effects + var tierAction = function(args) { + var $tier = args.$tier; + var $loading = $('
      ').addClass('loading-overlay'); + var $actions = args.$actions; + var actionArgs = args.action.action; + var action = actionArgs.action; + var actionID = args.action.id; + var notification = actionArgs.notification; + var label = actionArgs.label; + var context = args.context; + var actionPreFilter = args.actionPreFilter; + + var success = function(args) { + var remove = args ? args.remove : false; + var _custom = args ? args._custom : {}; + + cloudStack.ui.notifications.add( + // Notification + { + desc: label, + poll: notification.poll, + _custom: _custom + }, + + // Success + function(args) { + var newData = args.data ? args.data : {}; + var newTier = $.extend(true, {}, context.tiers[0], newData); + var newContext = $.extend(true, {}, context); + + // Update data + newContext.tiers = [newTier]; + + if (remove) { + $tier.remove(); + } else { + $loading.remove(); + } + + if (actionID == 'addVM') { + // Increment VM total + var $total = $tier.find('.vm-count .total'); + var prevTotal = parseInt($total.html()); + var newTotal = prevTotal + 1; + + $total.html(newTotal); + } + + filterActions({ + $actions: $actions, + actionPreFilter: actionPreFilter, + context: newContext + }); + }, + + {}, + + // Error + function(args) { + $loading.remove(); + } + ); + }; + + switch(actionID) { + case 'addVM': + action({ + context: context, + complete: function(args) { + $loading.appendTo($tier); + success(args); + } + }); + break; + case 'remove': + $loading.appendTo($tier); + action({ + context: context, + response: { + success: function(args) { + success({ remove: true }); + } + } + }); + break; + case 'acl': + // Show ACL dialog + $('
      ').multiEdit( + $.extend(true, {}, actionArgs.multiEdit, { + context: context + }) + ).dialog({ + title: 'Configure ACL', + dialogClass: 'configure-acl', + width: 820, + height: 600, + buttons: { + 'Done': function() { + $(':ui-dialog').remove(); + $('.overlay').remove(); + } + } + }).closest('.ui-dialog').overlay(); + break; + default: + $loading.appendTo($tier); + action({ + context: context, + complete: success, + response: { + success: success, + error: function(args) { $loading.remove(); } + } + }); + } + }; + + // Appends a new tier to chart + var addNewTier = function(args) { + var actions = args.actions; + var vmListView = args.vmListView; + var actionPreFilter = args.actionPreFilter; + var context = args.context; + var tier = $.extend(args.tier, { + context: context, + vmListView: vmListView, + actions: actions, + actionPreFilter: actionPreFilter, + virtualMachines: [] + }); + var $tiers = args.$tiers; + + $tiers.find('li.placeholder') + .before( + elems.tier(tier) + .hide() + .fadeIn('slow') + ); + }; + + // Renders the add tier form, in a dialog + var addTierDialog = function(args) { + var actions = args.actions; + var context = args.context; + var vmListView = args.vmListView; + var actionPreFilter = args.actionPreFilter; + var $tiers = args.$tiers; + + cloudStack.dialog.createForm({ + form: actions.add.createForm, + after: function(args) { + var $loading = $('
      ').addClass('loading-overlay').prependTo($tiers.find('li.placeholder')); + actions.add.action({ + context: context, + data: args.data, + response: { + success: function(args) { + var tier = args.data; + + cloudStack.ui.notifications.add( + // Notification + { + desc: actions.add.label, + poll: actions.add.notification.poll + }, + + // Success + function(args) { + $loading.remove(); + addNewTier({ + context: $.extend(true, {}, context, { + tiers: [tier] + }), + tier: tier, + $tiers: $tiers, + actions: actions, + actionPreFilter: actionPreFilter, + vmListView: vmListView + }); + }, + + {}, + + // Error + function(args) { + $loading.remove(); + } + ); + } + } + }); + } + }); + }; + + cloudStack.uiCustom.vpc = function(args) { + var vmListView = args.vmListView; + var tierArgs = args.tiers; + var siteToSiteVPN = args.siteToSiteVPN; + + return function(args) { + var context = args.context; + var $browser = $('#browser .container'); + var $toolbar = $('
      ').addClass('toolbar'); + var vpc = args.context.vpc[0]; + + $browser.cloudBrowser('addPanel', { + maximizeIfSelected: true, + title: 'Configure VPC: ' + vpc.name, + complete: function($panel) { + var $loading = $('
      ').addClass('loading-overlay').appendTo($panel); + + $panel.append($toolbar); + + // Load data + tierArgs.dataProvider({ + context: context, + response: { + success: function(args) { + var tiers = args.data.tiers; + var $chart = elems.chart({ + $browser: $browser, + siteToSiteVPN: siteToSiteVPN, + vmListView: vmListView, + context: context, + actions: tierArgs.actions, + actionPreFilter: tierArgs.actionPreFilter, + vpcName: vpc.name, + tiers: tiers + }).appendTo($panel); + + $loading.remove(); + $chart.fadeIn(function() { + }); + } + } + }); + } + }); + }; + }; +}(jQuery, cloudStack)); diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 3a727149234..d46bad9800b 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -560,31 +560,67 @@ .attr({ title: 'Remove this physical network' }) .append('').addClass('icon').html(' '); var $icon = $('
      ').addClass('physical-network-icon'); - var $nameField = $('
      ').addClass('field name').append( + + var $nameField = $('
      ').addClass('field name').append( $('
      ').addClass('name').append( $('