You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/04/09 09:45:38 UTC
[2/8] git commit: updated refs/heads/master to 770297e
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java b/plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java
new file mode 100644
index 0000000..c5407bc
--- /dev/null
+++ b/plugins/network-elements/bigswitch/src/com/cloud/network/resource/BigSwitchBcfResource.java
@@ -0,0 +1,589 @@
+//
+// 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.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.UpdateBcfRouterCommand;
+import com.cloud.agent.api.BcfAnswer;
+import com.cloud.agent.api.CacheBcfTopologyCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateBcfRouterCommand;
+import com.cloud.agent.api.CreateBcfRouterInterfaceCommand;
+import com.cloud.agent.api.CreateBcfSegmentCommand;
+import com.cloud.agent.api.CreateBcfAttachmentCommand;
+import com.cloud.agent.api.CreateBcfStaticNatCommand;
+import com.cloud.agent.api.DeleteBcfSegmentCommand;
+import com.cloud.agent.api.DeleteBcfAttachmentCommand;
+import com.cloud.agent.api.DeleteBcfStaticNatCommand;
+import com.cloud.agent.api.GetControllerDataAnswer;
+import com.cloud.agent.api.GetControllerDataCommand;
+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.StartupBigSwitchBcfCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.SyncBcfTopologyCommand;
+import com.cloud.agent.api.UpdateBcfAttachmentCommand;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.network.bigswitch.AclData;
+import com.cloud.network.bigswitch.BigSwitchBcfApi;
+import com.cloud.network.bigswitch.BigSwitchBcfApiException;
+import com.cloud.network.bigswitch.Capabilities;
+import com.cloud.network.bigswitch.ControlClusterStatus;
+import com.cloud.network.bigswitch.ControllerData;
+import com.cloud.network.bigswitch.FloatingIpData;
+import com.cloud.network.bigswitch.NetworkData;
+import com.cloud.network.bigswitch.AttachmentData;
+import com.cloud.network.bigswitch.RouterData;
+import com.cloud.network.bigswitch.RouterInterfaceData;
+import com.cloud.network.bigswitch.TopologyData;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.component.ManagerBase;
+
+public class BigSwitchBcfResource extends ManagerBase implements ServerResource {
+ private static final Logger s_logger = Logger.getLogger(BigSwitchBcfResource.class);
+
+ private String _name;
+ private String _guid;
+ private String _zoneId;
+ private int _numRetries;
+
+ private BigSwitchBcfApi _bigswitchBcfApi;
+ private TopologyData _latestTopology = null;
+ private boolean initTopologySyncDone = false;
+
+ protected BigSwitchBcfApi createBigSwitchBcfApi() {
+ return new BigSwitchBcfApi();
+ }
+
+ @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");
+ }
+
+ _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");
+ }
+
+ _numRetries = 2;
+
+ String hostname = (String)params.get("hostname");
+ if (hostname == null) {
+ throw new ConfigurationException("Missing host name from params: " + params);
+ }
+
+ String username = (String) params.get("username");
+ if (username == null) {
+ throw new ConfigurationException("Missing user name from params: " + params);
+ }
+
+ String password = (String) params.get("password");
+ if (password == null) {
+ throw new ConfigurationException("Missing password from params: " + params);
+ }
+
+ Boolean nat = Boolean.parseBoolean((String) params.get("nat"));
+ if (nat == null) {
+ throw new ConfigurationException("Missing password from params: " + params);
+ }
+
+ _bigswitchBcfApi = createBigSwitchBcfApi();
+ _bigswitchBcfApi.setControllerAddress(hostname);
+ _bigswitchBcfApi.setControllerUsername(username);
+ _bigswitchBcfApi.setControllerPassword(password);
+ _bigswitchBcfApi.setControllerNat(nat);
+ _bigswitchBcfApi.setZoneId(_zoneId);
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ return Host.Type.L2Networking;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupBigSwitchBcfCommand sc = new StartupBigSwitchBcfCommand();
+ 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) {
+ if(!initTopologySyncDone && _latestTopology != null){
+ initTopologySyncDone = true;
+ if(_bigswitchBcfApi.isNatEnabled()){
+ try{
+ executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
+ } catch(Exception e){
+ s_logger.error("BigSwitch BCF sync error", e);
+ }
+ } else {
+ try{
+ executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
+ } catch (Exception e){
+ s_logger.error("BigSwitch BCF sync error", e);
+ }
+ }
+ }
+ try {
+ ControlClusterStatus ccs = _bigswitchBcfApi.getControlClusterStatus();
+ if (!ccs.getStatus()) {
+ s_logger.error("ControlCluster state is not ready: " + ccs.getStatus());
+ return null;
+ }
+ if (ccs.isTopologySyncRequested()) {
+ if(_latestTopology != null) {
+ if(_bigswitchBcfApi.isNatEnabled()){
+ executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
+ } else {
+ executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
+ }
+ } else {
+ s_logger.debug("topology sync needed but no topology history");
+ }
+ }
+ } catch (BigSwitchBcfApiException e) {
+ s_logger.error("getControlClusterStatus failed", e);
+ return null;
+ }
+ try {
+ Capabilities cap = _bigswitchBcfApi.getCapabilities();
+
+ // TODO: update controller status display, enable/disable service accordingly
+ if (cap.isTopologySyncRequested()) {
+ if(_latestTopology != null) {
+ if(_bigswitchBcfApi.isNatEnabled()){
+ executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
+ } else {
+ executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
+ }
+ }
+ }
+
+ } catch (BigSwitchBcfApiException e) {
+ s_logger.error("getCapabilities failed", e);
+ }
+ return new PingCommand(Host.Type.L2Networking, id);
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ return executeRequest(cmd, _numRetries);
+ }
+
+ public Answer executeRequest(Command cmd, int numRetries) {
+ if (cmd instanceof ReadyCommand) {
+ return executeRequest((ReadyCommand)cmd);
+ } else if (cmd instanceof MaintainCommand) {
+ return executeRequest((MaintainCommand)cmd);
+ } else if (cmd instanceof CreateBcfSegmentCommand) {
+ _latestTopology = ((CreateBcfSegmentCommand) cmd).getTopology();
+ return executeRequest((CreateBcfSegmentCommand)cmd, numRetries);
+ } else if (cmd instanceof DeleteBcfSegmentCommand) {
+ _latestTopology = ((DeleteBcfSegmentCommand) cmd).getTopology();
+ return executeRequest((DeleteBcfSegmentCommand)cmd, numRetries);
+ } else if (cmd instanceof CreateBcfAttachmentCommand) {
+ _latestTopology = ((CreateBcfAttachmentCommand) cmd).getTopology();
+ return executeRequest((CreateBcfAttachmentCommand)cmd, numRetries);
+ } else if (cmd instanceof DeleteBcfAttachmentCommand) {
+ _latestTopology = ((DeleteBcfAttachmentCommand) cmd).getTopology();
+ return executeRequest((DeleteBcfAttachmentCommand)cmd, numRetries);
+ } else if (cmd instanceof UpdateBcfAttachmentCommand) {
+ _latestTopology = ((UpdateBcfAttachmentCommand) cmd).getTopology();
+ return executeRequest((UpdateBcfAttachmentCommand)cmd, numRetries);
+ } else if (cmd instanceof CreateBcfRouterCommand) {
+ _latestTopology = ((CreateBcfRouterCommand) cmd).getTopology();
+ return executeRequest((CreateBcfRouterCommand)cmd, numRetries);
+ } else if (cmd instanceof CreateBcfRouterInterfaceCommand) {
+ _latestTopology = ((CreateBcfRouterInterfaceCommand) cmd).getTopology();
+ return executeRequest((CreateBcfRouterInterfaceCommand)cmd, numRetries);
+ } else if (cmd instanceof CreateBcfStaticNatCommand) {
+ _latestTopology = ((CreateBcfStaticNatCommand) cmd).getTopology();
+ return executeRequest((CreateBcfStaticNatCommand)cmd, numRetries);
+ } else if (cmd instanceof DeleteBcfStaticNatCommand) {
+ _latestTopology = ((DeleteBcfStaticNatCommand) cmd).getTopology();
+ return executeRequest((DeleteBcfStaticNatCommand)cmd, numRetries);
+ } else if (cmd instanceof UpdateBcfRouterCommand) {
+ _latestTopology = ((UpdateBcfRouterCommand) cmd).getTopology();
+ return executeRequest((UpdateBcfRouterCommand)cmd, numRetries);
+ } else if (cmd instanceof SyncBcfTopologyCommand) {
+ return executeRequest((SyncBcfTopologyCommand)cmd, numRetries);
+ } else if (cmd instanceof CacheBcfTopologyCommand) {
+ return executeRequest((CacheBcfTopologyCommand)cmd, numRetries);
+ } else if (cmd instanceof GetControllerDataCommand) {
+ return executeRequest((GetControllerDataCommand)cmd, numRetries);
+ }
+ 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) {
+ }
+
+ public void setTopology(TopologyData topology){
+ _latestTopology = topology;
+ }
+
+ public TopologyData getTopology(){
+ return _latestTopology;
+ }
+
+ private Answer executeRequest(CreateBcfSegmentCommand cmd, int numRetries) {
+ NetworkData network = new NetworkData();
+ network.getNetwork().setTenantId(cmd.getTenantId());
+ network.getNetwork().setTenantName(cmd.getTenantName());
+ network.getNetwork().setId(cmd.getNetworkId());
+ network.getNetwork().setName(truncate("segment-cloudstack-" + cmd.getNetworkName(), 64));
+ network.getNetwork().setVlan(cmd.getVlan());
+
+ try {
+ String hash =_bigswitchBcfApi.createNetwork(network);
+ return new BcfAnswer(cmd, true, "Segment " + network.getNetwork().getId() + " created", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "Segment " + network.getNetwork().getId() + " created; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+
+ }
+
+ private Answer executeRequest(DeleteBcfSegmentCommand cmd, int numRetries) {
+ try {
+ String hash = _bigswitchBcfApi.deleteNetwork(cmd.get_tenantUuid(), cmd.getNetworkUuid());
+ return new BcfAnswer(cmd, true, "Segment " + cmd.getNetworkUuid() + " deleted", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "Segment " + cmd.getNetworkUuid() + " deleted; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(CreateBcfAttachmentCommand cmd, int numRetries) {
+ AttachmentData attachment = new AttachmentData();
+ attachment.getAttachment().setId(cmd.getNicId());
+ attachment.getAttachment().setHostId(cmd.getPortId());
+ attachment.getAttachment().setTenantName(cmd.getTenantName());
+ attachment.getAttachment().setVlan(cmd.getVlan());
+ attachment.getAttachment().addIpv4(cmd.getIpv4());
+ attachment.getAttachment().setMac(cmd.getMac());
+
+ try {
+ String hash = _bigswitchBcfApi.createAttachment(cmd.getTenantId(), cmd.getNetworkId(), attachment);
+ return new BcfAnswer(cmd, true, "network attachment " + cmd.getPortId() + " created", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "network attachment " + cmd.getPortId() + " created; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(DeleteBcfAttachmentCommand cmd, int numRetries) {
+ String nicName = cmd.getAttachmentId();
+ try {
+ String hash = _bigswitchBcfApi.deleteAttachment(cmd.getTenantId(), cmd.getNetworkId(), nicName);
+ return new BcfAnswer(cmd, true, "network attachment " + nicName + " deleted", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "network attachment " + nicName + " deleted; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(UpdateBcfAttachmentCommand cmd, int numRetries) {
+ AttachmentData attachment = new AttachmentData();
+ attachment.getAttachment().setId(cmd.getAttachmentId());
+ attachment.getAttachment().setTenantName(cmd.getTenantId());
+
+ try {
+ String hash = _bigswitchBcfApi.modifyAttachment(cmd.getTenantId(), cmd.getNetworkId(), attachment);
+ return new BcfAnswer(cmd, true, "Network attachment " + cmd.getAttachmentId() + " updated", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "Network attachment " + cmd.getAttachmentId() + " updated; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(CreateBcfStaticNatCommand cmd, int numRetries) {
+ FloatingIpData fip = new FloatingIpData();
+ fip.setTenantId(cmd.get_tenantId());
+ fip.setNetworkId(cmd.get_networkId());
+ fip.setFixedIp(cmd.get_privateIp());
+ fip.setFloatingIpAndId(cmd.get_publicIp());
+ fip.setMac(cmd.get_mac());
+
+ try {
+ String hash = _bigswitchBcfApi.createFloatingIp(cmd.get_tenantId(), fip);
+ return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + ":" +
+ cmd.get_privateIp() + " created", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + ":" +
+ cmd.get_privateIp() + " created; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(DeleteBcfStaticNatCommand cmd, int numRetries) {
+ try {
+ String hash = _bigswitchBcfApi.deleteFloatingIp(cmd.get_tenantId(), cmd.get_floatingIpId());
+ return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + " deleted", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + " deleted; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(CreateBcfRouterCommand cmd, int numRetries) {
+ RouterData router = new RouterData(cmd.get_tenantId());
+ try {
+ String hash;
+ hash = _bigswitchBcfApi.createRouter(cmd.get_tenantId(), router);
+
+ return new BcfAnswer(cmd, true, "router " + cmd.get_tenantId() +
+ " created.", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, " created; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(CreateBcfRouterInterfaceCommand cmd, int numRetries) {
+ RouterInterfaceData routerInterface = new RouterInterfaceData(cmd.get_tenantId(),
+ cmd.get_gateway(), cmd.get_cidr(), cmd.get_networkId(), cmd.get_networkName());
+ try {
+ String hash;
+ hash = _bigswitchBcfApi.createRouterInterface(cmd.get_tenantId(),
+ cmd.get_tenantId(), routerInterface);
+
+ return new BcfAnswer(cmd, true, "router " + cmd.get_tenantId() +
+ " created.", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, " created; topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ }
+ }
+
+ private Answer executeRequest(UpdateBcfRouterCommand cmd, int numRetries){
+ RouterData routerData = new RouterData(cmd.getTenantId());
+
+ List<AclData> acls = new ArrayList<AclData>();
+ acls.addAll(cmd.getAcls());
+ routerData.getRouter().getAcls().addAll(acls);
+
+ routerData.getRouter().addExternalGateway(cmd.getPublicIp());
+
+ try {
+ String hash = _bigswitchBcfApi.modifyRouter(cmd.getTenantId(), routerData);
+ return new BcfAnswer(cmd, true, "tenant " + cmd.getTenantId() + " router updated", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (e.is_topologySyncRequested()) {
+ cmd.set_topologySyncRequested(true);
+ return new BcfAnswer(cmd, true, "tenant " + cmd.getTenantId() + " router updated but topology sync required.");
+ } else {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ }
+ } catch (IllegalArgumentException e1){
+ return new BcfAnswer(cmd, false, "Illegal argument in BCF router update");
+ }
+ }
+
+ private Answer executeRequest(SyncBcfTopologyCommand cmd, int numRetries) {
+ try {
+ TopologyData topo = _latestTopology;
+ if (!cmd.isNetworkIncluded()) {
+ topo.clearNetworks();
+ }
+ if(!cmd.isRouterIncluded()) {
+ topo.clearRouters();
+ }
+ String hash = _bigswitchBcfApi.syncTopology(topo);
+ if(!initTopologySyncDone){
+ initTopologySyncDone=true;
+ }
+ return new BcfAnswer(cmd, true, "BCF topology synced", hash);
+ } catch (BigSwitchBcfApiException e) {
+ if (numRetries > 0) {
+ return retry(cmd, --numRetries);
+ } else {
+ return new BcfAnswer(cmd, e);
+ }
+ } catch (IllegalArgumentException e1){
+ return new BcfAnswer(cmd, false, "Illegal argument in BCF topology sync");
+ }
+ }
+
+ private Answer executeRequest(CacheBcfTopologyCommand cmd, int numRetries) {
+ _latestTopology = cmd.getTopology();
+ return new Answer(cmd, true, "BCF topology cached");
+ }
+
+ private Answer executeRequest(GetControllerDataCommand cmd, int numRetries) {
+ ControllerData controller = _bigswitchBcfApi.getControllerData();
+ return new GetControllerDataAnswer(cmd,
+ controller.getIpAddress(),
+ controller.isMaster());
+ }
+
+ private Answer executeRequest(ReadyCommand cmd) {
+ return new ReadyAnswer(cmd);
+ }
+
+ private Answer executeRequest(MaintainCommand cmd) {
+ return new MaintainAnswer(cmd);
+ }
+
+ private Answer retry(Command cmd, int numRetries) {
+ s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries);
+ return executeRequest(cmd, numRetries);
+ }
+
+ private String truncate(String string, int length) {
+ if (string.length() <= length) {
+ return string;
+ } else {
+ return string.substring(0, length);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java b/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java
new file mode 100644
index 0000000..5d40e5d
--- /dev/null
+++ b/plugins/network-elements/bigswitch/test/com/cloud/network/bigswitch/BigSwitchApiTest.java
@@ -0,0 +1,433 @@
+//
+// 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.bigswitch;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.UUID;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+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.params.HttpClientParams;
+import org.apache.http.HttpStatus;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.gson.reflect.TypeToken;
+
+public class BigSwitchApiTest {
+ BigSwitchBcfApi _api;
+ HttpClient _client = mock(HttpClient.class);
+ HttpMethod _method;
+
+ @Before
+ public void setUp() {
+ HttpClientParams hmp = mock(HttpClientParams.class);
+ when(_client.getParams()).thenReturn(hmp);
+ _api = new BigSwitchBcfApi(){
+ @Override
+ protected HttpClient createHttpClient() {
+ return _client;
+ }
+
+ @Override
+ protected HttpMethod createMethod(String type, String uri, int port) {
+ return _method;
+ }
+ };
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithoutHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress(null);
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithEmptyHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithoutUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername(null);
+ _api.setControllerPassword("mypassword");
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithEmptyUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("");
+ _api.setControllerPassword("mypassword");
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithoutPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword(null);
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectWithEmptyPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("");
+ _api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithoutHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress(null);
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithEmptyHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithoutUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername(null);
+ _api.setControllerPassword("mypassword");
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithEmptyUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("");
+ _api.setControllerPassword("mypassword");
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithoutPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword(null);
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectWithEmptyPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("");
+ _api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithoutHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress(null);
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeDeleteObject("/");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithEmptyHostname() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("mypassword");
+ _api.executeDeleteObject("/");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithoutUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername(null);
+ _api.setControllerPassword("mypassword");
+ _api.executeDeleteObject("/");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithEmptyUsername() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("");
+ _api.setControllerPassword("mypassword");
+ _api.executeDeleteObject("/");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithoutPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword(null);
+ _api.executeDeleteObject("/");
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectWithEmptyPassword() throws BigSwitchBcfApiException {
+ _api.setControllerAddress("10.10.0.10");
+ _api.setControllerUsername("myname");
+ _api.setControllerPassword("");
+ _api.executeDeleteObject("/");
+ }
+
+ @Test
+ public void executeMethodTestOK() throws BigSwitchBcfApiException, HttpException, IOException {
+ GetMethod gm = mock(GetMethod.class);
+ when(gm.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ _api.executeMethod(gm);
+ verify(gm, times(1)).getStatusCode();
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void executeMethodTestUnauthorized() throws BigSwitchBcfApiException, IOException {
+ GetMethod gm = mock(GetMethod.class);
+ when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
+ when(gm.getStatusCode()).thenReturn(HttpStatus.SC_UNAUTHORIZED);
+ _api.executeMethod(gm);
+ }
+
+ @Test
+ public void testExecuteCreateObjectOK() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PostMethod.class);
+ when(_method.getResponseHeader("X-BSN-BVS-HASH-MATCH")).thenReturn(new Header("X-BSN-BVS-HASH-MATCH", UUID.randomUUID().toString()));
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ String hash = _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);assertNotEquals(hash, "");
+ assertNotEquals(hash, BigSwitchBcfApi.HASH_CONFLICT);
+ assertNotEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectConflict() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PostMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
+ _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test
+ public void testExecuteCreateObjectSlave() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PostMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
+ String hash = _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
+ assertEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
+ assertEquals(_api.getControllerData().isMaster(), false);
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectFailure() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PostMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ Header header = mock(Header.class);
+ when(header.getValue()).thenReturn("text/html");
+ when(_method.getResponseHeader("Content-type")).thenReturn(header);
+ when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
+ when(_method.isRequestSent()).thenReturn(true);
+ try {
+ _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteCreateObjectException() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
+ _method = mock(PostMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ Header header = mock(Header.class);
+ when(header.getValue()).thenReturn("text/html");
+ when(_method.getResponseHeader("Content-type")).thenReturn(header);
+ when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
+ try {
+ _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test
+ public void testExecuteUpdateObjectOK() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PutMethod.class);
+ when(_method.getResponseHeader("X-BSN-BVS-HASH-MATCH")).thenReturn(new Header("X-BSN-BVS-HASH-MATCH", UUID.randomUUID().toString()));
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ String hash = _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);
+ assertNotEquals(hash, "");
+ assertNotEquals(hash, BigSwitchBcfApi.HASH_CONFLICT);
+ assertNotEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectConflict() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PutMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
+ _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
+ }
+
+ @Test
+ public void testExecuteUpdateObjectSlave() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PutMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
+ String hash = _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
+ assertEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectFailure() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PutMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ Header header = mock(Header.class);
+ when(header.getValue()).thenReturn("text/html");
+ when(_method.getResponseHeader("Content-type")).thenReturn(header);
+ when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
+ when(_method.isRequestSent()).thenReturn(true);
+ try {
+ _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteUpdateObjectException() throws BigSwitchBcfApiException, IOException {
+ NetworkData network = new NetworkData();
+ _method = mock(PutMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ when(_client.executeMethod((HttpMethod)any())).thenThrow(new IOException());
+ try {
+ _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test
+ public void testExecuteDeleteObject() throws BigSwitchBcfApiException, IOException {
+ _method = mock(DeleteMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ _api.executeDeleteObject("/");
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectFailure() throws BigSwitchBcfApiException, IOException {
+ _method = mock(DeleteMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ Header header = mock(Header.class);
+ when(header.getValue()).thenReturn("text/html");
+ when(_method.getResponseHeader("Content-type")).thenReturn(header);
+ when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
+ when(_method.isRequestSent()).thenReturn(true);
+ try {
+ _api.executeDeleteObject("/");
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test(expected = BigSwitchBcfApiException.class)
+ public void testExecuteDeleteObjectException() throws BigSwitchBcfApiException, IOException {
+ _method = mock(DeleteMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
+ try {
+ _api.executeDeleteObject("/");
+ } finally {
+ verify(_method, times(1)).releaseConnection();
+ }
+ }
+
+ @Test
+ public void testExecuteRetrieveControllerMasterStatus() throws BigSwitchBcfApiException, IOException {
+ _method = mock(GetMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
+ when(((HttpMethodBase)_method).getResponseBodyAsString(2048)).thenReturn("{'healthy': true, 'topologySyncRequested': false}");
+ _api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
+ }.getType(), "/", null);
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);
+ assertEquals(_api.getControllerData().isMaster(), true);
+ }
+
+ @Test
+ public void testExecuteRetrieveControllerMasterStatusWithTopoConflict() throws BigSwitchBcfApiException, IOException {
+ _method = mock(GetMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
+ when(((HttpMethodBase)_method).getResponseBodyAsString(2048)).thenReturn("{'healthy': true, 'topologySyncRequested': true}");
+ _api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
+ }.getType(), "/", null);
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);
+ assertEquals(_api.getControllerData().isMaster(), true);
+ }
+
+ @Test
+ public void testExecuteRetrieveControllerSlaveStatus() throws BigSwitchBcfApiException, IOException {
+ _method = mock(GetMethod.class);
+ when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
+ when(((HttpMethodBase)_method).getResponseBodyAsString(1024)).thenReturn("{'healthy': true, 'topologySyncRequested': false}");
+ _api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
+ }.getType(), "/", null);
+ verify(_method, times(1)).releaseConnection();
+ verify(_client, times(1)).executeMethod(_method);
+ assertEquals(_api.getControllerData().isMaster(), false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java b/plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java
new file mode 100644
index 0000000..005e2f6
--- /dev/null
+++ b/plugins/network-elements/bigswitch/test/com/cloud/network/resource/BigSwitchBcfResourceTest.java
@@ -0,0 +1,431 @@
+//
+// 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.resource;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.cloud.agent.api.BcfAnswer;
+import com.cloud.agent.api.CreateBcfRouterCommand;
+import com.cloud.agent.api.CreateBcfSegmentCommand;
+import com.cloud.agent.api.CreateBcfAttachmentCommand;
+import com.cloud.agent.api.CreateBcfStaticNatCommand;
+import com.cloud.agent.api.DeleteBcfSegmentCommand;
+import com.cloud.agent.api.DeleteBcfAttachmentCommand;
+import com.cloud.agent.api.DeleteBcfStaticNatCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.SyncBcfTopologyCommand;
+import com.cloud.agent.api.UpdateBcfAttachmentCommand;
+import com.cloud.agent.api.UpdateBcfRouterCommand;
+import com.cloud.host.Host;
+import com.cloud.network.bigswitch.BigSwitchBcfApi;
+import com.cloud.network.bigswitch.BigSwitchBcfApiException;
+import com.cloud.network.bigswitch.Capabilities;
+import com.cloud.network.bigswitch.ControlClusterStatus;
+import com.cloud.network.bigswitch.FloatingIpData;
+import com.cloud.network.bigswitch.NetworkData;
+import com.cloud.network.bigswitch.AttachmentData;
+import com.cloud.network.bigswitch.RouterData;
+import com.cloud.network.bigswitch.TopologyData;
+
+public class BigSwitchBcfResourceTest {
+ BigSwitchBcfApi _bigswitchBcfApi = mock(BigSwitchBcfApi.class);
+ BigSwitchBcfResource _resource;
+ Map<String, Object> _parameters;
+
+ String bcfAddress = "127.0.0.1";
+ String bcfUserName = "myname";
+ String bcfPassword = "mypassword";
+
+ @Before
+ public void setUp() throws ConfigurationException {
+ _resource = new BigSwitchBcfResource() {
+ @Override
+ protected BigSwitchBcfApi createBigSwitchBcfApi() {
+ return _bigswitchBcfApi;
+ }
+ };
+
+ _parameters = new HashMap<String, Object>();
+ _parameters.put("name", "bigswitchbcftestdevice");
+ _parameters.put("hostname", bcfAddress);
+ _parameters.put("guid", "aaaaa-bbbbb-ccccc");
+ _parameters.put("zoneId", "blublub");
+ _parameters.put("username", bcfUserName);
+ _parameters.put("password", bcfPassword);
+ }
+
+ @Test(expected = ConfigurationException.class)
+ public void resourceConfigureFailure() throws ConfigurationException {
+ _resource.configure("BigSwitchBcfResource", Collections.<String, Object> emptyMap());
+ }
+
+ @Test
+ public void resourceConfigure() throws ConfigurationException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ verify(_bigswitchBcfApi).setControllerAddress(bcfAddress);
+ verify(_bigswitchBcfApi).setControllerUsername(bcfUserName);
+ verify(_bigswitchBcfApi).setControllerPassword(bcfPassword);
+
+ assertTrue("bigswitchbcftestdevice".equals(_resource.getName()));
+
+ /* Pretty lame test, but here to assure this plugin fails
+ * if the type name ever changes from L2Networking
+ */
+ assertTrue(_resource.getType() == Host.Type.L2Networking);
+ }
+
+ @Test
+ public void testInitialization() throws ConfigurationException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ StartupCommand[] sc = _resource.initialize();
+ assertTrue(sc.length == 1);
+ assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid()));
+ assertTrue("bigswitchbcftestdevice".equals(sc[0].getName()));
+ assertTrue("blublub".equals(sc[0].getDataCenter()));
+ }
+
+ @Test
+ public void testPingCommandStatusOk() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ ControlClusterStatus ccs = mock(ControlClusterStatus.class);
+ when(ccs.getStatus()).thenReturn(true);
+ when(_bigswitchBcfApi.getControlClusterStatus()).thenReturn(ccs);
+
+ Capabilities cap = mock(Capabilities.class);
+ when(_bigswitchBcfApi.getCapabilities()).thenReturn(cap);
+
+ PingCommand ping = _resource.getCurrentStatus(42);
+ assertTrue(ping != null);
+ assertTrue(ping.getHostId() == 42);
+ assertTrue(ping.getHostType() == Host.Type.L2Networking);
+ }
+
+ @Test
+ public void testPingCommandStatusFail() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ ControlClusterStatus ccs = mock(ControlClusterStatus.class);
+ when(ccs.getStatus()).thenReturn(false);
+ when(_bigswitchBcfApi.getControlClusterStatus()).thenReturn(ccs);
+
+ PingCommand ping = _resource.getCurrentStatus(42);
+ assertTrue(ping == null);
+ }
+
+ @Test
+ public void testPingCommandStatusApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ ControlClusterStatus ccs = mock(ControlClusterStatus.class);
+ when(ccs.getStatus()).thenReturn(false);
+ when(_bigswitchBcfApi.getControlClusterStatus()).thenThrow(new BigSwitchBcfApiException());
+
+ PingCommand ping = _resource.getCurrentStatus(42);
+ assertTrue(ping == null);
+ }
+
+ @Test
+ public void testCreateNetworkRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ NetworkData networkdata = mock(NetworkData.class);
+ NetworkData.Network network = mock(NetworkData.Network.class);
+ when(networkdata.getNetwork()).thenReturn(network);
+ when(network.getId()).thenReturn("cccc");
+ when(_bigswitchBcfApi.createNetwork((NetworkData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ CreateBcfSegmentCommand cmd = new CreateBcfSegmentCommand("tenantid", "tenantname",
+ (String)_parameters.get("guid"), "networkName", 0);
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testCreateNetworkApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ NetworkData networkdata = mock(NetworkData.class);
+ NetworkData.Network network = mock(NetworkData.Network.class);
+ when(networkdata.getNetwork()).thenReturn(network);
+ when(network.getId()).thenReturn("cccc");
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createNetwork((NetworkData)any());
+
+ CreateBcfSegmentCommand cmd = new CreateBcfSegmentCommand("tenantid", "tenantname",
+ (String)_parameters.get("guid"), "networkName", 0);
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).createNetwork((NetworkData)any());
+ }
+
+ @Test
+ public void testDeleteNetworkRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+ when(_bigswitchBcfApi.deleteNetwork((String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand("tenantid", "networkid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testDeleteNetworkApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteNetwork((String)any(), (String)any());
+
+ DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand("tenantid", "networkid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).deleteNetwork((String)any(), (String)any());
+ }
+
+ @Test
+ public void testCreateAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ AttachmentData attachmentData = mock(AttachmentData.class);
+ AttachmentData.Attachment attachment = mock(AttachmentData.Attachment.class);
+ when(attachmentData.getAttachment()).thenReturn(attachment);
+ when(attachment.getId()).thenReturn("eeee");
+ when(_bigswitchBcfApi.createAttachment((String)any(), (String)any(), (AttachmentData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand("tenantid", "tenantname",
+ "networkid", "portid", "nicId", 100, "1.2.3.4", "aa:bb:cc:dd:ee:ff");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testCreateAttachmentApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ AttachmentData attachmentData = mock(AttachmentData.class);
+ AttachmentData.Attachment attachment = mock(AttachmentData.Attachment.class);
+ when(attachmentData.getAttachment()).thenReturn(attachment);
+ when(attachment.getId()).thenReturn("eeee");
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createAttachment((String)any(), (String)any(), (AttachmentData)any());
+
+ CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand("tenantid", "tenantname",
+ "networkid", "portid", "nicId", 100, "1.2.3.4", "aa:bb:cc:dd:ee:ff");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).createAttachment((String)any(), (String)any(), (AttachmentData)any());
+ }
+
+ @Test
+ public void testDeleteAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.deleteAttachment((String)any(), (String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new DeleteBcfAttachmentCommand("networkId", "portid", "tenantid"));
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testDeleteAttachmentException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteAttachment((String)any(), (String)any(), (String)any());
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new DeleteBcfAttachmentCommand("networkId", "portid", "tenantid"));
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).deleteAttachment((String)any(), (String)any(), (String)any());
+ }
+
+ @Test
+ public void testUpdateAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.modifyAttachment((String)any(), (String)any(), (AttachmentData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new UpdateBcfAttachmentCommand("networkId", "portId", "tenantId", "portname"));
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testUpdateAttachmentException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyAttachment((String)any(), (String)any(), (AttachmentData)any());
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new UpdateBcfAttachmentCommand("networkId", "portId", "tenantId", "portname"));
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).modifyAttachment((String)any(), (String)any(), (AttachmentData)any());
+ }
+
+ @Test
+ public void testCreateStaticNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.createFloatingIp((String)any(), (FloatingIpData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ CreateBcfStaticNatCommand cmd = new CreateBcfStaticNatCommand("tenantid",
+ "networkid", "192.168.0.10", "10.4.4.100", "90:b1:1c:49:d8:56");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testCreateStaticNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createFloatingIp((String)any(), (FloatingIpData)any());
+
+ CreateBcfStaticNatCommand cmd = new CreateBcfStaticNatCommand("tenantid",
+ "networkid", "192.168.0.10", "10.4.4.100", "90:b1:1c:49:d8:56");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).createFloatingIp((String)any(), (FloatingIpData)any());
+ }
+
+ @Test
+ public void testDeleteStaticNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.deleteFloatingIp((String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ DeleteBcfStaticNatCommand cmd = new DeleteBcfStaticNatCommand("tenantid",
+ "10.4.4.100");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testDeleteStaticNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteFloatingIp((String)any(), (String)any());
+
+ DeleteBcfStaticNatCommand cmd = new DeleteBcfStaticNatCommand("tenantid",
+ "10.4.4.100");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).deleteFloatingIp((String)any(), (String)any());
+ }
+
+ @Test
+ public void testCreateRouterRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.createRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ CreateBcfRouterCommand cmd = new CreateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testCreateRouterApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createRouter((String)any(), (RouterData)any());
+
+ CreateBcfRouterCommand cmd = new CreateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).createRouter((String)any(), (RouterData)any());
+ }
+
+ @Test
+ public void testCreateSourceNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.modifyRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testCreateSourceNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyRouter((String)any(), (RouterData)any());
+
+ UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).modifyRouter((String)any(), (RouterData)any());
+ }
+
+ @Test
+ public void testDeleteSourceNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ when(_bigswitchBcfApi.modifyRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+
+ UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertTrue(ans.getResult());
+ }
+
+ @Test
+ public void testDeleteSourceNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+
+ doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyRouter((String)any(), (RouterData)any());
+
+ UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
+ assertFalse(ans.getResult());
+ verify(_bigswitchBcfApi, times(3)).modifyRouter((String)any(), (RouterData)any());
+ }
+
+ @Test
+ public void testSyncTopologyRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
+ _resource.configure("BigSwitchBcfResource", _parameters);
+ _resource.setTopology(new TopologyData());
+
+ when(_bigswitchBcfApi.syncTopology((TopologyData)any())).thenThrow(new BigSwitchBcfApiException())
+ .thenReturn(UUID.randomUUID().toString());
+ BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new SyncBcfTopologyCommand(true, false));
+ assertTrue(ans.getResult());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index ccda955..a547e1e 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -65,7 +65,7 @@
<module>network-elements/palo-alto</module>
<module>network-elements/netscaler</module>
<module>network-elements/nicira-nvp</module>
- <module>network-elements/bigswitch-vns</module>
+ <module>network-elements/bigswitch</module>
<module>network-elements/brocade-vcs</module>
<module>network-elements/midonet</module>
<module>network-elements/stratosphere-ssp</module>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/scripts/util/qemu-ivs-ifup
----------------------------------------------------------------------
diff --git a/scripts/util/qemu-ivs-ifup b/scripts/util/qemu-ivs-ifup
new file mode 100755
index 0000000..6830d23
--- /dev/null
+++ b/scripts/util/qemu-ivs-ifup
@@ -0,0 +1,20 @@
+#!/bin/bash
+# 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.
+
+/sbin/ifconfig $1 0.0.0.0 up
+/usr/sbin/ivs-ctl add-port $1
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 65d9a21..ef4c19a 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2401,7 +2401,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (Network.Provider serviceProvider : serviceProviders) {
// return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
if (service == Service.Firewall
- && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp)) {
+ && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp || serviceProvider == Provider.BigSwitchBcf)) {
continue;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/server/src/com/cloud/network/rules/RulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java
index 39e0c1b..1ec531a 100644
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -1406,7 +1406,14 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
throw new InvalidParameterValueException("Vm ip is not set as dnat ip for this public ip");
}
- StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, forRevoke);
+ String srcMac = null;
+ try {
+ srcMac = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
+ } catch (InsufficientAddressCapacityException e) {
+ throw new CloudRuntimeException("Insufficient MAC address for static NAT instantiation.");
+ }
+
+ StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, srcMac, forRevoke);
staticNats.add(staticNat);
return staticNats;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/server/src/com/cloud/network/rules/StaticNatImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/StaticNatImpl.java b/server/src/com/cloud/network/rules/StaticNatImpl.java
index 49e9b78..f07b45e 100644
--- a/server/src/com/cloud/network/rules/StaticNatImpl.java
+++ b/server/src/com/cloud/network/rules/StaticNatImpl.java
@@ -22,6 +22,7 @@ public class StaticNatImpl implements StaticNat {
long networkId;
long sourceIpAddressId;
String destIpAddress;
+ String sourceMacAddress;
boolean forRevoke;
public StaticNatImpl(long accountId, long domainId, long networkId, long sourceIpAddressId, String destIpAddress, boolean forRevoke) {
@@ -31,6 +32,18 @@ public class StaticNatImpl implements StaticNat {
this.networkId = networkId;
this.sourceIpAddressId = sourceIpAddressId;
this.destIpAddress = destIpAddress;
+ this.sourceMacAddress = null;
+ this.forRevoke = forRevoke;
+ }
+
+ public StaticNatImpl(long accountId, long domainId, long networkId, long sourceIpAddressId, String destIpAddress, String sourceMacAddress, boolean forRevoke) {
+ super();
+ this.accountId = accountId;
+ this.domainId = domainId;
+ this.networkId = networkId;
+ this.sourceIpAddressId = sourceIpAddressId;
+ this.destIpAddress = destIpAddress;
+ this.sourceMacAddress = sourceMacAddress;
this.forRevoke = forRevoke;
}
@@ -60,6 +73,11 @@ public class StaticNatImpl implements StaticNat {
}
@Override
+ public String getSourceMacAddress() {
+ return sourceMacAddress;
+ }
+
+ @Override
public boolean isForRevoke() {
return forRevoke;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index abd779b..2a07895 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -224,7 +224,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter,
Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter,
- Provider.Ovs, Provider.NuageVsp);
+ Provider.Ovs, Provider.NuageVsp, Provider.BigSwitchBcf);
int _cleanupInterval;
int _maxNetworks;
@@ -2431,4 +2431,4 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final StaticRoute route = _staticRouteDao.findById(routeId);
return applyStaticRoutesForVpc(route.getVpcId());
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index b4786c0..7665aec 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -150,6 +150,7 @@ DROP TABLE IF EXISTS `cloud`.`nicira_nvp_nic_map`;
DROP TABLE IF EXISTS `cloud`.`s3`;
DROP TABLE IF EXISTS `cloud`.`template_s3_ref`;
DROP TABLE IF EXISTS `cloud`.`nicira_nvp_router_map`;
+DROP TABLE IF EXISTS `cloud`.`external_bigswitch_bcf_devices`;
DROP TABLE IF EXISTS `cloud`.`external_bigswitch_vns_devices`;
DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroup_policy_map`;
DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroup_vm_map`;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01864ef7/setup/db/db/schema-442to450.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-442to450.sql b/setup/db/db/schema-442to450.sql
index 4a8f250..5dee6c6 100644
--- a/setup/db/db/schema-442to450.sql
+++ b/setup/db/db/schema-442to450.sql
@@ -284,6 +284,24 @@ CREATE TABLE `cloud`.`brocade_network_vlan_map` (
CONSTRAINT `fk_brocade_network_vlan_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS `cloud`.`external_bigswitch_vns_devices`;
+CREATE TABLE `cloud`.`external_bigswitch_bcf_devices` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `uuid` varchar(255) UNIQUE,
+ `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which bigswitch bcf device is added',
+ `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this bigswitch bcf device',
+ `device_name` varchar(255) NOT NULL COMMENT 'name of the bigswitch bcf device',
+ `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external bigswitch bcf device',
+ `hostname` varchar(255) NOT NULL COMMENT 'host name or IP address for the bigswitch bcf device',
+ `username` varchar(255) NOT NULL COMMENT 'username for the bigswitch bcf device',
+ `password` varchar(255) NOT NULL COMMENT 'password for the bigswitch bcf device',
+ `nat` boolean NOT NULL COMMENT 'NAT support for the bigswitch bcf device',
+ `hash` varchar(255) NOT NULL COMMENT 'topology hash for the bigswitch bcf networks',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_external_bigswitch_bcf_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
+ CONSTRAINT `fk_external_bigswitch_bcf_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
/* As part of the separation of Xen and XenServer, update the column for the network labels */
ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host';