You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2012/07/12 02:15:14 UTC
[2/3] Phase 1 of Nicira integration
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
new file mode 100644
index 0000000..ba4b961
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
@@ -0,0 +1,502 @@
+/** 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.network.element;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.CreateLogicalSwitchPortAnswer;
+import com.cloud.agent.api.CreateLogicalSwitchPortCommand;
+import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer;
+import com.cloud.agent.api.DeleteLogicalSwitchPortCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupNiciraNvpCommand;
+import com.cloud.api.commands.AddNiciraNvpDeviceCmd;
+import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd;
+import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd;
+import com.cloud.api.commands.ListNiciraNvpDevicesCmd;
+import com.cloud.api.response.NiciraNvpDeviceResponse;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.Network;
+import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkVO;
+import com.cloud.network.Networks;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.NiciraNvpDeviceVO;
+import com.cloud.network.NiciraNvpNicMappingVO;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NiciraNvpDao;
+import com.cloud.network.dao.NiciraNvpNicMappingDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.guru.NiciraNvpGuestNetworkGuru;
+import com.cloud.network.resource.NiciraNvpResource;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+
+@Local(value = NetworkElement.class)
+public class NiciraNvpElement extends AdapterBase implements NetworkElement, NiciraNvpElementService, ResourceStateAdapter {
+ private static final Logger s_logger = Logger.getLogger(NiciraNvpElement.class);
+
+ private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
+
+
+ @Inject
+ NicDao _nicDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject
+ NiciraNvpDao _niciraNvpDao;
+ @Inject
+ HostDetailsDao _hostDetailsDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ NiciraNvpNicMappingDao _niciraNvpNicMappingDao;
+ @Inject
+ NetworkDao _networkDao;
+
+ @Override
+ public Map<Service, Map<Capability, String>> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ public Provider getProvider() {
+ return Provider.NiciraNvp;
+ }
+
+ private boolean canHandle(Network network) {
+ if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ super.configure(name, params);
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return true;
+ }
+
+ @Override
+ public boolean implement(Network network, NetworkOffering offering,
+ DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean prepare(Network network, NicProfile nic,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ if (network.getBroadcastUri() == null) {
+ s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid");
+ return false;
+ }
+
+ NicVO nicVO = _nicDao.findById(nic.getId());
+
+ List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId());
+ return false;
+ }
+ NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
+ HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId());
+
+ CreateLogicalSwitchPortCommand cmd = new CreateLogicalSwitchPortCommand(network.getBroadcastUri().getSchemeSpecificPart(), nicVO.getUuid(),
+ context.getDomain().getName() + "-" + context.getAccount().getAccountName(), nic.getName());
+ CreateLogicalSwitchPortAnswer answer = (CreateLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd);
+
+ if (answer == null || !answer.getResult()) {
+ s_logger.error ("CreateLogicalSwitchPortCommand failed");
+ return false;
+ }
+
+ NiciraNvpNicMappingVO nicMap = new NiciraNvpNicMappingVO(network.getBroadcastUri().getSchemeSpecificPart(), answer.getLogicalSwitchPortUuid(), nicVO.getUuid());
+ _niciraNvpNicMappingDao.persist(nicMap);
+
+ return true;
+ }
+
+ @Override
+ public boolean release(Network network, NicProfile nic,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ ReservationContext context) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ if (network.getBroadcastUri() == null) {
+ s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid");
+ return false;
+ }
+
+ NicVO nicVO = _nicDao.findById(nic.getId());
+
+ List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId());
+ return false;
+ }
+ NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
+ HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId());
+
+ NiciraNvpNicMappingVO nicMap = _niciraNvpNicMappingDao.findByNicUuid(nicVO.getUuid());
+ if (nicMap == null) {
+ s_logger.error("No mapping for nic " + nic.getName());
+ return false;
+ }
+
+ DeleteLogicalSwitchPortCommand cmd = new DeleteLogicalSwitchPortCommand(nicMap.getLogicalSwitchUuid(), nicMap.getLogicalSwitchPortUuid());
+ DeleteLogicalSwitchPortAnswer answer = (DeleteLogicalSwitchPortAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd);
+
+ if (answer == null || !answer.getResult()) {
+ s_logger.error ("DeleteLogicalSwitchPortCommand failed");
+ return false;
+ }
+
+ _niciraNvpNicMappingDao.remove(nicMap.getId());
+
+ return true;
+ }
+
+ @Override
+ public boolean shutdown(Network network, ReservationContext context,
+ boolean cleanup) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean destroy(Network network)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isReady(PhysicalNetworkServiceProvider provider) {
+ return true;
+ }
+
+ @Override
+ public boolean shutdownProviderInstances(
+ PhysicalNetworkServiceProvider provider, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ // Nothing to do here.
+ return true;
+ }
+
+ @Override
+ public boolean canEnableIndividualServices() {
+ return false;
+ }
+
+ @Override
+ public boolean verifyServicesCombination(List<String> services) {
+ return true;
+ }
+
+ private static Map<Service, Map<Capability, String>> setCapabilities() {
+ Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+
+ capabilities.put(Service.Connectivity, null);
+ return capabilities;
+ }
+
+ @Override
+ public String getPropertiesFile() {
+ return "nicira-nvp_commands.properties";
+ }
+
+ @Override
+ @DB
+ public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) {
+ ServerResource resource = new NiciraNvpResource();
+ String deviceName = Network.Provider.NiciraNvp.getName();
+ NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ NiciraNvpDeviceVO niciraNvpDevice = null;
+
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+ }
+ long zoneId = physicalNetwork.getDataCenterId();
+
+ PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder());
+ if (ntwkSvcProvider == null) {
+ throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() +
+ " is not enabled in the physical network: " + physicalNetworkId + "to add this device");
+ } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+ throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() +
+ " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device");
+ }
+
+ if (_niciraNvpDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) {
+ throw new CloudRuntimeException("A NiciraNvp device is already configured on this physical network");
+ }
+
+ Map<String, String> params = new HashMap<String,String>();
+ params.put("guid", UUID.randomUUID().toString());
+ params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
+ params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
+ params.put("name", "Nicira Controller - " + cmd.getHost());
+ params.put("ip", cmd.getHost());
+ params.put("adminuser", cmd.getUsername());
+ params.put("adminpass", cmd.getPassword());
+ params.put("transportzoneuuid", cmd.getTransportzoneUuid());
+ params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase()); // FIXME What to do with multiple isolation types
+
+ Map<String, Object> hostdetails = new HashMap<String,Object>();
+ hostdetails.putAll(params);
+
+
+ Transaction txn = Transaction.currentTxn();
+ try {
+ resource.configure(cmd.getHost(), hostdetails);
+
+ Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params);
+ if (host != null) {
+ txn.start();
+
+ niciraNvpDevice = new NiciraNvpDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName);
+ _niciraNvpDao.persist(niciraNvpDevice);
+
+ DetailVO detail = new DetailVO(host.getId(), "niciranvpdeviceid", String.valueOf(niciraNvpDevice.getId()));
+ _hostDetailsDao.persist(detail);
+
+ txn.commit();
+ return niciraNvpDevice;
+ } else {
+ throw new CloudRuntimeException("Failed to add Nicira Nvp Device due to internal error.");
+ }
+ } catch (ConfigurationException e) {
+ txn.rollback();
+ throw new CloudRuntimeException(e.getMessage());
+ }
+ }
+
+ @Override
+ public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse(
+ NiciraNvpDeviceVO niciraNvpDeviceVO) {
+ NiciraNvpDeviceResponse response = new NiciraNvpDeviceResponse();
+ response.setDeviceName(niciraNvpDeviceVO.getDeviceName());
+ response.setPhysicalNetworkId(niciraNvpDeviceVO.getPhysicalNetworkId());
+ response.setId(niciraNvpDeviceVO.getId());
+ response.setProviderName(niciraNvpDeviceVO.getProviderName());
+ return response;
+ }
+
+ @Override
+ public boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd) {
+ Long niciraDeviceId = cmd.getNiciraNvpDeviceId();
+ NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId);
+ if (niciraNvpDevice == null) {
+ throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId);
+ }
+
+ // Find the physical network we work for
+ Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId();
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork != null) {
+ // Lets see if there are networks that use us
+ // Find the nicira networks on this physical network
+ List<NetworkVO> networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId);
+
+ // Networks with broadcast type lswitch are ours
+ for (NetworkVO network : networkList) {
+ if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) {
+ if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) {
+ throw new CloudRuntimeException("This Nicira Nvp device can not be deleted as there are one or more logical networks provisioned by cloudstack.");
+ }
+ }
+ }
+ }
+
+ HostVO niciraHost = _hostDao.findById(niciraNvpDevice.getHostId());
+ Long hostId = niciraHost.getId();
+
+ niciraHost.setResourceState(ResourceState.Maintenance);
+ _hostDao.update(hostId, niciraHost);
+ _resourceMgr.deleteHost(hostId, false, false);
+
+ _niciraNvpDao.remove(niciraDeviceId);
+
+ return true;
+ }
+
+ @Override
+ public List<NiciraNvpDeviceVO> listNiciraNvpDevices(ListNiciraNvpDevicesCmd cmd) {
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ Long niciraNvpDeviceId = cmd.getNiciraNvpDeviceId();
+ List<NiciraNvpDeviceVO> responseList = new ArrayList<NiciraNvpDeviceVO>();
+
+ if (physicalNetworkId == null && niciraNvpDeviceId == null) {
+ throw new InvalidParameterValueException("Either physical network Id or nicira device Id must be specified");
+ }
+
+ if (niciraNvpDeviceId != null) {
+ NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraNvpDeviceId);
+ if (niciraNvpDevice == null) {
+ throw new InvalidParameterValueException("Could not find Nicira Nvp device with id: " + niciraNvpDevice);
+ }
+ responseList.add(niciraNvpDevice);
+ }
+ else {
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId);
+ }
+ responseList = _niciraNvpDao.listByPhysicalNetwork(physicalNetworkId);
+ }
+
+ return responseList;
+ }
+
+ @Override
+ public List<? extends Network> listNiciraNvpDeviceNetworks(ListNiciraNvpDeviceNetworksCmd cmd) {
+ Long niciraDeviceId = cmd.getNiciraNvpDeviceId();
+ NiciraNvpDeviceVO niciraNvpDevice = _niciraNvpDao.findById(niciraDeviceId);
+ if (niciraNvpDevice == null) {
+ throw new InvalidParameterValueException("Could not find a nicira device with id " + niciraDeviceId);
+ }
+
+ // Find the physical network we work for
+ Long physicalNetworkId = niciraNvpDevice.getPhysicalNetworkId();
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ // No such physical network, so no provisioned networks
+ return Collections.emptyList();
+ }
+
+ // Find the nicira networks on this physical network
+ List<NetworkVO> networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId);
+
+ // Networks with broadcast type lswitch are ours
+ List<NetworkVO> responseList = new ArrayList<NetworkVO>();
+ for (NetworkVO network : networkList) {
+ if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) {
+ responseList.add(network);
+ }
+ }
+
+ return responseList;
+ }
+
+ @Override
+ public HostVO createHostVOForConnectedAgent(HostVO host,
+ StartupCommand[] cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host,
+ StartupCommand[] startup, ServerResource resource,
+ Map<String, String> details, List<String> hostTags) {
+ if (!(startup[0] instanceof StartupNiciraNvpCommand)) {
+ return null;
+ }
+ host.setType(Host.Type.L2Networking);
+ return host;
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+ boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ if (!(host.getType() == Host.Type.L2Networking)) {
+ return null;
+ }
+ return new DeleteHostAnswer(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElementService.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElementService.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElementService.java
new file mode 100644
index 0000000..0f503e7
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElementService.java
@@ -0,0 +1,28 @@
+package com.cloud.network.element;
+
+import java.util.List;
+
+import com.cloud.api.commands.AddNiciraNvpDeviceCmd;
+import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd;
+import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd;
+import com.cloud.api.commands.ListNiciraNvpDevicesCmd;
+import com.cloud.api.response.NiciraNvpDeviceResponse;
+import com.cloud.network.Network;
+import com.cloud.network.NiciraNvpDeviceVO;
+import com.cloud.utils.component.PluggableService;
+
+public interface NiciraNvpElementService extends PluggableService {
+
+ public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd);
+
+ public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse(
+ NiciraNvpDeviceVO niciraDeviceVO);
+
+ boolean deleteNiciraNvpDevice(DeleteNiciraNvpDeviceCmd cmd);
+
+ List<? extends Network> listNiciraNvpDeviceNetworks(
+ ListNiciraNvpDeviceNetworksCmd cmd);
+
+ List<NiciraNvpDeviceVO> listNiciraNvpDevices(ListNiciraNvpDevicesCmd cmd);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
new file mode 100644
index 0000000..3bac88b
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java
@@ -0,0 +1,257 @@
+/** 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.network.guru;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.CreateLogicalSwitchAnswer;
+import com.cloud.agent.api.CreateLogicalSwitchCommand;
+import com.cloud.agent.api.DeleteLogicalSwitchAnswer;
+import com.cloud.agent.api.DeleteLogicalSwitchCommand;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.NetworkVO;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.State;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.NiciraNvpDeviceVO;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NiciraNvpDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.user.Account;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.component.Inject;
+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 NiciraNvpGuestNetworkGuru extends GuestNetworkGuru {
+ private static final Logger s_logger = Logger.getLogger(NiciraNvpGuestNetworkGuru.class);
+
+ @Inject
+ NetworkManager _externalNetworkManager;
+ @Inject
+ NetworkManager _networkMgr;
+ @Inject
+ NetworkDao _networkDao;
+ @Inject
+ DataCenterDao _zoneDao;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ AccountDao _accountDao;
+ @Inject
+ NiciraNvpDao _niciraNvpDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ HostDetailsDao _hostDetailsDao;
+
+ public NiciraNvpGuestNetworkGuru() {
+ super();
+ _isolationMethods = new IsolationMethod[] { IsolationMethod.STT };
+ }
+
+ @Override
+ protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+ // This guru handles only Guest Isolated network that supports Source nat service
+ if (networkType == NetworkType.Advanced
+ && isMyTrafficType(offering.getTrafficType())
+ && offering.getGuestType() == Network.GuestType.Isolated
+ && isMyIsolationMethod(physicalNetwork)) {
+ return true;
+ } else {
+ s_logger.trace("We only take care of 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) {
+ // Check of the isolation type of the related physical network is STT
+ PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
+ if (physnet == null || physnet.getIsolationMethods() == null || !physnet.getIsolationMethods().contains("STT")) {
+ s_logger.debug("Refusing to design this network, the physical isolation type is not STT");
+ return null;
+ }
+
+ List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(physnet.getId());
+ if (devices.isEmpty()) {
+ s_logger.error("No NiciraNvp Controller on physical network " + physnet.getName());
+ return null;
+ }
+ s_logger.debug("Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());
+
+ s_logger.debug("Physical isolation type is STT, asking GuestNetworkGuru to design this network");
+ NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, owner);
+ if (networkObject == null) {
+ return null;
+ }
+ // Override the broadcast domain type
+ networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch);
+
+ return networkObject;
+ }
+
+ @Override
+ 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();
+
+ //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,
+ network.getDataCenterId(), physicalNetworkId);
+
+ if (network.getGateway() != null) {
+ implemented.setGateway(network.getGateway());
+ }
+
+ if (network.getCidr() != null) {
+ implemented.setCidr(network.getCidr());
+ }
+
+ // Name is either the given name or the uuid
+ String name = implemented.getName();
+ if (name == null || name.isEmpty()) {
+ name = implemented.getUuid();
+ }
+ if (name.length() > 40 ) {
+ name = name.substring(0, 39); // max length 40
+ }
+
+ List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(physicalNetworkId);
+ if (devices.isEmpty()) {
+ s_logger.error("No NiciraNvp Controller on physical network " + physicalNetworkId);
+ return null;
+ }
+ NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
+ HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId());
+ _hostDao.loadDetails(niciraNvpHost);
+ String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid");
+ String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype");
+
+ CreateLogicalSwitchCommand cmd = new CreateLogicalSwitchCommand(transportzoneuuid, transportzoneisotype, network.getName(),
+ context.getDomain().getName() + "-" + context.getAccount().getAccountName());
+ CreateLogicalSwitchAnswer answer = (CreateLogicalSwitchAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd);
+
+ if (answer == null || !answer.getResult()) {
+ s_logger.error ("CreateLogicalSwitchCommand failed");
+ return null;
+ }
+
+ try {
+ implemented.setBroadcastUri(new URI("lswitch", answer.getLogicalSwitchUuid(), null));
+ implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch);
+ s_logger.info("Implemented OK, network linked to = " + implemented.getBroadcastUri().toString());
+ } catch (URISyntaxException e) {
+ s_logger.error("Unable to store logical switch id in broadcast uri, uuid = " + implemented.getUuid(), e);
+ }
+
+ return implemented;
+ }
+
+ @Override
+ public void reserve(NicProfile nic, Network network,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ DeployDestination dest, ReservationContext context)
+ throws InsufficientVirtualNetworkCapcityException,
+ InsufficientAddressCapacityException {
+ // TODO Auto-generated method stub
+ super.reserve(nic, network, vm, dest, context);
+ }
+
+ @Override
+ public boolean release(NicProfile nic,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ String reservationId) {
+ // TODO Auto-generated method stub
+ return super.release(nic, vm, reservationId);
+ }
+
+ @Override
+ public void shutdown(NetworkProfile profile, NetworkOffering offering) {
+ NetworkVO networkObject = _networkDao.findById(profile.getId());
+ if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Lswitch ||
+ networkObject.getBroadcastUri() == null) {
+ s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
+ return;
+ }
+
+ List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No NiciraNvp Controller on physical network " + networkObject.getPhysicalNetworkId());
+ return;
+ }
+ NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
+ HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId());
+
+ DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(networkObject.getBroadcastUri().getSchemeSpecificPart());
+ DeleteLogicalSwitchAnswer answer = (DeleteLogicalSwitchAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd);
+
+ if (answer == null || !answer.getResult()) {
+ s_logger.error ("DeleteLogicalSwitchCommand failed");
+ }
+
+ super.shutdown(profile, offering);
+ }
+
+ @Override
+ public boolean trash(Network network, NetworkOffering offering,
+ Account owner) {
+ return super.trash(network, offering, owner);
+ }
+
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java
new file mode 100644
index 0000000..f70d0a1
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/Attachment.java
@@ -0,0 +1,22 @@
+/** 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.network.nicira;
+
+public abstract class Attachment {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java
new file mode 100644
index 0000000..5502442
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitch.java
@@ -0,0 +1,99 @@
+/** 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.network.nicira;
+
+import java.util.List;
+
+public class LogicalSwitch {
+ private String display_name;
+ private boolean port_isolation_enabled;
+ private List<NiciraNvpTag> tags;
+ private List<TransportZoneBinding> transport_zones;
+ private String type;
+ private String uuid;
+ private String _href;
+ //private RequestQueryParameters _query;
+ //private LogicalSwitchRelations _relations;
+ private String _schema;
+
+ public String getDisplay_name() {
+ return display_name;
+ }
+
+ public void setDisplay_name(String display_name) {
+ this.display_name = display_name;
+ }
+
+ public boolean isPort_isolation_enabled() {
+ return port_isolation_enabled;
+ }
+
+ public void setPort_isolation_enabled(boolean port_isolation_enabled) {
+ this.port_isolation_enabled = port_isolation_enabled;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String get_href() {
+ return _href;
+ }
+
+ public void set_href(String _href) {
+ this._href = _href;
+ }
+
+ public String get_schema() {
+ return _schema;
+ }
+
+ public void set_schema(String _schema) {
+ this._schema = _schema;
+ }
+
+ public List<NiciraNvpTag> getTags() {
+ return tags;
+ }
+
+ public void setTags(List<NiciraNvpTag> tags) {
+ this.tags = tags;
+ }
+
+ public List<TransportZoneBinding> getTransport_zones() {
+ return transport_zones;
+ }
+
+ public void setTransport_zones(List<TransportZoneBinding> transport_zones) {
+ this.transport_zones = transport_zones;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java
new file mode 100644
index 0000000..e74fda2
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/LogicalSwitchPort.java
@@ -0,0 +1,118 @@
+/** 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.network.nicira;
+
+import java.util.List;
+
+public class LogicalSwitchPort {
+ private String display_name;
+ private List<NiciraNvpTag> tags;
+ private Integer portno;
+ private boolean admin_status_enabled;
+ //private List<AddressPairs> allowed_address_pairs;
+ private String queue_uuid;
+ private List<String> security_profiles;
+ private List<String> mirror_targets;
+ private String type;
+ private String uuid;
+
+ public LogicalSwitchPort() {
+ super();
+ }
+
+ public LogicalSwitchPort(String display_name, List<NiciraNvpTag> tags,
+ boolean admin_status_enabled) {
+ super();
+ this.display_name = display_name;
+ this.tags = tags;
+ this.admin_status_enabled = admin_status_enabled;
+ }
+
+ public String getDisplay_name() {
+ return display_name;
+ }
+
+ public void setDisplay_name(String display_name) {
+ this.display_name = display_name;
+ }
+
+ public List<NiciraNvpTag> getTags() {
+ return tags;
+ }
+
+ public void setTags(List<NiciraNvpTag> tags) {
+ this.tags = tags;
+ }
+
+ public Integer getPortno() {
+ return portno;
+ }
+
+ public void setPortno(Integer portno) {
+ this.portno = portno;
+ }
+
+ public boolean isAdmin_status_enabled() {
+ return admin_status_enabled;
+ }
+
+ public void setAdmin_status_enabled(boolean admin_status_enabled) {
+ this.admin_status_enabled = admin_status_enabled;
+ }
+
+ public String getQueue_uuid() {
+ return queue_uuid;
+ }
+
+ public void setQueue_uuid(String queue_uuid) {
+ this.queue_uuid = queue_uuid;
+ }
+
+ public List<String> getSecurity_profiles() {
+ return security_profiles;
+ }
+
+ public void setSecurity_profiles(List<String> security_profiles) {
+ this.security_profiles = security_profiles;
+ }
+
+ public List<String> getMirror_targets() {
+ return mirror_targets;
+ }
+
+ public void setMirror_targets(List<String> mirror_targets) {
+ this.mirror_targets = mirror_targets;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
new file mode 100644
index 0000000..c2cf9c5
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
@@ -0,0 +1,413 @@
+/** 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.network.nicira;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+import org.apache.log4j.Logger;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+public class NiciraNvpApi {
+ private static final Logger s_logger = Logger.getLogger(NiciraNvpApi.class);
+
+ private String _name;
+ private String _host;
+ private String _adminuser;
+ private String _adminpass;
+
+ private HttpClient _client;
+
+ public NiciraNvpApi(String host, String adminuser, String adminpass) throws NiciraNvpApiException {
+ this._host = host;
+ this._adminpass = adminpass;
+ this._adminuser = adminuser;
+
+ if (_host == null || _adminpass == null || _adminuser == null) {
+ throw new NiciraNvpApiException("host, adminuser and adminpass may not be null");
+ }
+
+ _client = new HttpClient( );
+ _client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+
+ try {
+ // Cast to ProtocolSocketFactory to avoid the deprecated constructor with the SecureProtocolSocketFactory parameter
+ Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) new TrustingProtocolSocketFactory(), 443));
+ } catch (IOException e) {
+ s_logger.warn("Failed to register the TrustingProtocolSocketFactory, falling back to default SSLSocketFactory", e);
+ }
+
+ }
+
+ /**
+ * Logs into the Nicira API. The cookie is stored in the <code>_authcookie<code> variable.
+ * <p>
+ * The method returns false if the login failed or the connection could not be made.
+ *
+ */
+ private void login() throws NiciraNvpApiException {
+ String url;
+
+ try {
+ url = new URL("https", _host, "/ws.v1/login").toString();
+ } catch (MalformedURLException e) {
+ s_logger.error("Unable to build Nicira API URL", e);
+ throw new NiciraNvpApiException("Unable to build Nicira API URL", e);
+ }
+
+ PostMethod pm = new PostMethod(url);
+ pm.addParameter("username", _adminuser);
+ pm.addParameter("password", _adminpass);
+
+ try {
+ _client.executeMethod(pm);
+ } catch (HttpException e) {
+ throw new NiciraNvpApiException("Nicira NVP API login failed ", e);
+ } catch (IOException e) {
+ throw new NiciraNvpApiException("Nicira NVP API login failed ", e);
+ }
+
+ if (pm.getStatusCode() != HttpStatus.SC_OK) {
+ s_logger.error("Nicira NVP API login failed : " + pm.getStatusText());
+ throw new NiciraNvpApiException("Nicira NVP API login failed " + pm.getStatusText());
+ }
+
+ // Success; the cookie required for login is kept in _client
+ }
+
+ public LogicalSwitch createLogicalSwitch(LogicalSwitch logicalSwitch) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch";
+ LogicalSwitch createdLogicalSwitch = executeCreateObject(logicalSwitch, new TypeToken<LogicalSwitch>(){}.getType(), uri, Collections.<String,String>emptyMap());
+
+ return createdLogicalSwitch;
+ }
+
+ public void deleteLogicalSwitch(String uuid) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch/" + uuid;
+ executeDeleteObject(uri);
+ }
+
+ public LogicalSwitchPort createLogicalSwitchPort(String logicalSwitchUuid, LogicalSwitchPort logicalSwitchPort) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch/" + logicalSwitchUuid + "/lport";
+ LogicalSwitchPort createdLogicalSwitchPort = executeCreateObject(logicalSwitchPort, new TypeToken<LogicalSwitchPort>(){}.getType(), uri, Collections.<String,String>emptyMap());;
+
+ return createdLogicalSwitchPort;
+ }
+
+ public void modifyLogicalSwitchPortAttachment(String logicalSwitchUuid, String logicalSwitchPortUuid, Attachment attachment) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch/" + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid + "/attachment";
+ executeUpdateObject(attachment, uri, Collections.<String,String>emptyMap());
+ }
+
+ public void deleteLogicalSwitchPort(String logicalSwitchUuid, String logicalSwitchPortUuid) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch/" + logicalSwitchUuid + "/lport/" + logicalSwitchPortUuid;
+ executeDeleteObject(uri);
+ }
+
+ public String findLogicalSwitchPortUuidByVifAttachmentUuid(String logicalSwitchUuid, String vifAttachmentUuid) throws NiciraNvpApiException {
+ String uri = "/ws.v1/lswitch/" + logicalSwitchUuid + "/lport";
+ Map<String,String> params = new HashMap<String,String>();
+ params.put("attachment_vif_uuid", vifAttachmentUuid);
+ params.put("fields", "uuid");
+
+ NiciraNvpList<LogicalSwitchPort> lspl = executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalSwitchPort>>(){}.getType(), uri, params);
+
+ if (lspl == null || lspl.getResult_count() != 1) {
+ throw new NiciraNvpApiException("Unexpected response from API");
+ }
+
+ LogicalSwitchPort lsp = lspl.getResults().get(0);
+ return lsp.getUuid();
+ }
+
+ private <T> void executeUpdateObject(T newObject, String uri, Map<String,String> parameters) throws NiciraNvpApiException {
+ String url;
+ try {
+ url = new URL("https", _host, uri).toString();
+ } catch (MalformedURLException e) {
+ s_logger.error("Unable to build Nicira API URL", e);
+ throw new NiciraNvpApiException("Connection to NVP Failed");
+ }
+
+ Gson gson = new Gson();
+
+ PutMethod pm = new PutMethod(url);
+ pm.setRequestHeader("Content-Type", "application/json");
+ try {
+ pm.setRequestEntity(new StringRequestEntity(
+ gson.toJson(newObject),"application/json", null));
+ } catch (UnsupportedEncodingException e) {
+ throw new NiciraNvpApiException("Failed to encode json request body", e);
+ }
+
+ executeMethod(pm);
+
+ if (pm.getStatusCode() != HttpStatus.SC_OK) {
+ String errorMessage = responseToErrorMessage(pm);
+ s_logger.error("Failed to update object : " + errorMessage);
+ throw new NiciraNvpApiException("Failed to update object : " + errorMessage);
+ }
+
+ }
+
+ private <T> T executeCreateObject(T newObject, Type returnObjectType, String uri, Map<String,String> parameters) throws NiciraNvpApiException {
+ String url;
+ try {
+ url = new URL("https", _host, uri).toString();
+ } catch (MalformedURLException e) {
+ s_logger.error("Unable to build Nicira API URL", e);
+ throw new NiciraNvpApiException("Unable to build Nicira API URL", e);
+ }
+
+ Gson gson = new Gson();
+
+ PostMethod pm = new PostMethod(url);
+ pm.setRequestHeader("Content-Type", "application/json");
+ try {
+ pm.setRequestEntity(new StringRequestEntity(
+ gson.toJson(newObject),"application/json", null));
+ } catch (UnsupportedEncodingException e) {
+ throw new NiciraNvpApiException("Failed to encode json request body", e);
+ }
+
+ executeMethod(pm);
+
+ if (pm.getStatusCode() != HttpStatus.SC_CREATED) {
+ String errorMessage = responseToErrorMessage(pm);
+ s_logger.error("Failed to create object : " + errorMessage);
+ throw new NiciraNvpApiException("Failed to create object : " + errorMessage);
+ }
+
+ T result;
+ try {
+ result = gson.fromJson(pm.getResponseBodyAsString(), TypeToken.get(newObject.getClass()).getType());
+ } catch (IOException e) {
+ throw new NiciraNvpApiException("Failed to decode json response body", e);
+ }
+
+ return result;
+ }
+
+ private void executeDeleteObject(String uri) throws NiciraNvpApiException {
+ String url;
+ try {
+ url = new URL("https", _host, uri).toString();
+ } catch (MalformedURLException e) {
+ s_logger.error("Unable to build Nicira API URL", e);
+ throw new NiciraNvpApiException("Unable to build Nicira API URL", e);
+ }
+
+ DeleteMethod dm = new DeleteMethod(url);
+ dm.setRequestHeader("Content-Type", "application/json");
+
+ executeMethod(dm);
+
+ if (dm.getStatusCode() != HttpStatus.SC_NO_CONTENT) {
+ String errorMessage = responseToErrorMessage(dm);
+ s_logger.error("Failed to delete object : " + errorMessage);
+ throw new NiciraNvpApiException("Failed to delete object : " + errorMessage);
+ }
+ }
+
+ private <T> T executeRetrieveObject(Type returnObjectType, String uri, Map<String,String> parameters) throws NiciraNvpApiException {
+ String url;
+ try {
+ url = new URL("https", _host, uri).toString();
+ } catch (MalformedURLException e) {
+ s_logger.error("Unable to build Nicira API URL", e);
+ throw new NiciraNvpApiException("Unable to build Nicira API URL", e);
+ }
+
+ GetMethod gm = new GetMethod(url);
+ gm.setRequestHeader("Content-Type", "application/json");
+ List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(parameters.size());
+ for (Entry<String,String> e : parameters.entrySet()) {
+ nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue()));
+ }
+ gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0]));
+
+ executeMethod(gm);
+
+ if (gm.getStatusCode() != HttpStatus.SC_OK) {
+ String errorMessage = responseToErrorMessage(gm);
+ s_logger.error("Failed to retrieve object : " + errorMessage);
+ throw new NiciraNvpApiException("Failed to retrieve object : " + errorMessage);
+ }
+
+ Gson gson = new Gson();
+ T returnValue;
+ try {
+ returnValue = gson.fromJson(gm.getResponseBodyAsString(), returnObjectType);
+ } catch (IOException e) {
+ s_logger.error("IOException while retrieving response body",e);
+ throw new NiciraNvpApiException(e);
+ }
+
+ return returnValue;
+ }
+
+ private void executeMethod(HttpMethodBase method) throws NiciraNvpApiException {
+ try {
+ _client.executeMethod(method);
+ if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+ // login and try again
+ login();
+ _client.executeMethod(method);
+ }
+ } catch (HttpException e) {
+ s_logger.error("HttpException caught while trying to connect to the Nicira NVP Controller", e);
+ throw new NiciraNvpApiException("API call to Nicira NVP Controller Failed", e);
+ } catch (IOException e) {
+ s_logger.error("IOException caught while trying to connect to the Nicira NVP Controller", e);
+ throw new NiciraNvpApiException("API call to Nicira NVP Controller Failed", e);
+ }
+ }
+
+ private String responseToErrorMessage(HttpMethodBase method) {
+ assert method.isRequestSent() : "no use getting an error message unless the request is sent";
+
+ if ("text/html".equals(method.getResponseHeader("Content-Type").getValue())) {
+ // The error message is the response content
+ // Safety margin of 1024 characters, anything longer is probably useless
+ // and will clutter the logs
+ try {
+ return method.getResponseBodyAsString(1024);
+ } catch (IOException e) {
+ s_logger.debug("Error while loading response body", e);
+ }
+ }
+
+ // The default
+ return method.getStatusText();
+ }
+
+ /* The Nicira controller uses a self-signed certificate. The
+ * TrustingProtocolSocketFactory will accept any provided
+ * certificate when making an SSL connection to the SDN
+ * Manager
+ */
+ private class TrustingProtocolSocketFactory implements SecureProtocolSocketFactory {
+
+ private SSLSocketFactory ssf;
+
+ public TrustingProtocolSocketFactory() throws IOException {
+ // Create a trust manager that does not validate certificate chains
+ TrustManager[] trustAllCerts = new TrustManager[] {
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ // Trust always
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ // Trust always
+ }
+ }
+ };
+
+ try {
+ // Install the all-trusting trust manager
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ ssf = sc.getSocketFactory();
+ } catch (KeyManagementException e) {
+ throw new IOException(e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException {
+ return ssf.createSocket(host, port);
+ }
+
+ @Override
+ public Socket createSocket(String address, int port, InetAddress localAddress,
+ int localPort) throws IOException, UnknownHostException {
+ return ssf.createSocket(address, port, localAddress, localPort);
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port,
+ boolean autoClose) throws IOException, UnknownHostException {
+ return ssf.createSocket(socket, host, port, autoClose);
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localAddress,
+ int localPort, HttpConnectionParams params) throws IOException,
+ UnknownHostException, ConnectTimeoutException {
+ int timeout = params.getConnectionTimeout();
+ if (timeout == 0) {
+ return createSocket(host, port, localAddress, localPort);
+ }
+ else {
+ Socket s = ssf.createSocket();
+ s.bind(new InetSocketAddress(localAddress, localPort));
+ s.connect(new InetSocketAddress(host, port), timeout);
+ return s;
+ }
+ }
+
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java
new file mode 100644
index 0000000..2a09cc0
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java
@@ -0,0 +1,20 @@
+package com.cloud.network.nicira;
+
+public class NiciraNvpApiException extends Exception {
+
+ public NiciraNvpApiException() {
+ }
+
+ public NiciraNvpApiException(String message) {
+ super(message);
+ }
+
+ public NiciraNvpApiException(Throwable cause) {
+ super(cause);
+ }
+
+ public NiciraNvpApiException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
new file mode 100644
index 0000000..79f582a
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
@@ -0,0 +1,25 @@
+package com.cloud.network.nicira;
+
+import java.util.List;
+
+public class NiciraNvpList<T> {
+ private List<T> results;
+ private int result_count;
+
+ public List<T> getResults() {
+ return results;
+ }
+
+ public void setResults(List<T> results) {
+ this.results = results;
+ }
+
+ public int getResult_count() {
+ return result_count;
+ }
+
+ public void setResult_count(int result_count) {
+ this.result_count = result_count;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java
new file mode 100644
index 0000000..de0b40f
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java
@@ -0,0 +1,47 @@
+/** 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.network.nicira;
+
+public class NiciraNvpTag {
+ private String scope;
+ private String tag;
+
+ public NiciraNvpTag() {}
+
+ public NiciraNvpTag(String scope, String tag) {
+ this.scope = scope;
+ this.tag = tag;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java
new file mode 100644
index 0000000..530352e
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java
@@ -0,0 +1,47 @@
+/** 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.network.nicira;
+
+public class TransportZoneBinding {
+ private String zone_uuid;
+ private String transport_type;
+
+ public TransportZoneBinding() {}
+
+ public TransportZoneBinding(String zone_uuid, String transport_type) {
+ this.zone_uuid = zone_uuid;
+ this.transport_type = transport_type;
+ }
+
+ public String getZone_uuid() {
+ return zone_uuid;
+ }
+
+ public void setZone_uuid(String zone_uuid) {
+ this.zone_uuid = zone_uuid;
+ }
+
+ public String getTransport_type() {
+ return transport_type;
+ }
+
+ public void setTransport_type(String transport_type) {
+ this.transport_type = transport_type;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java
new file mode 100644
index 0000000..a5f0de7
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java
@@ -0,0 +1,43 @@
+/** 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.network.nicira;
+
+public class VifAttachment extends Attachment {
+ private final String type = "VifAttachment";
+ private String vif_uuid;
+
+ public VifAttachment() {
+ }
+
+ public VifAttachment(String vifUuid) {
+ this.vif_uuid = vifUuid;
+ }
+
+ public String getVif_uuid() {
+ return vif_uuid;
+ }
+
+ public void setVif_uuid(String vif_uuid) {
+ this.vif_uuid = vif_uuid;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
new file mode 100644
index 0000000..ae7b37e
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
@@ -0,0 +1,240 @@
+package com.cloud.network.resource;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateLogicalSwitchAnswer;
+import com.cloud.agent.api.CreateLogicalSwitchCommand;
+import com.cloud.agent.api.CreateLogicalSwitchPortAnswer;
+import com.cloud.agent.api.CreateLogicalSwitchPortCommand;
+import com.cloud.agent.api.DeleteLogicalSwitchAnswer;
+import com.cloud.agent.api.DeleteLogicalSwitchCommand;
+import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer;
+import com.cloud.agent.api.DeleteLogicalSwitchPortCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupNiciraNvpCommand;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.network.nicira.LogicalSwitch;
+import com.cloud.network.nicira.LogicalSwitchPort;
+import com.cloud.network.nicira.NiciraNvpApi;
+import com.cloud.network.nicira.NiciraNvpApiException;
+import com.cloud.network.nicira.NiciraNvpTag;
+import com.cloud.network.nicira.TransportZoneBinding;
+import com.cloud.network.nicira.VifAttachment;
+import com.cloud.resource.ServerResource;
+
+public class NiciraNvpResource implements ServerResource {
+ private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class);
+
+ private String _name;
+ private String _ip;
+ private String _adminuser;
+ private String _adminpass;
+ private String _guid;
+ private String _zoneId;
+
+ private NiciraNvpApi _niciraNvpApi;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+
+ _name = (String) params.get("name");
+ if (_name == null) {
+ throw new ConfigurationException("Unable to find name");
+ }
+
+ _ip = (String) params.get("ip");
+ if (_ip == null) {
+ throw new ConfigurationException("Unable to find IP");
+ }
+
+ _adminuser = (String) params.get("adminuser");
+ if (_adminuser == null) {
+ throw new ConfigurationException("Unable to find admin username");
+ }
+
+ _adminpass = (String) params.get("adminpass");
+ if (_adminpass == null) {
+ throw new ConfigurationException("Unable to find admin password");
+ }
+
+ _guid = (String)params.get("guid");
+ if (_guid == null) {
+ throw new ConfigurationException("Unable to find the guid");
+ }
+
+ _zoneId = (String) params.get("zoneId");
+ if (_zoneId == null) {
+ throw new ConfigurationException("Unable to find zone");
+ }
+
+ try {
+ _niciraNvpApi = new NiciraNvpApi(_ip, _adminuser, _adminpass);
+ } catch (NiciraNvpApiException e) {
+ throw new ConfigurationException(e.getMessage());
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ // Think up a better name for this Type?
+ return Host.Type.L2Networking;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupNiciraNvpCommand sc = new StartupNiciraNvpCommand();
+ sc.setGuid(_guid);
+ sc.setName(_name);
+ sc.setDataCenter(_zoneId);
+ sc.setPod("");
+ sc.setPrivateIpAddress("");
+ sc.setStorageIpAddress("");
+ sc.setVersion("");
+ return new StartupCommand[] { sc };
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ return new PingCommand(Host.Type.L2Networking, id);
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof ReadyCommand) {
+ return executeRequest((ReadyCommand) cmd);
+ }
+ else if (cmd instanceof MaintainCommand) {
+ return executeRequest((MaintainCommand)cmd);
+ }
+ else if (cmd instanceof CreateLogicalSwitchCommand) {
+ return executeRequest((CreateLogicalSwitchCommand)cmd);
+ }
+ else if (cmd instanceof DeleteLogicalSwitchCommand) {
+ return executeRequest((DeleteLogicalSwitchCommand) cmd);
+ }
+ else if (cmd instanceof CreateLogicalSwitchPortCommand) {
+ return executeRequest((CreateLogicalSwitchPortCommand) cmd);
+ }
+ else if (cmd instanceof DeleteLogicalSwitchPortCommand) {
+ return executeRequest((DeleteLogicalSwitchPortCommand) cmd);
+ }
+ s_logger.debug("Received unsupported command " + cmd.toString());
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+
+ @Override
+ public void disconnected() {
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ return null;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ }
+
+ private Answer executeRequest(CreateLogicalSwitchCommand cmd) {
+ LogicalSwitch logicalSwitch = new LogicalSwitch();
+ logicalSwitch.setDisplay_name("lswitch-" + cmd.getOwnerName());
+ logicalSwitch.setPort_isolation_enabled(false);
+
+ // Set transport binding
+ List<TransportZoneBinding> ltzb = new ArrayList<TransportZoneBinding>();
+ ltzb.add(new TransportZoneBinding(cmd.getTransportUuid(), cmd.getTransportType()));
+ logicalSwitch.setTransport_zones(ltzb);
+
+ // Tags set to scope cs_account and account name
+ List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
+ tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName()));
+ logicalSwitch.setTags(tags);
+
+ try {
+ logicalSwitch = _niciraNvpApi.createLogicalSwitch(logicalSwitch);
+ return new CreateLogicalSwitchAnswer(cmd, true, "Logicalswitch " + logicalSwitch.getUuid() + " created", logicalSwitch.getUuid());
+ } catch (NiciraNvpApiException e) {
+ return new CreateLogicalSwitchAnswer(cmd, e);
+ }
+
+ }
+
+ private Answer executeRequest(DeleteLogicalSwitchCommand cmd) {
+ try {
+ _niciraNvpApi.deleteLogicalSwitch(cmd.getLogicalSwitchUuid());
+ return new DeleteLogicalSwitchAnswer(cmd, true, "Logicalswitch " + cmd.getLogicalSwitchUuid() + " deleted");
+ } catch (NiciraNvpApiException e) {
+ return new DeleteLogicalSwitchAnswer(cmd, e);
+ }
+ }
+
+ private Answer executeRequest(CreateLogicalSwitchPortCommand cmd) {
+ String logicalSwitchUuid = cmd.getLogicalSwitchUuid();
+ String attachmentUuid = cmd.getAttachmentUuid();
+
+ try {
+ // Tags set to scope cs_account and account name
+ List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
+ tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName()));
+
+ LogicalSwitchPort logicalSwitchPort = new LogicalSwitchPort(attachmentUuid, tags, true);
+ LogicalSwitchPort newPort = _niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, logicalSwitchPort);
+ _niciraNvpApi.modifyLogicalSwitchPortAttachment(cmd.getLogicalSwitchUuid(), newPort.getUuid(), new VifAttachment(attachmentUuid));
+ return new CreateLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + newPort.getUuid() + " created", newPort.getUuid());
+ } catch (NiciraNvpApiException e) {
+ return new CreateLogicalSwitchPortAnswer(cmd, e);
+ }
+
+ }
+
+ private Answer executeRequest(DeleteLogicalSwitchPortCommand cmd) {
+ try {
+ _niciraNvpApi.deleteLogicalSwitchPort(cmd.getLogicalSwitchUuid(), cmd.getLogicalSwitchPortUuid());
+ return new DeleteLogicalSwitchPortAnswer(cmd, true, "Logical switch port " + cmd.getLogicalSwitchPortUuid() + " deleted");
+ } catch (NiciraNvpApiException e) {
+ return new DeleteLogicalSwitchPortAnswer(cmd, e);
+ }
+ }
+
+ private Answer executeRequest(ReadyCommand cmd) {
+ return new ReadyAnswer(cmd);
+ }
+
+ private Answer executeRequest(MaintainCommand cmd) {
+ return new MaintainAnswer(cmd);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index d031fee..7bfa715 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -12,11 +12,14 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.guru;
+import java.util.List;
+
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.event.EventTypes;
@@ -38,7 +41,10 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.IsolationMethod;
@Local(value=NetworkGuru.class)
public class OvsGuestNetworkGuru extends GuestNetworkGuru {
@@ -46,6 +52,28 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
@Inject NetworkManager _externalNetworkManager;
@Inject OvsTunnelManager _ovsTunnelMgr;
+
+ OvsGuestNetworkGuru() {
+ super();
+ _isolationMethods = new IsolationMethod[] { IsolationMethod.GRE, IsolationMethod.L3, IsolationMethod.VLAN };
+ }
+
+ protected boolean canHandle(NetworkOffering offering,
+ final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
+ // This guru handles only Guest Isolated network that supports Source
+ // nat service
+ if (networkType == NetworkType.Advanced
+ && isMyTrafficType(offering.getTrafficType())
+ && offering.getGuestType() == Network.GuestType.Isolated
+ && isMyIsolationMethod(physicalNetwork)) {
+ return true;
+ } else {
+ s_logger.trace("We only take care of 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) {
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/server/src/com/cloud/host/dao/HostDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/server/src/com/cloud/host/dao/HostDaoImpl.java
index a6d794d..ab1e77e 100755
--- a/server/src/com/cloud/host/dao/HostDaoImpl.java
+++ b/server/src/com/cloud/host/dao/HostDaoImpl.java
@@ -354,7 +354,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
txn.start();
SearchCriteria<HostVO> sc = UnmanagedApplianceSearch.create();
sc.setParameters("lastPinged", lastPingSecondsAfter);
- sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.PxeServer, Type.TrafficMonitor);
+ sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.PxeServer, Type.TrafficMonitor, Type.L2Networking);
List<HostVO> hosts = lockRows(sc, null, true);
for (HostVO host : hosts) {
@@ -493,7 +493,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
List<HostVO> result = new ArrayList<HostVO>();
ResultSet rs = null;
try {
- String sql = "select h.id from host h left join cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage') and (h.cluster_id is null or c.managed_state = 'Managed') ;" ;
+ String sql = "select h.id from host h left join cluster c on h.cluster_id=c.id where h.mgmt_server_id is not null and h.last_ping < ? and h.status in ('Up', 'Updating', 'Disconnected', 'Connecting') and h.type not in ('ExternalFirewall', 'ExternalLoadBalancer', 'TrafficMonitor', 'SecondaryStorage', 'LocalSecondaryStorage', 'L2Networking') and (h.cluster_id is null or c.managed_state = 'Managed') ;" ;
pstmt = txn.prepareStatement(sql);
pstmt.setLong(1, timeout);
rs = pstmt.executeQuery();
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index a515194..bd547ab 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -28,12 +28,18 @@ import com.cloud.storage.dao.VMTemplateDetailsDao;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
@Inject VMTemplateDetailsDao _templateDetailsDao;
+ @Inject NicDao _nicDao;
+ @Inject VMInstanceDao _virtualMachineDao;
protected HypervisorGuruBase() {
super();
@@ -55,6 +61,10 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIsolationuri(profile.getIsolationUri());
to.setNetworkRateMbps(profile.getNetworkRate());
to.setName(profile.getName());
+
+ // Workaround to make sure the TO has the UUID we need for Niciri integration
+ NicVO nicVO = _nicDao.findById(profile.getId());
+ to.setUuid(nicVO.getUuid());
return to;
}
@@ -92,6 +102,11 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
details.putAll(detailsInVm);
}
to.setDetails(details);
+
+ // Workaround to make sure the TO has the UUID we need for Niciri integration
+ VMInstanceVO vmInstance = _virtualMachineDao.findById(to.getId());
+ to.setUuid(vmInstance.getUuid());
+
return to;
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/server/src/com/cloud/network/ExternalNetworkDeviceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalNetworkDeviceManager.java b/server/src/com/cloud/network/ExternalNetworkDeviceManager.java
index 115de1b..dec0608 100644
--- a/server/src/com/cloud/network/ExternalNetworkDeviceManager.java
+++ b/server/src/com/cloud/network/ExternalNetworkDeviceManager.java
@@ -39,6 +39,8 @@ public interface ExternalNetworkDeviceManager extends Manager {
public static final NetworkDevice NetscalerSDXLoadBalancer = new NetworkDevice("NetscalerSDXLoadBalancer", Network.Provider.Netscaler.getName());
public static final NetworkDevice F5BigIpLoadBalancer = new NetworkDevice("F5BigIpLoadBalancer", Network.Provider.F5BigIp.getName());
public static final NetworkDevice JuniperSRXFirewall = new NetworkDevice("JuniperSRXFirewall", Network.Provider.JuniperSRX.getName());
+ public static final NetworkDevice NiciraNvp = new NetworkDevice("NiciraNvp", Network.Provider.NiciraNvp.getName());
+
public NetworkDevice(String deviceName, String ntwkServiceprovider) {
_name = deviceName;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/79c7da07/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index f26d40d..d04a140 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -1455,7 +1455,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 || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch))) {
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (configs.size() > 0) {
if (s_logger.isDebugEnabled()) {
@@ -1721,6 +1722,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
Integer networkRate = getNetworkRate(config.getId(), null);
to.setNetworkRateMbps(networkRate);
+
+ to.setUuid(config.getUuid());
return to;
}