diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 71bfdb68541..411f620d16f 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -428,6 +428,9 @@ public class EventTypes { public static final String EVENT_EXTERNAL_OVS_CONTROLLER_ADD = "PHYSICAL.OVSCONTROLLER.ADD"; public static final String EVENT_EXTERNAL_OVS_CONTROLLER_DELETE = "PHYSICAL.OVSCONTROLLER.DELETE"; + // external network mapping events + public static final String EVENT_EXTERNAL_VSP_VSD_ADD = "PHYSICAL.NUAGE.VSD.ADD"; + public static final String EVENT_EXTERNAL_VSP_VSD_DELETE = "PHYSICAL.NUAGE.VSD.DELETE"; // AutoScale public static final String EVENT_COUNTER_CREATE = "COUNTER.CREATE"; public static final String EVENT_COUNTER_DELETE = "COUNTER.DELETE"; @@ -824,6 +827,10 @@ public class EventTypes { entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_DELETE, "NvpController"); entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController"); + // external network mapping events + entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_ADD, "NuageVsp"); + entityEventDetails.put(EVENT_EXTERNAL_VSP_VSD_DELETE, "NuageVsp"); + // AutoScale entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class); entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class); diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 885bffef98e..0a08f28104f 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -132,6 +132,9 @@ public interface Network extends ControlledEntity, StateObject, I // add new Ovs provider public static final Provider Ovs = new Provider("Ovs", false); public static final Provider Opendaylight = new Provider("Opendaylight", false); + // add Nuage Vsp Providers + public static final Provider NuageVsp = new Provider("NuageVsp", false); + public static final Provider NuageVspVpc = new Provider("NuageVspVpc", false); private final String name; private final boolean isExternal; diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index 1e4d2294641..1ad33509fb2 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -109,7 +109,8 @@ public class Networks { } } }, - UnDecided(null, null), OpenDaylight("opendaylight", String.class); + UnDecided(null, null), OpenDaylight("opendaylight", String.class), + Vsp("vsp", String.class),; private final String scheme; private final Class type; diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 8cc214e894b..024b3cedec4 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -33,7 +33,7 @@ public interface PhysicalNetwork extends Identity, InternalIdentity { } public enum IsolationMethod { - VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN; + VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN, VSP; } public enum BroadcastDomainRange { diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index b192cb0e78c..bb75b08a273 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -327,6 +327,7 @@ label.add.new.SRX=Add new SRX label.add.new.PA=Add new Palo Alto label.add.new.tier=Add new tier label.add.NiciraNvp.device=Add Nvp Controller +label.add.NuageVsp.device=Add Nuage Virtualized Services Directory (VSD) label.add.physical.network=Add physical network label.add.pod=Add Pod label.add.port.forwarding.rule=Add port forwarding rule @@ -387,6 +388,7 @@ label.anti.affinity.group=Anti-affinity Group label.anti.affinity.groups=Anti-affinity Groups label.anti.affinity=Anti-affinity label.api.key=API Key +label.api.version=API Version label.apply=Apply label.assign.to.load.balancer=Assigning instance to load balancer label.assign=Assign @@ -501,6 +503,7 @@ label.delete.F5=Delete F5 label.delete.gateway=delete gateway label.delete.NetScaler=Delete NetScaler label.delete.NiciraNvp=Remove Nvp Controller +label.delete.NuageVsp=Remove Nuage VSD label.delete.project=Delete project label.delete.SRX=Delete SRX label.delete.PA=Delete Palo Alto @@ -1009,6 +1012,7 @@ label.restart.network=Restart network label.restart.required=Restart required label.restart.vpc=restart VPC label.restore=Restore +label.retry.interval=Retry Interval label.review=Review label.revoke.project.invite=Revoke invitation label.role=Role @@ -1631,6 +1635,7 @@ message.configuring.storage.traffic=Configuring storage traffic message.confirm.action.force.reconnect=Please confirm that you want to force reconnect this host. message.confirm.delete.F5=Please confirm that you would like to delete F5 message.confirm.delete.NetScaler=Please confirm that you would like to delete NetScaler +message.confirm.delete.NuageVsp=Please confirm that you would like to delete Nuage Virtualized Services Directory message.confirm.delete.SRX=Please confirm that you would like to delete SRX message.confirm.delete.PA=Please confirm that you would like to delete Palo Alto message.confirm.destroy.router=Please confirm that you would like to destroy this router diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties index 1ec4e9537a6..d7a0ca9ba6a 100644 --- a/client/WEB-INF/classes/resources/messages_zh_CN.properties +++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties @@ -297,6 +297,7 @@ label.add.new.SRX=\u6dfb\u52a0\u65b0 SRX label.add.new.tier=\u6dfb\u52a0\u65b0\u5c42 label.add.nfs.secondary.staging.store=\u6dfb\u52a0 NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8 label.add.NiciraNvp.device=\u6dfb\u52a0 Nvp \u63a7\u5236\u5668 +label.add.NuageVsp.device=\u6DFB\u52A0 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 (VSD) label.add.OpenDaylight.device=\u6dfb\u52a0 OpenDaylight \u63a7\u5236\u5668 label.add.PA.device=\u6dfb\u52a0 Palo Alto \u8bbe\u5907 label.add.physical.network=\u6dfb\u52a0\u7269\u7406\u7f51\u7edc @@ -355,6 +356,7 @@ label.anti.affinity.groups=\u53cd\u5173\u8054\u6027\u7ec4 label.anti.affinity.group=\u53cd\u5173\u8054\u6027\u7ec4 label.anti.affinity=\u53cd\u5173\u8054\u6027 label.api.key=API \u5bc6\u94a5 +label.api.version=API \u7248\u672C label.apply=\u5e94\u7528 label.app.name=CloudStack label.archive.alerts=\u5b58\u6863\u8b66\u62a5 @@ -508,6 +510,7 @@ label.delete.F5=\u5220\u9664 F5 label.delete.gateway=\u5220\u9664\u7f51\u5173 label.delete.NetScaler=\u5220\u9664 NetScaler label.delete.NiciraNvp=\u79fb\u9664 Nvp \u63a7\u5236\u5668 +label.delete.NuageVsp=\u5220\u9664 Nuage VSD label.delete.OpenDaylight.device=\u5220\u9664 OpenDaylight \u63a7\u5236\u5668 label.delete.PA=\u5220\u9664 Palo Alto label.delete.portable.ip.range=\u5220\u9664\u53ef\u79fb\u690d IP \u8303\u56f4 @@ -1142,6 +1145,7 @@ label.restart.network=\u91cd\u65b0\u542f\u52a8\u7f51\u7edc label.restart.required=\u9700\u8981\u91cd\u65b0\u542f\u52a8 label.restart.vpc=\u91cd\u65b0\u542f\u52a8 VPC label.restore=\u8fd8\u539f +label.retry.interval=\u91cd\u8bd5\u95f4\u9694 label.review=\u6838\u5bf9 label.revoke.project.invite=\u64a4\u9500\u9080\u8bf7 label.role=\u89d2\u8272 @@ -1607,6 +1611,7 @@ message.confirm.dedicate.zone=\u662f\u5426\u8981\u5c06\u6b64\u8d44\u6e90\u57df\u message.confirm.delete.ciscovnmc.resource=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 CiscoVNMC \u8d44\u6e90 message.confirm.delete.F5=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 F5 message.confirm.delete.NetScaler=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 NetScaler +message.confirm.delete.NuageVsp=\u8BF7\u786E\u8BA4\u5220\u9664 Nuage \u865A\u62DF\u670D\u52A1\u76EE\u5F55 message.confirm.delete.PA=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 Palo Alto message.confirm.delete.secondary.staging.store=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664\u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8\u3002 message.confirm.delete.SRX=\u8bf7\u786e\u8ba4\u60a8\u786e\u5b9e\u8981\u5220\u9664 SRX diff --git a/client/pom.xml b/client/pom.xml index 46933d92c02..1621a05babd 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -105,6 +105,11 @@ cloud-plugin-network-netscaler ${project.version} + + org.apache.cloudstack + cloud-plugin-network-vsp + ${project.version} + org.apache.cloudstack cloud-plugin-network-ovs @@ -943,6 +948,21 @@ + + nuagevsp + + + noredist + + + + + org.apache.cloudstack + cloud-plugin-network-vsp + ${project.version} + + + srx diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index b9ac27b0bae..aa03949fa43 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -618,6 +618,13 @@ listBigSwitchVnsDevices=1 addStratosphereSsp=1 deleteStratoshereSsp=1 +#### nuage vsp commands + +addNuageVspDevice=1 +deleteNuageVspDevice=1 +listNuageVspDevices=1 +issueNuageVspResourceRequest=15 + #### host simulator commands configureSimulator=1 diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java index 8e4c7106b95..1420682006c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/OvsVifDriver.java @@ -93,6 +93,10 @@ public class OvsVifDriver extends VifDriverBase { String brName = "OVSTunnel" + vnetId; s_logger.debug("nic " + nic + " needs to be connected to LogicalSwitch " + brName); intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); + } else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vsp) { + intf.setVirtualPortInterfaceId(nic.getUuid()); + String brName = (trafficLabel != null && !trafficLabel.isEmpty()) ? _pifs.get(trafficLabel) : _pifs.get("private"); + intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); } else { intf.defBridgeNet(_bridges.get("guest"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 09227659280..7b73b19e34d 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -931,6 +931,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); vmConfigSpec.getDeviceChange().add(deviceConfigSpec); + setNuageVspVrIpInExtraConfig(vmConfigSpec.getExtraConfig(), nicTo); if (!vmMo.configureVm(vmConfigSpec)) { throw new Exception("Failed to configure devices when running PlugNicCommand"); } @@ -1900,11 +1901,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa newVal.setKey("nvp.iface-id." + nicNum); newVal.setValue(nicTo.getUuid()); extraOptions.add(newVal); + setNuageVspVrIpInExtraConfig(extraOptions, nicTo); } nicNum++; } } + private static void setNuageVspVrIpInExtraConfig(List extraOptions, NicTO nicTo) { + URI broadcastUri = nicTo.getBroadcastUri(); + if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) { + String path = broadcastUri.getPath(); + OptionValue newVal = new OptionValue(); + newVal.setKey("vsp.vr-ip." + nicTo.getMac()); + newVal.setValue(path.substring(1)); + extraOptions.add(newVal); + } + } + private static void configCustomExtraOption(List extraOptions, VirtualMachineTO vmSpec) { // we no longer to validation anymore for (Map.Entry entry : vmSpec.getDetails().entrySet()) { diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index a2b96259e46..71aa01e6b66 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1037,7 +1037,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe assert (BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Vlan); long vlan = Long.parseLong(BroadcastDomainType.getValue(uri)); return enableVlanNetwork(conn, vlan, network); - } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal) { + } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal || + type == BroadcastDomainType.Vsp) { return network.getNetwork(); } else if (uri != null && type == BroadcastDomainType.Vswitch) { String header = uri.toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length()); @@ -1105,6 +1106,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // when bridge is setup for distributed routing vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid()); + // Nuage Vsp needs Virtual Router IP to be passed in the otherconfig + // get the virtual router IP information from broadcast uri + URI broadcastUri = nic.getBroadcastUri(); + if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) { + String path = broadcastUri.getPath(); + vifr.otherConfig.put("vsp-vr-ip", path.substring(1)); + } vifr.network = getNetwork(conn, nic); if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) { @@ -1302,6 +1310,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.nameLabel = vmSpec.getName(); vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY; vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY; + vmr.otherConfig.put("vm_uuid", vmSpec.getUuid()); if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { //scaling is allowed diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml new file mode 100644 index 00000000000..694ebf026ec --- /dev/null +++ b/plugins/network-elements/nuage-vsp/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + cloud-plugin-network-vsp + Apache CloudStack Plugin - Nuage VSP + + org.apache.cloudstack + cloudstack-plugins + 4.5.0-SNAPSHOT + ../../pom.xml + + + + + com.mycila + license-maven-plugin + + + cloudstack-checklicence + process-classes + + check + + + + + + + \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties new file mode 100644 index 00000000000..e51229e199e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/module.properties @@ -0,0 +1,21 @@ +# +# 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. +# + +name=vsp +parent=network \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml new file mode 100644 index 00000000000..c579789e5e7 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/resources/META-INF/cloudstack/vsp/spring-vsp-context.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java new file mode 100644 index 00000000000..6dba8820a87 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/StartupVspCommand.java @@ -0,0 +1,29 @@ +// +// 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.agent.api; + +import com.cloud.host.Host; + +public class StartupVspCommand extends StartupCommand { + + public StartupVspCommand() { + super(Host.Type.L2Networking); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java new file mode 100644 index 00000000000..9327809a0eb --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceAnswer.java @@ -0,0 +1,42 @@ +// +// 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.agent.api; + +public class VspResourceAnswer extends Answer { + + String _resourceInfo; + + public VspResourceAnswer(Command cmd, String resourceInfo, String details) { + super(cmd, true, details); + this._resourceInfo = resourceInfo; + } + + public VspResourceAnswer(VspResourceCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public VspResourceAnswer(VspResourceCommand cmd, Exception e) { + super(cmd, e); + } + + public String getResourceInfo() { + return this._resourceInfo; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java new file mode 100644 index 00000000000..f7e1417aed9 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/VspResourceCommand.java @@ -0,0 +1,82 @@ +// +// 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.agent.api; + +public class VspResourceCommand extends Command { + + String _method; + String _resource; + String _resourceId; + String _childResource; + Object _entityDetails; + String _resourceFilter; + String _proxyUserUuid; + String _proxyUserDomainuuid; + + public VspResourceCommand(String method, String resource, String resourceId, String childResource, Object entityDetails, String resourceFilter, String proxyUserUuid, + String proxyUserDomainuuid) { + super(); + this._method = method; + this._resource = resource; + this._resourceId = resourceId; + this._childResource = childResource; + this._entityDetails = entityDetails; + this._resourceFilter = resourceFilter; + this._proxyUserUuid = proxyUserUuid; + this._proxyUserDomainuuid = proxyUserDomainuuid; + } + + public String getRequestType() { + return _method; + } + + public String getResource() { + return _resource; + } + + public String getResourceId() { + return _resourceId; + } + + public String getChildResource() { + return _childResource; + } + + public Object getEntityDetails() { + return _entityDetails; + } + + public String getResourceFilter() { + return _resourceFilter; + } + + public String getProxyUserUuid() { + return _proxyUserUuid; + } + + public String getProxyUserDomainuuid() { + return _proxyUserDomainuuid; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java new file mode 100644 index 00000000000..2b41266f02c --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ApplyAclRuleVspAnswer extends Answer { + + public ApplyAclRuleVspAnswer(ApplyAclRuleVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ApplyAclRuleVspAnswer(ApplyAclRuleVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java new file mode 100644 index 00000000000..53764669378 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyAclRuleVspCommand.java @@ -0,0 +1,82 @@ +// +// 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.agent.api.element; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Command; + +public class ApplyAclRuleVspCommand extends Command { + + String _networkUuid; + String _networkDomainUuid; + String _vpcOrSubnetUuid; + boolean _isL3Network; + List> _aclRules; + boolean _isVpc; + long _networkId; + + public ApplyAclRuleVspCommand(String networkUuid, String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> aclRules, boolean isVpc, + long networkId) { + super(); + this._networkUuid = networkUuid; + this._networkDomainUuid = networkDomainUuid; + this._vpcOrSubnetUuid = vpcOrSubnetUuid; + this._isL3Network = isL3Network; + this._aclRules = aclRules; + this._isVpc = isVpc; + this._networkId = networkId; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getVpcOrSubnetUuid() { + return _vpcOrSubnetUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public List> getAclRules() { + return _aclRules; + } + + public boolean isVpc() { + return _isVpc; + } + + public long getNetworkId() { + return this._networkId; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java new file mode 100644 index 00000000000..c40c1a312f2 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ApplyStaticNatVspAnswer extends Answer { + + public ApplyStaticNatVspAnswer(ApplyStaticNatVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ApplyStaticNatVspAnswer(ApplyStaticNatVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java new file mode 100644 index 00000000000..b013634e372 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ApplyStaticNatVspCommand.java @@ -0,0 +1,63 @@ +// +// 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.agent.api.element; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Command; + +public class ApplyStaticNatVspCommand extends Command { + + String _networkDomainUuid; + String _vpcOrSubnetUuid; + boolean _isL3Network; + List> _staticNatDetails; + + public ApplyStaticNatVspCommand(String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> staticNatDetails) { + super(); + this._networkDomainUuid = networkDomainUuid; + this._vpcOrSubnetUuid = vpcOrSubnetUuid; + this._isL3Network = isL3Network; + this._staticNatDetails = staticNatDetails; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getVpcOrSubnetUuid() { + return _vpcOrSubnetUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public List> getStaticNatDetails() { + return _staticNatDetails; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java new file mode 100644 index 00000000000..592216e12ee --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.element; + +import com.cloud.agent.api.Answer; + +public class ShutDownVpcVspAnswer extends Answer { + + public ShutDownVpcVspAnswer(ShutDownVpcVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public ShutDownVpcVspAnswer(ShutDownVpcVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java new file mode 100644 index 00000000000..fc05559514c --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/element/ShutDownVpcVspCommand.java @@ -0,0 +1,48 @@ +// +// 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.agent.api.element; + +import com.cloud.agent.api.Command; + +public class ShutDownVpcVspCommand extends Command { + + String _domainUuid; + String _vpcUuid; + + public ShutDownVpcVspCommand(String domainUuid, String vpcUuid) { + super(); + this._domainUuid = domainUuid; + this._vpcUuid = vpcUuid; + } + + public String getDomainUuid() { + return _domainUuid; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java new file mode 100644 index 00000000000..57ecf296cd9 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class DeallocateVmVspAnswer extends Answer { + + public DeallocateVmVspAnswer(Command command, Exception e) { + super(command, e); + } + + public DeallocateVmVspAnswer(DeallocateVmVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java new file mode 100644 index 00000000000..19c904f9f20 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/DeallocateVmVspCommand.java @@ -0,0 +1,91 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class DeallocateVmVspCommand extends Command { + + String _networkUuid; + String _nicFrmDdUuid; + String _nicMacAddress; + String _nicIp4Address; + boolean _isL3Network; + String _vpcUuid; + String _networksDomainUuid; + String _vmInstanceName; + String _vmUuid; + + public DeallocateVmVspCommand(String networkUuid, String nicFrmDdUuid, String nicMacAddress, String nicIp4Address, boolean isL3Network, String vpcUuid, + String networksDomainUuid, String vmInstanceName, String vmUuid) { + super(); + this._networkUuid = networkUuid; + this._nicFrmDdUuid = nicFrmDdUuid; + this._nicMacAddress = nicMacAddress; + this._nicIp4Address = nicIp4Address; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + this._networksDomainUuid = networksDomainUuid; + this._vmInstanceName = vmInstanceName; + this._vmUuid = vmUuid; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getNicFrmDdUuid() { + return _nicFrmDdUuid; + } + + public String getNicMacAddress() { + return _nicMacAddress; + } + + public String getNicIp4Address() { + return _nicIp4Address; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public String getNetworksDomainUuid() { + return _networksDomainUuid; + } + + public String getVmInstanceName() { + return _vmInstanceName; + } + + public String getVmUuid() { + return _vmUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java new file mode 100644 index 00000000000..87e7b328265 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspAnswer.java @@ -0,0 +1,35 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ImplementNetworkVspAnswer extends Answer { + + public ImplementNetworkVspAnswer(Command command, Exception e) { + super(command, e); + } + + public ImplementNetworkVspAnswer(ImplementNetworkVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java new file mode 100644 index 00000000000..0ffbda42a37 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ImplementNetworkVspCommand.java @@ -0,0 +1,124 @@ +// +// 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.agent.api.guru; + +import java.util.Collection; + +import com.cloud.agent.api.Command; + +public class ImplementNetworkVspCommand extends Command { + + String _networkDomainName; + String _networkDomainPath; + String _networkDomainUuid; + String _networkAccountName; + String _networkAccountUuid; + String _networkName; + String _networkCidr; + String _networkGateway; + String _networkUuid; + boolean _isL3Network; + String _vpcName; + String _vpcUuid; + boolean _defaultEgressPolicy; + Collection _ipAddressRange; + + public ImplementNetworkVspCommand(String networkDomainName, String networkDomainPath, String networkDomainUuid, String networkAccountName, String networkAccountUuid, + String networkName, String networkCidr, String networkGateway, String networkUuid, boolean isL3Network, String vpcName, String vpcUuid, boolean defaultEgressPolicy, + Collection ipAddressRange) { + super(); + this._networkDomainName = networkDomainName; + this._networkDomainPath = networkDomainPath; + this._networkDomainUuid = networkDomainUuid; + this._networkAccountName = networkAccountName; + this._networkAccountUuid = networkAccountUuid; + this._networkName = networkName; + this._networkCidr = networkCidr; + this._networkGateway = networkGateway; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcName = vpcName; + this._vpcUuid = vpcUuid; + this._defaultEgressPolicy = defaultEgressPolicy; + this._ipAddressRange = ipAddressRange; + } + + public String getNetworkDomainName() { + return _networkDomainName; + } + + public String getNetworkDomainPath() { + return _networkDomainPath; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getNetworkAccountName() { + return _networkAccountName; + } + + public String getNetworkAccountUuid() { + return _networkAccountUuid; + } + + public String getNetworkName() { + return _networkName; + } + + public String getNetworkCidr() { + return _networkCidr; + } + + public String getNetworkGateway() { + return _networkGateway; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcName() { + return _vpcName; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public boolean isDefaultEgressPolicy() { + return _defaultEgressPolicy; + } + + public Collection getIpAddressRange() { + return _ipAddressRange; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java new file mode 100644 index 00000000000..8bc8e4c4da0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ReleaseVmVspAnswer extends Answer { + + public ReleaseVmVspAnswer(Command command, Exception e) { + super(command, e); + } + + public ReleaseVmVspAnswer(ReleaseVmVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java new file mode 100644 index 00000000000..9a6a4d7cbb9 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReleaseVmVspCommand.java @@ -0,0 +1,54 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class ReleaseVmVspCommand extends Command { + + String _networkUuid; + String _vmUuid; + String _vmInstanceName; + + public ReleaseVmVspCommand(String networkUuid, String vmUuid, String vmInstanceName) { + super(); + this._networkUuid = networkUuid; + this._vmUuid = vmUuid; + this._vmInstanceName = vmInstanceName; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public String getVmUuid() { + return _vmUuid; + } + + public String getVmInstanceName() { + return _vmInstanceName; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java new file mode 100644 index 00000000000..8fabbef0375 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspAnswer.java @@ -0,0 +1,44 @@ +// +// 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.agent.api.guru; + +import java.util.List; +import java.util.Map; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class ReserveVmInterfaceVspAnswer extends Answer { + + public List> _interfaceDetails; + + public ReserveVmInterfaceVspAnswer(Command cmd, List> interfaceDetails, String details) { + super(cmd, true, details); + this._interfaceDetails = interfaceDetails; + } + + public ReserveVmInterfaceVspAnswer(Command cmd, Exception e) { + super(cmd, e); + } + + public List> getInterfaceDetails() { + return this._interfaceDetails; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java new file mode 100644 index 00000000000..6844bf9d1be --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/ReserveVmInterfaceVspCommand.java @@ -0,0 +1,115 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class ReserveVmInterfaceVspCommand extends Command { + + String _nicUuid; + String _nicMacAddress; + String _networkUuid; + boolean _isL3Network; + String _vpcUuid; + String _networkDomainUuid; + String _networksAccountUuid; + boolean _isDomainRouter; + String _domainRouterIp; + String _vmInstanceName; + String _vmUuid; + String _vmUserName; + String _vmUserDomainName; + + public ReserveVmInterfaceVspCommand(String nicUuid, String nicMacAddress, String networkUuid, boolean isL3Network, String vpcUuid, String networkDomainUuid, + String networksAccountUuid, boolean isDomainRouter, String domainRouterIp, String vmInstanceName, String vmUuid, String vmUserName, String vmUserDomainName) { + super(); + this._nicUuid = nicUuid; + this._nicMacAddress = nicMacAddress; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + this._networkDomainUuid = networkDomainUuid; + this._networksAccountUuid = networksAccountUuid; + this._isDomainRouter = isDomainRouter; + this._domainRouterIp = domainRouterIp; + this._vmInstanceName = vmInstanceName; + this._vmUuid = vmUuid; + this._vmUserName = vmUserName; + this._vmUserDomainName = vmUserDomainName; + } + + public String getNicUuid() { + return _nicUuid; + } + + public String getNicMacAddress() { + return _nicMacAddress; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + public String getNetworkDomainUuid() { + return _networkDomainUuid; + } + + public String getNetworksAccountUuid() { + return _networksAccountUuid; + } + + public boolean isDomainRouter() { + return _isDomainRouter; + } + + public String _getDomainRouterIp() { + return _domainRouterIp; + } + + public String _getVmInstanceName() { + return _vmInstanceName; + } + + public String _getVmUuid() { + return _vmUuid; + } + + public String _getVmUserName() { + return _vmUserName; + } + + public String _getVmUserDomainName() { + return _vmUserDomainName; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java new file mode 100644 index 00000000000..0c0c0d2eeee --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; + +public class TrashNetworkVspAnswer extends Answer { + + public TrashNetworkVspAnswer(Command command, Exception e) { + super(command, e); + } + + public TrashNetworkVspAnswer(TrashNetworkVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java new file mode 100644 index 00000000000..e10e9beb001 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/guru/TrashNetworkVspCommand.java @@ -0,0 +1,60 @@ +// +// 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.agent.api.guru; + +import com.cloud.agent.api.Command; + +public class TrashNetworkVspCommand extends Command { + + String _domainUuid; + String _networkUuid; + boolean _isL3Network; + String _vpcUuid; + + public TrashNetworkVspCommand(String domainUuid, String networkUuid, boolean isL3Network, String vpcUuid) { + super(); + this._domainUuid = domainUuid; + this._networkUuid = networkUuid; + this._isL3Network = isL3Network; + this._vpcUuid = vpcUuid; + } + + public String getDomainUuid() { + return _domainUuid; + } + + public String getNetworkUuid() { + return _networkUuid; + } + + public boolean isL3Network() { + return _isL3Network; + } + + public String getVpcUuid() { + return _vpcUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java new file mode 100644 index 00000000000..52848e558a0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspAnswer.java @@ -0,0 +1,34 @@ +// +// 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.agent.api.sync; + +import com.cloud.agent.api.Answer; + +public class SyncVspAnswer extends Answer { + + public SyncVspAnswer(SyncVspCommand cmd, boolean success, String details) { + super(cmd, success, details); + } + + public SyncVspAnswer(SyncVspCommand cmd, Exception e) { + super(cmd, e); + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java new file mode 100644 index 00000000000..8ccd84db55d --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncVspCommand.java @@ -0,0 +1,42 @@ +// +// 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.agent.api.sync; + +import com.cloud.agent.api.Command; + +public class SyncVspCommand extends Command { + + String _nuageVspEntity; + + public SyncVspCommand(String nuageVspEntity) { + super(); + this._nuageVspEntity = nuageVspEntity; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getNuageVspEntity() { + return _nuageVspEntity; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java new file mode 100644 index 00000000000..19f2d09b399 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/AddNuageVspDeviceCmd.java @@ -0,0 +1,179 @@ +// +// 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.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "addNuageVspDevice", responseObject = NuageVspDeviceResponse.class, description = "Adds a Nuage VSP device") +public class AddNuageVspDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "addnuagevspdeviceresponse"; + + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = BaseCmd.CommandType.UUID, entityType = PhysicalNetworkResponse.class, + required = true, description = "the ID of the physical network in to which Nuage VSP is added") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_PORT, type = CommandType.INTEGER, required = true, description = "the port to communicate to Nuage VSD") + private int port; + + @Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "the hostname of the Nuage VSD") + private String hostName; + + @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "the user name of the CMS user in Nuage VSD") + private String userName; + + @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "the password of CMS user in Nuage VSD") + private String password; + + @Parameter(name = VspConstants.NUAGE_VSP_API_VERSION, type = CommandType.STRING, required = true, description = "the version of the API to use to communicate to Nuage VSD") + private String apiVersion; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RETRY_COUNT, type = CommandType.INTEGER, required = true, description = "the number of retries on failure to communicate to Nuage VSD") + private int apiRetryCount; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RETRY_INTERVAL, type = CommandType.LONG, required = true, description = "the time to wait after failure before retrying to communicate to Nuage VSD") + private long apiRetryInterval; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public String getUserName() { + return userName; + } + + public String getPassword() { + return password; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public int getApiRetryCount() { + return apiRetryCount; + } + + public void setApiRetryCount(int apiRetryCount) { + this.apiRetryCount = apiRetryCount; + } + + public long getApiRetryInterval() { + return apiRetryInterval; + } + + public void setApiRetryInterval(long apiRetryInterval) { + this.apiRetryInterval = apiRetryInterval; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + NuageVspDeviceVO nuageVspDeviceVO = _nuageVspManager.addNuageVspDevice(this); + if (nuageVspDeviceVO != null) { + NuageVspDeviceResponse response = _nuageVspManager.createNuageVspDeviceResponse(nuageVspDeviceVO); + response.setObjectName("nuagevspdevice"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Nuage VSP device due to internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_VSP_VSD_ADD; + } + + @Override + public String getEventDescription() { + return "Adding a Nuage VSD"; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java new file mode 100644 index 00000000000..ae81c847bf9 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DeleteNuageVspDeviceCmd.java @@ -0,0 +1,105 @@ +// +// 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.api.commands; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "deleteNuageVspDevice", responseObject = SuccessResponse.class, description = "delete a nuage vsp device") +public class DeleteNuageVspDeviceCmd extends BaseAsyncCmd { + private static final String s_name = "deletenuagevspdeviceresponse"; + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = VspConstants.NUAGE_VSP_DEVICE_ID, type = CommandType.UUID, entityType = NuageVspDeviceResponse.class, required = true, description = "Nuage device ID") + private Long nuageVspDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNuageVspDeviceId() { + return nuageVspDeviceId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result = _nuageVspManager.deleteNuageVspDevice(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Nuage device."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_VSP_VSD_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting Nuage VSD"; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java new file mode 100644 index 00000000000..f0e3ff8fd82 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/IssueNuageVspResourceRequestCmd.java @@ -0,0 +1,215 @@ +// +// 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.api.commands; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.NetworkOfferingResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.VspResourceAnswer; +import com.cloud.agent.api.VspResourceCommand; +import com.cloud.api.response.NuageVspResourceResponse; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +@APICommand(name = "issueNuageVspResourceRequest", responseObject = NuageVspResourceResponse.class, description = "Issues a Nuage VSP REST API resource request") +public class IssueNuageVspResourceRequestCmd extends BaseCmd { + private static final Logger s_logger = Logger.getLogger(IssueNuageVspResourceRequestCmd.class.getName()); + private static final String s_name = "nuagevspresourceresponse"; + + @Inject + protected AccountManager _accountMgr; + @Inject + protected DomainDao _domainDao; + @Inject + protected NuageVspDao _nuageConfigDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, required = true, description = "the network offering id") + private Long networkOfferingId; + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the Zone ID for the network") + private Long zoneId; + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the ID of the physical network in to which Nuage VSP Controller is added") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_METHOD, type = CommandType.STRING, required = true, description = "the Nuage VSP REST API method type") + private String method; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE, type = CommandType.STRING, required = true, description = "the resource in Nuage VSP") + private String resource; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE_ID, type = CommandType.STRING, description = "the ID of the resource in Nuage VSP") + private String resourceId; + + @Parameter(name = VspConstants.NUAGE_VSP_API_CHILD_RESOURCE, type = CommandType.STRING, description = "the child resource in Nuage VSP") + private String childResource; + + @Parameter(name = VspConstants.NUAGE_VSP_API_RESOURCE_FILTER, type = CommandType.STRING, description = "the resource filter in Nuage VSP") + private String resourceFilter; + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + public Long getNetworkOfferingId() { + return networkOfferingId; + } + + public Long getZoneId() { + Long physicalNetworkId = getPhysicalNetworkId(); + + if (physicalNetworkId == null && zoneId == null) { + throw new InvalidParameterValueException("Zone id is required"); + } + + return zoneId; + } + + public Long getPhysicalNetworkId() { + if (physicalNetworkId != null) { + return physicalNetworkId; + } + + NetworkOffering offering = _entityMgr.findById(NetworkOffering.class, networkOfferingId); + if (offering == null) { + throw new InvalidParameterValueException("Unable to find network offering by id " + networkOfferingId); + } + + if (zoneId == null) { + throw new InvalidParameterValueException("ZoneId is required as physicalNetworkId is null"); + } + return _networkService.findPhysicalNetworkId(zoneId, offering.getTags(), offering.getTrafficType()); + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getResource() { + return resource; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getChildResource() { + return childResource; + } + + public void setChildResource(String childResource) { + this.childResource = childResource; + } + + public String getResourceFilter() { + return resourceFilter; + } + + public void setResourceFilter(String resourceFilter) { + this.resourceFilter = resourceFilter; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + long accountId = CallContext.current().getCallingAccount().getAccountId(); + Account account = _accountMgr.getAccount(accountId); + + List nuageVspDevices = _nuageConfigDao.listByPhysicalNetwork(getPhysicalNetworkId()); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + HostVO nuageVspHost = _hostDao.findById(config.getHostId()); + VspResourceCommand cmd = new VspResourceCommand(method, resource, resourceId, childResource, null, resourceFilter, null, null); + VspResourceAnswer answer = (VspResourceAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("VspResourceCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, answer.getDetails()); + } + } else { + NuageVspResourceResponse response = new NuageVspResourceResponse(); + response.setResourceInfo(StringUtils.isBlank(answer.getResourceInfo()) ? "" : answer.getResourceInfo()); + response.setObjectName("nuagevspresource"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + } else { + String errorMessage = "No Nuage VSP Controller configured on physical network " + getPhysicalNetworkId(); + s_logger.error(errorMessage); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMessage); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java new file mode 100644 index 00000000000..46797e0af03 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageVspDevicesCmd.java @@ -0,0 +1,107 @@ +// +// 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.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; + +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "listNuageVspDevices", responseObject = NuageVspDeviceResponse.class, description = "Lists Nuage VSP devices") +public class ListNuageVspDevicesCmd extends BaseListCmd { + private static final String s_name = "listnuagevspdeviceresponse"; + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the Physical Network ID") + private Long physicalNetworkId; + + @Parameter(name = VspConstants.NUAGE_VSP_DEVICE_ID, type = CommandType.UUID, entityType = NuageVspDeviceResponse.class, description = "the Nuage VSP device ID") + private Long nuageVspDeviceId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getNuageVspDeviceId() { + return nuageVspDeviceId; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + List nuageDevices = _nuageVspManager.listNuageVspDevices(this); + ListResponse response = new ListResponse(); + List nuageDevicesResponse = new ArrayList(); + + if (nuageDevices != null && !nuageDevices.isEmpty()) { + for (NuageVspDeviceVO nuageDeviceVO : nuageDevices) { + NuageVspDeviceResponse nuageDeviceResponse = _nuageVspManager.createNuageVspDeviceResponse(nuageDeviceVO); + nuageDevicesResponse.add(nuageDeviceResponse); + } + } + + response.setResponses(nuageDevicesResponse); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java new file mode 100644 index 00000000000..237289064a5 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java @@ -0,0 +1,35 @@ +// +// 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.api.commands; + +public class VspConstants { + public static final String NUAGE_VSP_DEVICE_ID = "vspdeviceid"; + public static final String NUAGE_VSP_DEVICE_NAME = "nuagedevicename"; + public static final String NUAGE_VSP_API_PORT = "port"; + public static final String NUAGE_VSP_API_VERSION = "apiversion"; + public static final String NUAGE_VSP_API_RETRY_COUNT = "retrycount"; + public static final String NUAGE_VSP_API_RETRY_INTERVAL = "retryinterval"; + public static final String NUAGE_VSP_API_METHOD = "method"; + public static final String NUAGE_VSP_API_RESOURCE = "resource"; + public static final String NUAGE_VSP_API_RESOURCE_ID = "resourceid"; + public static final String NUAGE_VSP_API_CHILD_RESOURCE = "childresource"; + public static final String NUAGE_VSP_API_RESOURCE_FILTER = "resourcefilter"; + public static final String NUAGE_VSP_API_RESOURCE_INFO = "resourceinfo"; +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java new file mode 100644 index 00000000000..b0bbcc8ebc7 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspDeviceResponse.java @@ -0,0 +1,105 @@ +// +// 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.api.response; + +import com.cloud.api.commands.VspConstants; +import com.cloud.network.NuageVspDeviceVO; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@EntityReference(value = NuageVspDeviceVO.class) +public class NuageVspDeviceResponse extends BaseResponse { + @SerializedName(VspConstants.NUAGE_VSP_DEVICE_ID) + @Param(description = "the device id of the Nuage VSD") + private String id; + + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) + @Param(description = "the ID of the physical network to which this Nuage VSP belongs to") + private String physicalNetworkId; + + @SerializedName(ApiConstants.PROVIDER) + @Param(description = "the service provider name corresponding to this Nuage VSP device") + private String providerName; + + @SerializedName(VspConstants.NUAGE_VSP_DEVICE_NAME) + @Param(description = "the name of the Nuage VSP device") + private String deviceName; + + @SerializedName(VspConstants.NUAGE_VSP_API_PORT) + @Param(description = "the port to communicate to Nuage VSD") + private int port; + + @SerializedName(ApiConstants.HOST_NAME) + @Param(description = "the hostname of the Nuage VSD") + private String hostName; + + @SerializedName(VspConstants.NUAGE_VSP_API_VERSION) + @Param(description = "the version of the API to use to communicate to Nuage VSD") + private String apiVersion; + + @SerializedName(VspConstants.NUAGE_VSP_API_RETRY_COUNT) + @Param(description = "the number of retries on failure to communicate to Nuage VSD") + private int apiRetryCount; + + @SerializedName(VspConstants.NUAGE_VSP_API_RETRY_INTERVAL) + @Param(description = "the time to wait after failure before retrying to communicate to Nuage VSD") + private long apiRetryInterval; + + public void setId(String vspDetailsId) { + this.id = vspDetailsId; + } + + public void setPhysicalNetworkId(String physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public void setPort(int port) { + this.port = port; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public void setApiRetryCount(int apiRetryCount) { + this.apiRetryCount = apiRetryCount; + } + + public void setApiRetryInterval(long apiRetryInterval) { + this.apiRetryInterval = apiRetryInterval; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java new file mode 100644 index 00000000000..8e620ed4c3d --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVspResourceResponse.java @@ -0,0 +1,41 @@ +// +// 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.api.response; + +import com.cloud.api.commands.VspConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class NuageVspResourceResponse extends BaseResponse { + @SerializedName(VspConstants.NUAGE_VSP_API_RESOURCE_INFO) + @Param(description = "the details of the Nuage VSP resource") + private String resourceInfo; + + public String getResourceInfo() { + return resourceInfo; + } + + public void setResourceInfo(String resourceInfo) { + this.resourceInfo = resourceInfo; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java new file mode 100644 index 00000000000..00cb1e4dc7e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/NuageVspDeviceVO.java @@ -0,0 +1,98 @@ +// +// 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; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "external_nuage_vsp_devices") +public class NuageVspDeviceVO implements InternalIdentity { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "host_id") + private long hostId; + + @Column(name = "physical_network_id") + private long physicalNetworkId; + + @Column(name = "provider_name") + private String providerName; + + @Column(name = "device_name") + private String deviceName; + + public NuageVspDeviceVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public NuageVspDeviceVO(long hostId, long physicalNetworkId, + String providerName, String deviceName){ + super(); + this.hostId = hostId; + this.physicalNetworkId = physicalNetworkId; + this.providerName = providerName; + this.deviceName = deviceName; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + public long getHostId() { + return hostId; + } + + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getProviderName() { + return providerName; + } + + public String getDeviceName() { + return deviceName; + } + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java new file mode 100644 index 00000000000..6cf7e1a5f62 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDao.java @@ -0,0 +1,36 @@ +// +// 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.dao; + +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.db.GenericDao; + +import java.util.List; + +public interface NuageVspDao extends GenericDao { + /** + * List all the Nuage Vsp devices added in to this physical network + * + * @param physicalNetworkId physical Network Id + * @return list of NuageVspDeviceVO for this physical network. + */ + List listByPhysicalNetwork(long physicalNetworkId); + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java new file mode 100644 index 00000000000..bc55f434c0f --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/dao/NuageVspDaoImpl.java @@ -0,0 +1,52 @@ +// +// 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.dao; + +import javax.ejb.Local; + +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; + +import java.util.List; + +@Component +@Local(value = NuageVspDao.class) +public class NuageVspDaoImpl extends GenericDaoBase + implements NuageVspDao { + + protected final SearchBuilder physicalNetworkIdSearch; + + public NuageVspDaoImpl() { + physicalNetworkIdSearch = createSearchBuilder(); + physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ); + physicalNetworkIdSearch.done(); + } + + @Override + public List listByPhysicalNetwork(long physicalNetworkId) { + SearchCriteria sc = physicalNetworkIdSearch.create(); + sc.setParameters("physicalNetworkId", physicalNetworkId); + return search(sc, null); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java new file mode 100644 index 00000000000..06f9733fc0e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java @@ -0,0 +1,534 @@ +// +// 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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupVspCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.Domain; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.CloudException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.FirewallRuleType; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceStateAdapter; +import com.cloud.resource.ServerResource; +import com.cloud.resource.UnableDeleteHostException; +import com.cloud.utils.component.AdapterBase; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicDao; + +@Local(value = {NetworkElement.class, ConnectivityProvider.class, IpDeployer.class, SourceNatServiceProvider.class, StaticNatServiceProvider.class, FirewallServiceProvider.class, + DhcpServiceProvider.class, NetworkACLServiceProvider.class}) +public class NuageVspElement extends AdapterBase implements ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, + DhcpServiceProvider, NetworkACLServiceProvider, ResourceStateAdapter { + + private static final Logger s_logger = Logger.getLogger(NuageVspElement.class); + + private static final Map> capabilities = setCapabilities(); + + public static final ExternalNetworkDeviceManager.NetworkDevice NuageVspDevice = new ExternalNetworkDeviceManager.NetworkDevice("NuageVsp", Provider.NuageVsp.getName()); + + @Inject + ResourceManager _resourceMgr; + @Inject + HostDao _hostDao; + @Inject + NetworkModel _networkModel; + @Inject + NetworkServiceMapDao _ntwkSrvcDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + NetworkDao _networkDao; + @Inject + protected DomainDao _domainDao; + @Inject + protected DataCenterDao _dcDao; + @Inject + IPAddressDao _ipAddressDao; + @Inject + VlanDao _vlanDao; + @Inject + NicDao _nicDao; + @Inject + VpcDao _vpcDao; + @Inject + NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; + @Inject + AgentManager _agentMgr; + @Inject + NetworkOfferingDao _ntwkOfferingDao; + + @Override + public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { + return false; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + // L2 Support : SDN provisioning + capabilities.put(Service.Connectivity, null); + + // L3 Support : Generic + capabilities.put(Service.Gateway, null); + + // L3 Support : SourceNat + Map sourceNatCapabilities = new HashMap(); + sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount"); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + // L3 support : StaticNat + capabilities.put(Service.StaticNat, null); + + // Set capabilities for Firewall service + Map firewallCapabilities = new HashMap(); + firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); + firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); + firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all"); + firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress"); + firewallCapabilities.put(Capability.MultipleIps, "true"); + capabilities.put(Service.Firewall, firewallCapabilities); + + // L3 Support : DHCP + Map dhcpCapabilities = new HashMap(); + capabilities.put(Service.Dhcp, dhcpCapabilities); + + //add network ACL capability + Map networkACLCapabilities = new HashMap(); + networkACLCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp"); + capabilities.put(Network.Service.NetworkACL, networkACLCapabilities); + + return capabilities; + } + + @Override + public Provider getProvider() { + return Provider.NuageVsp; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _resourceMgr.registerResourceStateAdapter(name, this); + return true; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + s_logger.debug("Entering NuageElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")"); + + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + if (network.getBroadcastUri() == null) { + s_logger.error("Nic has no broadcast Uri with the virtual router IP"); + return false; + } + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean isReady(PhysicalNetworkServiceProvider provider) { + return true; + } + + @Override + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + return true; + } + + @Override + public boolean canEnableIndividualServices() { + return false; + } + + @Override + public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { + if (!canHandle(network, Service.Connectivity)) { + return false; + } + + return true; + } + + @Override + public boolean verifyServicesCombination(Set services) { + // This element can only function in a NuageVsp based + // SDN network, so Connectivity needs to be present here + if (!services.contains(Service.Connectivity)) { + s_logger.warn("Unable to support services combination without Connectivity service provided by Nuage VSP."); + return false; + } + + if ((services.contains(Service.StaticNat)) && (!services.contains(Service.SourceNat))) { + s_logger.warn("Unable to provide StaticNat without the SourceNat service."); + return false; + } + + if (services.contains(Service.Vpn) || services.contains(Service.Dns) || services.contains(Service.Lb) || services.contains(Service.PortForwarding) + || services.contains(Service.SecurityGroup)) { + // NuageVsp doesn't implement any of these services, and we don't + // want anyone else to do it for us. So if these services + // exist, we can't handle it. + s_logger.warn("Unable to support services combination. The services list contains service(s) not supported by Nuage VSP."); + return false; + } + + return true; + } + + protected boolean canHandle(Network network, Service service) { + + if (network.getBroadcastDomainType() != Networks.BroadcastDomainType.Vsp) { + return false; + } + + if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) { + s_logger.debug("NuageElement is not a provider for network " + network.getDisplayText()); + return false; + } + + if (service != null) { + if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { + s_logger.debug("NuageElement can't provide the " + service.getName() + " service on network " + network.getDisplayText()); + return false; + } + } + + return true; + } + + @Override + public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + return true; + } + + @Override + public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + return true; + } + + @Override + public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException { + return true; + } + + @Override + public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { + //Check if the network is associated to a VPC + Long vpcId = config.getVpcId(); + String vpcOrSubnetUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcOrSubnetUuid = vpcObj.getUuid(); + } else { + vpcOrSubnetUuid = config.getUuid(); + } + Domain networkDomain = _domainDao.findById(config.getDomainId()); + + long networkOfferingId = _ntwkOfferingDao.findById(config.getNetworkOfferingId()).getId(); + boolean isL3Network = isL3Network(networkOfferingId); + + List> sourceNatDetails = new ArrayList>(); + for (StaticNat staticNat : rules) { + Map sourceNatDetail = new HashMap(); + IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId()); + VlanVO sourceNatVan = _vlanDao.findById(sourceNatIp.getVlanId()); + NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId()); + //Just get all the information about the sourceNat which will be used by NuageVsp + //client to process the request + sourceNatDetail.put("sourceNatIpUuid", sourceNatIp.getUuid()); + sourceNatDetail.put("sourceNatIpAddress", sourceNatIp.getAddress().addr()); + sourceNatDetail.put("nicMacAddress", nicVO == null ? null : nicVO.getMacAddress()); + sourceNatDetail.put("isRevoke", staticNat.isForRevoke()); + sourceNatDetail.put("sourceNatVlanUuid", sourceNatVan.getUuid()); + sourceNatDetail.put("sourceNatVlanGateway", sourceNatVan.getVlanGateway()); + sourceNatDetail.put("sourceNatVlanNetmask", sourceNatVan.getVlanNetmask()); + sourceNatDetails.add(sourceNatDetail); + } + try { + try { + HostVO nuageVspHost = getNuageVspHost(config.getPhysicalNetworkId()); + ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(networkDomain.getUuid(), vpcOrSubnetUuid, isL3Network, sourceNatDetails); + ApplyStaticNatVspAnswer answer = (ApplyStaticNatVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ApplyStaticNatNuageVspCommand for network " + config.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ResourceUnavailableException(answer.getDetails(), Network.class, config.getId()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to apply static Nat in Vsp " + e.getMessage()); + } + } catch (Exception e) { + throw new ResourceUnavailableException("Failed to apply Static NAT in VSP", Network.class, config.getId(), e); + } + + return true; + } + + @Override + public IpDeployer getIpDeployer(Network network) { + return this; + } + + @Override + public boolean applyFWRules(Network network, List rules) throws ResourceUnavailableException { + s_logger.debug("Handling applyFWRules for network " + network.getName() + " with " + rules.size() + " FWRules"); + if (rules != null && rules.size() == 1 && rules.iterator().next().getType().equals(FirewallRuleType.System)) { + s_logger.debug("Default ACL added by CS as system is ignored for network " + network.getName() + " with rule " + rules); + return true; + } + return applyACLRules(network, rules, false); + } + + @Override + public boolean applyNetworkACLs(Network network, List rules) throws ResourceUnavailableException { + s_logger.debug("Handling applyNetworkACLs for network " + network.getName() + " with " + rules.size() + " Network ACLs"); + if (rules == null || rules.isEmpty()) { + s_logger.debug("No rules to apply. So, delete all the existing ACL in VSP from Subnet with uuid " + network.getUuid()); + } else { + s_logger.debug("New rules has to applied. So, delete all the existing ACL in VSP from Subnet with uuid " + network.getUuid()); + } + applyACLRules(network, rules, true); + return true; + } + + protected boolean applyACLRules(Network network, List rules, boolean isVpc) throws ResourceUnavailableException { + Domain networksDomain = _domainDao.findById(network.getDomainId()); + NetworkOfferingVO networkOferringVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); + try { + Long vpcId = network.getVpcId(); + String vpcOrSubnetUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcOrSubnetUuid = vpcObj.getUuid(); + } else { + vpcOrSubnetUuid = network.getUuid(); + } + boolean egressDefaultPolicy = networkOferringVO.getEgressDefaultPolicy(); + List> aclRules = new ArrayList>(); + for (InternalIdentity acl : rules) { + aclRules.add(getACLRuleDetails(acl, egressDefaultPolicy)); + } + + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(network.getUuid(), networksDomain.getUuid(), vpcOrSubnetUuid, isL3Network(networkOferringVO.getId()), aclRules, + isVpc, network.getId()); + ApplyAclRuleVspAnswer answer = (ApplyAclRuleVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ApplyAclRuleNuageVspCommand for network " + network.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new ResourceUnavailableException(answer.getDetails(), Network.class, network.getId()); + } + } + + } catch (Exception e1) { + throw new ResourceUnavailableException(e1.getMessage(), Network.class, network.getId()); + } + + return true; + } + + @Override + public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { + return null; + } + + @Override + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { + if (!(startup[0] instanceof StartupVspCommand)) { + 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); + } + + protected HostVO getNuageVspHost(Long physicalNetworkId) throws CloudException { + HostVO nuageVspHost; + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + nuageVspHost = _hostDao.findById(config.getHostId()); + _hostDao.loadDetails(nuageVspHost); + } else { + throw new CloudException("Nuage VSD is not configured on physical network " + physicalNetworkId); + } + return nuageVspHost; + } + + protected boolean isL3Network(Long offeringId) { + return _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.SourceNat) + || _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.StaticNat); + } + + private Map getACLRuleDetails(Object aclRule, boolean egressDefaultPolicy) { + Map aclDetails = new HashMap(); + if (aclRule instanceof FirewallRule) { + FirewallRule firewallRule = (FirewallRule)aclRule; + aclDetails.put("sourceCidrList", firewallRule.getSourceCidrList()); + aclDetails.put("uuid", firewallRule.getUuid()); + aclDetails.put("protocol", firewallRule.getProtocol()); + aclDetails.put("startPort", firewallRule.getSourcePortStart()); + aclDetails.put("endPort", firewallRule.getSourcePortEnd()); + aclDetails.put("state", firewallRule.getState().name()); + aclDetails.put("trafficType", firewallRule.getTrafficType().name()); + if (firewallRule.getSourceIpAddressId() != null) { + //add the source IP + IPAddressVO ipaddress = _ipAddressDao.findById(((FirewallRule)aclRule).getSourceIpAddressId()); + aclDetails.put("sourceIpAddress", ipaddress != null ? ipaddress.getVmIp() + "/32" : null); + } + if (firewallRule.getTrafficType().equals(FirewallRule.TrafficType.Egress) && egressDefaultPolicy) { + aclDetails.put("action", "Deny"); + } else { + aclDetails.put("action", "Allow"); + } + aclDetails.put("priority", -1); + aclDetails.put("type", "Firewall"); + } else { + NetworkACLItem networkAcl = (NetworkACLItem)aclRule; + aclDetails.put("sourceCidrList", networkAcl.getSourceCidrList()); + aclDetails.put("uuid", networkAcl.getUuid()); + aclDetails.put("protocol", networkAcl.getProtocol()); + aclDetails.put("startPort", networkAcl.getSourcePortStart()); + aclDetails.put("endPort", networkAcl.getSourcePortEnd()); + aclDetails.put("state", networkAcl.getState().name()); + aclDetails.put("trafficType", networkAcl.getTrafficType().name()); + //Set sourceIP to null as it is not applicable + aclDetails.put("sourceIpAddress", null); + aclDetails.put("action", networkAcl.getAction().name()); + aclDetails.put("priority", networkAcl.getNumber()); + aclDetails.put("type", "NetworkACL"); + } + return aclDetails; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java new file mode 100644 index 00000000000..d9882eaa7b3 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java @@ -0,0 +1,416 @@ +// +// 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.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkProfile; +import com.cloud.network.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetwork.IsolationMethod; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.db.DB; +import com.cloud.utils.net.NetUtils; +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; + +@Local(value = NetworkGuru.class) +public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { + public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class); + + @Inject + NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao; + @Inject + NetworkOfferingDao _ntwkOfferingDao; + @Inject + DomainDao _domainDao; + @Inject + AccountDao _accountDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + HostDao _hostDao; + @Inject + VpcDao _vpcDao; + @Inject + AgentManager _agentMgr; + + public NuageVspGuestNetworkGuru() { + super(); + _isolationMethods = new IsolationMethod[] {IsolationMethod.VSP}; + } + + @Override + public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { + PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId()); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + if (!canHandle(offering, dc.getNetworkType(), physnet)) { + s_logger.debug("Refusing to design this network"); + return null; + } + + NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner); + if (networkObject == null) { + return null; + } + + networkObject.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); + return networkObject; + } + + @Override + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException { + + assert (network.getState() == State.Implementing) : "Why are we implementing " + network; + + long dcId = dest.getDataCenter().getId(); + //Get physical network id + Long physicalNetworkId = network.getPhysicalNetworkId(); + //Physical network id can be null in Guest Network in Basic zone, so locate the physical network + if (physicalNetworkId == null) { + physicalNetworkId = _networkModel.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()); + } + Collection ipAddressRange = new ArrayList(); + String virtualRouterIp = getVirtualRouterIP(network, ipAddressRange); + String networkUuid = implemented.getUuid(); + String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId(); + String broadcastUriStr = networkUuid + "/" + virtualRouterIp; + implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr)); + implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); + //Check if the network is associated to a VPC + Long vpcId = network.getVpcId(); + boolean isVpc = (vpcId != null); + //Check owner of the Network + Domain networksDomain = _domainDao.findById(network.getDomainId()); + //Get the Account details and find the type + AccountVO networksAccount = _accountDao.findById(network.getAccountId()); + if (networksAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { + String errorMessage = "CS project support is not yet implemented in NuageVsp"; + s_logger.debug(errorMessage); + throw new InsufficientVirtualNetworkCapacityException(errorMessage, Account.class, network.getAccountId()); + } + boolean isL3Network = isL3Network(offering.getId()); + String vpcName = null; + String vpcUuid = null; + if (isVpc) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcName = vpcObj.getName(); + vpcUuid = vpcObj.getUuid(); + } + + HostVO nuageVspHost = getNuageVspHost(physicalNetworkId); + ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(networksDomain.getName(), networksDomain.getPath(), networksDomain.getUuid(), + networksAccount.getAccountName(), networksAccount.getUuid(), network.getName(), network.getCidr(), network.getGateway(), network.getUuid(), isL3Network, vpcName, + vpcUuid, offering.getEgressDefaultPolicy(), ipAddressRange); + ImplementNetworkVspAnswer answer = (ImplementNetworkVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("ImplementNetworkNuageVspCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + return null; + } + s_logger.info("Implemented OK, network " + networkUuid + " in tenant " + tenantId + " linked to " + implemented.getBroadcastUri().toString()); + return implemented; + } + + @Override + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + + return super.allocate(network, nic, vm); + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + nic.setBroadcastUri(network.getBroadcastUri()); + nic.setIsolationUri(network.getBroadcastUri()); + + s_logger.debug("Handling reserve() call back to with Create a new VM or add an interface to existing VM in network " + network.getName()); + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + Account networksAccount = _accountDao.findById(network.getAccountId()); + DomainVO networksDomain = _domainDao.findById(network.getDomainId()); + //Get the Account details and find the type + long networkOwnedBy = network.getAccountId(); + AccountVO neworkAccountDetails = _accountDao.findById(networkOwnedBy); + if (neworkAccountDetails.getType() == Account.ACCOUNT_TYPE_PROJECT) { + throw new InsufficientVirtualNetworkCapacityException("CS project support is " + "not yet implemented in NuageVsp", DataCenter.class, dc.getId()); + } + + //NicProfile does not contain the NIC UUID. We need this information to set it in the VMInterface and VPort + //that we create in VSP + NicVO nicFrmDB = _nicDao.findById(nic.getId()); + long networkOfferingId = _ntwkOfferingDao.findById(network.getNetworkOfferingId()).getId(); + boolean isL3Network = isL3Network(networkOfferingId); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(nicFrmDB.getUuid(), nic.getMacAddress(), network.getUuid(), isL3Network, vpcUuid, + networksDomain.getUuid(), networksAccount.getUuid(), vm.getType().equals(VirtualMachine.Type.DomainRouter), network.getBroadcastUri().getPath().substring(1), + vm.getInstanceName(), vm.getUuid(), networksDomain.getUuid(), networksAccount.getUuid()); + ReserveVmInterfaceVspAnswer answer = (ReserveVmInterfaceVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + + if (answer == null || !answer.getResult()) { + s_logger.error("ReserveVmInterfaceNuageVspCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + throw new InsufficientVirtualNetworkCapacityException("Failed to reserve VM in Nuage VSP.", Network.class, network.getId()); + } + List> vmInterfacesDetails = answer.getInterfaceDetails(); + setIPGatewayMaskInfo(network, nic, vmInterfacesDetails); + } + + @Override + protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { + 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 boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { + long networkId = nic.getNetworkId(); + Network network = _networkDao.findById(networkId); + s_logger.debug("Handling release() call back, which is called when a VM is stopped or destroyed, to delete the VM with state " + vm.getVirtualMachine().getState() + + " from netork " + network.getName()); + if (vm.getVirtualMachine().getState().equals(VirtualMachine.State.Stopping)) { + try { + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + ReleaseVmVspCommand cmd = new ReleaseVmVspCommand(network.getUuid(), vm.getUuid(), vm.getInstanceName()); + ReleaseVmVspAnswer answer = (ReleaseVmVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("ReleaseVmNuageVspCommand for VM " + vm.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (InsufficientVirtualNetworkCapacityException e) { + s_logger.debug("Handling release() call back. Failed to delete CS VM " + vm.getInstanceName() + " in VSP. " + e.getMessage()); + } + } else { + s_logger.debug("Handling release() call back. VM " + vm.getInstanceName() + " is in " + vm.getVirtualMachine().getState() + " state. So, the CS VM is not deleted." + + " This could be a case where VM interface is deleted. deallocate() call back should be called later"); + } + + return super.release(nic, vm, reservationId); + } + + @Override + @DB + public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + + try { + s_logger.debug("Handling deallocate() call back, which is called when a VM is destroyed or interface is removed, " + "to delete VM Interface with IP " + + nic.getIp4Address() + " from a VM " + vm.getInstanceName() + " with state " + vm.getVirtualMachine().getState()); + DomainVO networksDomain = _domainDao.findById(network.getDomainId()); + NicVO nicFrmDd = _nicDao.findById(nic.getId()); + long networkOfferingId = _ntwkOfferingDao.findById(network.getNetworkOfferingId()).getId(); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(network.getUuid(), nicFrmDd.getUuid(), nic.getMacAddress(), nic.getIp4Address(), + isL3Network(networkOfferingId), vpcUuid, networksDomain.getUuid(), vm.getInstanceName(), vm.getUuid()); + DeallocateVmVspAnswer answer = (DeallocateVmVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("DeallocateVmNuageVspCommand for VM " + vm.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (InsufficientVirtualNetworkCapacityException e) { + s_logger.error("Handling deallocate(). VM " + vm.getInstanceName() + " with NIC IP " + nic.getIp4Address() + + " is getting destroyed. REST API failed to update the VM state in NuageVsp", e); + } + super.deallocate(network, nic, vm); + } + + @Override + public void shutdown(NetworkProfile profile, NetworkOffering offering) { + super.shutdown(profile, offering); + } + + @Override + public boolean trash(Network network, NetworkOffering offering) { + + s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP"); + long domainId = network.getDomainId(); + Domain domain = _domainDao.findById(domainId); + Long vpcId = network.getVpcId(); + String vpcUuid = null; + if (vpcId != null) { + Vpc vpcObj = _vpcDao.findById(vpcId); + vpcUuid = vpcObj.getUuid(); + } + try { + HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(domain.getUuid(), network.getUuid(), isL3Network(offering.getId()), vpcUuid); + TrashNetworkVspAnswer answer = (TrashNetworkVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("TrashNetworkNuageVspCommand for network " + network.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to clean up network information in Vsp " + e.getMessage()); + } + + return super.trash(network, offering); + } + + private String getVirtualRouterIP(Network network, Collection addressRange) throws InsufficientVirtualNetworkCapacityException { + String virtualRouterIp; + String subnet = NetUtils.getCidrSubNet(network.getCidr()); + String netmask = NetUtils.getCidrNetmask(network.getCidr()); + long cidrSize = NetUtils.getCidrSize(netmask); + + Set allIPsInCidr = NetUtils.getAllIpsFromCidr(subnet, cidrSize, new HashSet()); + + if (allIPsInCidr.size() > 3) { + Iterator ipIterator = allIPsInCidr.iterator(); + long vip = ipIterator.next(); + if (NetUtils.ip2Long(network.getGateway()) == vip) { + s_logger.debug("Gateway of the Network(" + network.getUuid() + ") has the first IP " + NetUtils.long2Ip(vip)); + vip = ipIterator.next(); + virtualRouterIp = NetUtils.long2Ip(vip); + s_logger.debug("So, reserving the 2nd IP " + virtualRouterIp + " for the Virtual Router IP in Network(" + network.getUuid() + ")"); + } else { + virtualRouterIp = NetUtils.long2Ip(vip); + s_logger.debug("1nd IP is not used as the gateway IP. So, reserving" + virtualRouterIp + " for the Virtual Router IP for " + "Network(" + network.getUuid() + ")"); + } + addressRange.add(NetUtils.long2Ip(ipIterator.next())); + addressRange.add(NetUtils.long2Ip((Long)allIPsInCidr.toArray()[allIPsInCidr.size() - 1])); + return virtualRouterIp; + } + + throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " So, subnet should have atleast minimum 4 hosts ", Network.class, + network.getId()); + } + + private void setIPGatewayMaskInfo(Network network, NicProfile nic, List> vmInterfacesDetails) throws InsufficientVirtualNetworkCapacityException { + try { + for (Map interfaces : vmInterfacesDetails) { + String macFromNuage = interfaces.get("mac"); + if (StringUtils.equals(macFromNuage, nic.getMacAddress())) { + nic.setIp4Address(interfaces.get("ip4Address")); + nic.setGateway(interfaces.get("gateway")); + nic.setNetmask(interfaces.get("netmask")); + break; + } + } + } catch (Exception e) { + s_logger.error("Failed to parse the VM interface Json response from VSP REST API. VM interface json string is " + vmInterfacesDetails, e); + throw new InsufficientVirtualNetworkCapacityException("Failed to parse the VM interface Json response from VSP REST API. VM interface Json " + "string is " + + vmInterfacesDetails + ". So. failed to get IP for the VM from VSP address for network " + network, Network.class, network.getId()); + } + } + + private boolean isL3Network(Long offeringId) { + return _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.SourceNat) + || _ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offeringId, Service.StaticNat); + } + + private HostVO getNuageVspHost(long physicalNetworkId) throws InsufficientVirtualNetworkCapacityException { + HostVO nuageVspHost; + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + nuageVspHost = _hostDao.findById(config.getHostId()); + _hostDao.loadDetails(nuageVspHost); + } else { + throw new InsufficientVirtualNetworkCapacityException("Nuage VSD is not configured on physical network ", PhysicalNetwork.class, physicalNetworkId); + } + return nuageVspHost; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java new file mode 100644 index 00000000000..2b4d2b558a2 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java @@ -0,0 +1,55 @@ +// +// 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.manager; + +import java.util.List; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.ConfigKey.Scope; + +import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.utils.component.PluggableService; + +public interface NuageVspManager extends PluggableService { + + static final String NUAGE_VPC_OFFERING_NAME = "Default VPC offering with NuageVsp"; + + static final String NUAGE_VPC_OFFERING_DISPLAY_TEXT = "Default VPC offering with NuageVsp"; + + static final ConfigKey NuageVspSyncInterval = new ConfigKey(Integer.class, "nuagevsp.sync.interval", "Advanced", "480", + "The interval (in minutes) to wait before running the next synchronization worker to synchronize the information between CloudStack and NuageVsp", false, Scope.Global, + 1); + + static final ConfigKey NuageVspSyncWorkers = new ConfigKey(Integer.class, "nuagevsp.sync.workers", "Advanced", "1", + "Number of workers to synchronize the information between CloudStack and NuageVsp", false, Scope.Global, 1); + + NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd); + + NuageVspDeviceResponse createNuageVspDeviceResponse(NuageVspDeviceVO nuageVspDeviceVO); + + boolean deleteNuageVspDevice(DeleteNuageVspDeviceCmd cmd); + + List listNuageVspDevices(ListNuageVspDevicesCmd cmd); + +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java new file mode 100644 index 00000000000..fed970ede5a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java @@ -0,0 +1,353 @@ +// +// 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.manager; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.commands.AddNuageVspDeviceCmd; +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.IssueNuageVspResourceRequestCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.api.response.NuageVspDeviceResponse; +import com.cloud.exception.InvalidParameterValueException; +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.Networks; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.network.sync.NuageVspSync; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.resource.ServerResource; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.exception.CloudRuntimeException; + +@Local(value = {NuageVspManager.class}) +public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, Configurable { + + private static final Logger s_logger = Logger.getLogger(NuageVspManagerImpl.class); + + private static final int ONE_MINUTE_MULTIPLIER = 60 * 1000; + + @Inject + ResourceManager _resourceMgr; + @Inject + HostDetailsDao _hostDetailsDao; + @Inject + HostDao _hostDao; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; + @Inject + ConfigurationDao _configDao; + @Inject + NuageVspDao _nuageVspDao; + @Inject + NetworkDao _networkDao; + @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcOfferingServiceMapDao _vpcOffSvcMapDao; + @Inject + VpcDao _vpcDao; + @Inject + NuageVspDao nuageVspDao; + @Inject + NuageVspSync nuageVspSync; + + private ScheduledExecutorService scheduler; + + @Override + public List> getCommands() { + List> cmdList = new ArrayList>(); + cmdList.add(AddNuageVspDeviceCmd.class); + cmdList.add(DeleteNuageVspDeviceCmd.class); + cmdList.add(ListNuageVspDevicesCmd.class); + cmdList.add(IssueNuageVspResourceRequestCmd.class); + + return cmdList; + } + + @Override + public NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd) { + ServerResource resource = new NuageVspResource(); + final String deviceName = Network.Provider.NuageVsp.getName(); + ExternalNetworkDeviceManager.NetworkDevice networkDevice = ExternalNetworkDeviceManager.NetworkDevice.getNetworkDevice(deviceName); + final Long physicalNetworkId = cmd.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId); + } + long zoneId = physicalNetwork.getDataCenterId(); + + final PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), + networkDevice.getNetworkServiceProvder()); + if (ntwkSvcProvider == null) { + throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() + " is not added 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 (_nuageVspDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) { + throw new CloudRuntimeException("A NuageVsp device is already configured on this physical network"); + } + + Map params = new HashMap(); + params.put("guid", UUID.randomUUID().toString()); + params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId())); + params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId())); + params.put("name", "Nuage VSD - " + cmd.getHostName()); + params.put("hostname", cmd.getHostName()); + params.put("cmsuser", cmd.getUserName()); + String cmsUserPasswordBase64 = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.encodeBase64(cmd.getPassword().getBytes(Charset.forName("UTF-8")))); + params.put("cmsuserpass", cmsUserPasswordBase64); + int port = cmd.getPort(); + if (0 == port) { + port = 443; + } + params.put("port", String.valueOf(port)); + params.put("apirelativepath", "/nuage/api/" + cmd.getApiVersion()); + params.put("retrycount", String.valueOf(cmd.getApiRetryCount())); + params.put("retryinterval", String.valueOf(cmd.getApiRetryInterval())); + + Map hostdetails = new HashMap(); + hostdetails.putAll(params); + + try { + resource.configure(cmd.getHostName(), hostdetails); + + final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params); + if (host != null) { + return Transaction.execute(new TransactionCallback() { + @Override + public NuageVspDeviceVO doInTransaction(TransactionStatus status) { + NuageVspDeviceVO nuageVspDevice = new NuageVspDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName); + _nuageVspDao.persist(nuageVspDevice); + + DetailVO detail = new DetailVO(host.getId(), "nuagevspdeviceid", String.valueOf(nuageVspDevice.getId())); + _hostDetailsDao.persist(detail); + + return nuageVspDevice; + } + }); + } else { + throw new CloudRuntimeException("Failed to add Nuage Vsp Device due to internal error."); + } + } catch (ConfigurationException e) { + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public NuageVspDeviceResponse createNuageVspDeviceResponse(NuageVspDeviceVO nuageVspDeviceVO) { + HostVO nuageVspHost = _hostDao.findById(nuageVspDeviceVO.getHostId()); + _hostDao.loadDetails(nuageVspHost); + + NuageVspDeviceResponse response = new NuageVspDeviceResponse(); + response.setDeviceName(nuageVspDeviceVO.getDeviceName()); + PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(nuageVspDeviceVO.getPhysicalNetworkId()); + if (pnw != null) { + response.setPhysicalNetworkId(pnw.getUuid()); + } + response.setId(nuageVspDeviceVO.getUuid()); + response.setProviderName(nuageVspDeviceVO.getProviderName()); + response.setHostName(nuageVspHost.getDetail("hostname")); + response.setPort(Integer.parseInt(nuageVspHost.getDetail("port"))); + String apiRelativePath = nuageVspHost.getDetail("apirelativepath"); + response.setApiVersion(apiRelativePath.substring(apiRelativePath.lastIndexOf('/') + 1)); + response.setApiRetryCount(Integer.parseInt(nuageVspHost.getDetail("retrycount"))); + response.setApiRetryInterval(Long.parseLong(nuageVspHost.getDetail("retryinterval"))); + response.setObjectName("nuagevspdevice"); + return response; + } + + @Override + public boolean deleteNuageVspDevice(DeleteNuageVspDeviceCmd cmd) { + Long nuageDeviceId = cmd.getNuageVspDeviceId(); + NuageVspDeviceVO nuageVspDevice = _nuageVspDao.findById(nuageDeviceId); + if (nuageVspDevice == null) { + throw new InvalidParameterValueException("Could not find a Nuage Vsp device with id " + nuageDeviceId); + } + + // Find the physical network we work for + Long physicalNetworkId = nuageVspDevice.getPhysicalNetworkId(); + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork != null) { + // Lets see if there are networks that use us + // Find the NuageVsp on this physical network + List networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId); + + // Networks with broadcast type lswitch are ours + for (NetworkVO network : networkList) { + if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Vsp) { + if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) { + throw new CloudRuntimeException("This Nuage Vsp device can not be deleted as there are one or more logical networks provisioned by Cloudstack."); + } + } + } + } + + HostVO nuageHost = _hostDao.findById(nuageVspDevice.getHostId()); + Long hostId = nuageHost.getId(); + + nuageHost.setResourceState(ResourceState.Maintenance); + _hostDao.update(hostId, nuageHost); + _resourceMgr.deleteHost(hostId, false, false); + + _nuageVspDao.remove(nuageDeviceId); + return true; + } + + @Override + public List listNuageVspDevices(ListNuageVspDevicesCmd cmd) { + Long physicalNetworkId = cmd.getPhysicalNetworkId(); + Long nuageVspDeviceId = cmd.getNuageVspDeviceId(); + List responseList = new ArrayList(); + + if (physicalNetworkId == null && nuageVspDeviceId == null) { + throw new InvalidParameterValueException("Either physical network Id or Nuage device Id must be specified"); + } + + if (nuageVspDeviceId != null) { + NuageVspDeviceVO nuageVspDevice = _nuageVspDao.findById(nuageVspDeviceId); + if (nuageVspDevice == null) { + throw new InvalidParameterValueException("Could not find Nuage Vsp device with id: " + nuageVspDeviceId); + } + responseList.add(nuageVspDevice); + } else { + PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId); + } + responseList = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + } + + return responseList; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + try { + initNuageScheduledTasks(); + } catch (Exception ce) { + s_logger.warn("Failed to load NuageVsp configuration properties. Check if the NuageVsp properties are configured correctly"); + } + return true; + } + + private void initNuageScheduledTasks() { + Integer numOfSyncThreads = Integer.valueOf(_configDao.getValue(NuageVspManager.NuageVspSyncWorkers.key())); + Integer syncUpIntervalInMinutes = Integer.valueOf(_configDao.getValue(NuageVspManager.NuageVspSyncInterval.key())); + + if (numOfSyncThreads != null && syncUpIntervalInMinutes != null) { + ThreadFactory threadFactory = new ThreadFactory() { + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "Nuage Vsp sync task"); + if (thread.isDaemon()) + thread.setDaemon(false); + if (thread.getPriority() != Thread.NORM_PRIORITY) + thread.setPriority(Thread.NORM_PRIORITY); + return thread; + } + }; + scheduler = Executors.newScheduledThreadPool(numOfSyncThreads, threadFactory); + scheduler.scheduleWithFixedDelay(new NuageVspSyncTask("FLOATING_IP"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, + TimeUnit.MILLISECONDS); + scheduler.scheduleWithFixedDelay(new NuageVspSyncTask("ENTERPRISE_NTWK_MACRO"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, + TimeUnit.MILLISECONDS); + scheduler + .scheduleWithFixedDelay(new NuageVspSyncTask("ENTERPRISE"), ONE_MINUTE_MULTIPLIER * 15, ONE_MINUTE_MULTIPLIER * syncUpIntervalInMinutes, TimeUnit.MILLISECONDS); + } else { + s_logger.warn("NuageVsp configuration for syncWorkers=" + numOfSyncThreads + " syncInterval=" + syncUpIntervalInMinutes + + " could not be read properly. So, check if the properties are configured properly in global properties"); + } + } + + public class NuageVspSyncTask implements Runnable { + + private String nuageVspEntity; + + public NuageVspSyncTask(String nuageVspEntity) { + this.nuageVspEntity = nuageVspEntity; + } + + public String getNuageVspEntity() { + return nuageVspEntity; + } + + @Override + public void run() { + nuageVspSync.syncWithNuageVsp(nuageVspEntity); + } + } + + @Override + public String getConfigComponentName() { + return NuageVspManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {NuageVspSyncWorkers, NuageVspSyncInterval}; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java new file mode 100644 index 00000000000..65c8ae96fa3 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java @@ -0,0 +1,467 @@ +// +// 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.List; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.naming.ConfigurationException; + +import net.nuage.vsp.acs.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.NuageVspApiClient; +import net.nuage.vsp.acs.client.NuageVspElementClient; +import net.nuage.vsp.acs.client.NuageVspGuruClient; +import net.nuage.vsp.acs.client.NuageVspSyncClient; + +import org.apache.commons.codec.binary.Base64; +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.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.StartupVspCommand; +import com.cloud.agent.api.VspResourceAnswer; +import com.cloud.agent.api.VspResourceCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.agent.api.element.ShutDownVpcVspAnswer; +import com.cloud.agent.api.element.ShutDownVpcVspCommand; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.Host; +import com.cloud.resource.ServerResource; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; + +public class NuageVspResource extends ManagerBase implements ServerResource { + private static final Logger s_logger = Logger.getLogger(NuageVspResource.class); + + private String _name; + private String _guid; + private String _zoneId; + private String[] _cmsUserInfo; + private String _relativePath; + private int _numRetries; + private int _retryInterval; + + protected NuageVspApiClient _nuageVspApiClient; + protected NuageVspGuruClient _nuageVspGuruClient; + protected NuageVspElementClient _nuageVspElementClient; + protected NuageVspSyncClient _nuageVspSyncClient; + protected boolean _isNuageVspClientLoaded; + + private static final String CMS_USER_ENTEPRISE_NAME = "CSP"; + private static final String NUAGE_VSP_PLUGIN_ERROR_MESSAGE = "Nuage Vsp plugin client is not installed"; + private static final String NUAGE_PLUGIN_CLIENT_JAR_FILE = "/usr/share/nuagevsp/lib/nuage-vsp-acs-client.jar"; + private static final String NUAGE_VSP_API_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspApiClientImpl"; + private static final String NUAGE_VSP_SYNC_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspSyncClientImpl"; + private static final String NUAGE_VSP_ELEMENT_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspElementClientImpl"; + private static final String NUAGE_VSP_GURU_CLIENT_IMPL = "net.nuage.vsp.acs.client.impl.NuageVspGuruClientImpl"; + + @Override + public boolean configure(String name, Map 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"); + } + + String hostname = (String)params.get("hostname"); + if (hostname == null) { + throw new ConfigurationException("Unable to find hostname"); + } + + String cmsUser = (String)params.get("cmsuser"); + if (cmsUser == null) { + throw new ConfigurationException("Unable to find CMS username"); + } + + String cmsUserPassBase64 = (String)params.get("cmsuserpass"); + if (cmsUserPassBase64 == null) { + throw new ConfigurationException("Unable to find CMS password"); + } + + String port = (String)params.get("port"); + if (port == null) { + throw new ConfigurationException("Unable to find port"); + } + + String apiRelativePath = (String)params.get("apirelativepath"); + if ((apiRelativePath != null) && (!apiRelativePath.isEmpty())) { + String apiVersion = apiRelativePath.substring(apiRelativePath.lastIndexOf('/') + 1); + if (!Pattern.matches("v\\d+_\\d+", apiVersion)) { + throw new ConfigurationException("Incorrect API version"); + } + } else { + throw new ConfigurationException("Unable to find API version"); + } + + String retryCount = (String)params.get("retrycount"); + if ((retryCount != null) && (!retryCount.isEmpty())) { + try { + _numRetries = Integer.parseInt(retryCount); + } catch (NumberFormatException ex) { + throw new ConfigurationException("Number of retries has to be between 1 and 10"); + } + if ((_numRetries < 1) || (_numRetries > 10)) { + throw new ConfigurationException("Number of retries has to be between 1 and 10"); + } + } else { + throw new ConfigurationException("Unable to find number of retries"); + } + + String retryInterval = (String)params.get("retryinterval"); + if ((retryInterval != null) && (!retryInterval.isEmpty())) { + try { + _retryInterval = Integer.parseInt(retryInterval); + } catch (NumberFormatException ex) { + throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); + } + if ((_retryInterval < 0) || (_retryInterval > 10000)) { + throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); + } + } else { + throw new ConfigurationException("Unable to find retry interval"); + } + + _relativePath = new StringBuffer().append("https://").append(hostname).append(":").append(port).append(apiRelativePath).toString(); + + String cmsUserPass = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.decodeBase64(cmsUserPassBase64)); + _cmsUserInfo = new String[] {CMS_USER_ENTEPRISE_NAME, cmsUser, cmsUserPass}; + + try { + loadNuageClient(); + } catch (Exception e) { + throw new CloudRuntimeException("Failed to login to Nuage VSD on " + name + " as user " + cmsUser, e); + } + + try { + login(); + } catch (Exception e) { + s_logger.error("Failed to login to Nuage VSD on " + name + " as user " + cmsUser + " Exception " + e.getMessage()); + throw new CloudRuntimeException("Failed to login to Nuage VSD on " + name + " as user " + cmsUser, e); + } + + return true; + } + + protected void login() throws Exception { + isNuageVspApiLoaded(); + _nuageVspApiClient.login(); + } + + protected void loadNuageClient() throws Exception { + + try { + ClassLoader loader = NuageVspPluginClientLoader.getClassLoader(NUAGE_PLUGIN_CLIENT_JAR_FILE); + + Class nuageVspApiClientClass = Class.forName(NUAGE_VSP_API_CLIENT_IMPL, true, loader); + Class nuageVspSyncClientClass = Class.forName(NUAGE_VSP_SYNC_CLIENT_IMPL, true, loader); + Class nuageVspGuruClientClass = Class.forName(NUAGE_VSP_GURU_CLIENT_IMPL, true, loader); + Class nuageVspElementClientClass = Class.forName(NUAGE_VSP_ELEMENT_CLIENT_IMPL, true, loader); + + //Instantiate the instances + _nuageVspApiClient = (NuageVspApiClient)nuageVspApiClientClass.newInstance(); + _nuageVspApiClient.setNuageVspHost(_relativePath, _cmsUserInfo, _numRetries, _retryInterval); + _nuageVspSyncClient = (NuageVspSyncClient)nuageVspSyncClientClass.newInstance(); + _nuageVspSyncClient.setNuageVspApiClient(_nuageVspApiClient); + _nuageVspGuruClient = (NuageVspGuruClient)nuageVspGuruClientClass.newInstance(); + _nuageVspGuruClient.setNuageVspApiClient(_nuageVspApiClient); + _nuageVspElementClient = (NuageVspElementClient)nuageVspElementClientClass.newInstance(); + _nuageVspElementClient.setNuageVspApiClient(_nuageVspApiClient); + _isNuageVspClientLoaded = true; + } catch (Exception e) { + _isNuageVspClientLoaded = false; + String errorMessage = "Nuage Vsp Plugin client is not yet installed. Please install NuageVsp plugin client to use NuageVsp plugin in Cloudstack. "; + s_logger.warn(errorMessage + e.getMessage()); + throw new Exception(errorMessage); + } + + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public Host.Type getType() { + return Host.Type.L2Networking; + } + + @Override + public StartupCommand[] initialize() { + StartupVspCommand sc = new StartupVspCommand(); + sc.setGuid(_guid); + sc.setName(_name); + sc.setDataCenter(_zoneId); + sc.setPod(""); + sc.setPrivateIpAddress(""); + sc.setStorageIpAddress(""); + sc.setVersion(NuageVspResource.class.getPackage().getImplementationVersion()); + return new StartupCommand[] {sc}; + } + + @Override + public PingCommand getCurrentStatus(long id) { + if ((_relativePath == null) || (_relativePath.isEmpty()) || (_cmsUserInfo == null) || (_cmsUserInfo.length == 0)) { + s_logger.error("Failed to ping to Nuage VSD"); + return null; + } + try { + login(); + } catch (Exception e) { + s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " + _cmsUserInfo[1] + " Exception " + e.getMessage()); + return null; + } + 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 VspResourceCommand) { + return executeRequest((VspResourceCommand)cmd); + } + //Guru commands + else if (cmd instanceof ImplementNetworkVspCommand) { + return executeRequest((ImplementNetworkVspCommand)cmd); + } else if (cmd instanceof ReserveVmInterfaceVspCommand) { + return executeRequest((ReserveVmInterfaceVspCommand)cmd); + } else if (cmd instanceof ReleaseVmVspCommand) { + return executeRequest((ReleaseVmVspCommand)cmd); + } else if (cmd instanceof DeallocateVmVspCommand) { + return executeRequest((DeallocateVmVspCommand)cmd); + } else if (cmd instanceof TrashNetworkVspCommand) { + return executeRequest((TrashNetworkVspCommand)cmd); + } + //Element commands + else if (cmd instanceof ApplyAclRuleVspCommand) { + return executeRequest((ApplyAclRuleVspCommand)cmd); + } else if (cmd instanceof ApplyStaticNatVspCommand) { + return executeRequest((ApplyStaticNatVspCommand)cmd); + } else if (cmd instanceof ShutDownVpcVspCommand) { + return executeRequest((ShutDownVpcVspCommand)cmd); + } + //Sync Commands + else if (cmd instanceof SyncVspCommand) { + return executeRequest((SyncVspCommand)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(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + private Answer executeRequest(MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } + + private Answer executeRequest(VspResourceCommand cmd) { + try { + isNuageVspApiLoaded(); + if (cmd.getRequestType().equalsIgnoreCase("GETALL") || cmd.getRequestType().equalsIgnoreCase("GET") || cmd.getRequestType().equalsIgnoreCase("GETRELATED")) { + String resourceInfo = _nuageVspApiClient.executeRestApi(cmd.getRequestType(), cmd.getResource(), cmd.getResourceId(), cmd.getChildResource(), + cmd.getEntityDetails(), cmd.getResourceFilter(), cmd.getProxyUserUuid(), cmd.getProxyUserDomainuuid()); + return new VspResourceAnswer(cmd, resourceInfo, "Executed Issue Resource command"); + } + return new VspResourceAnswer(cmd, false, cmd.getRequestType() + " is not yet supported"); + } catch (Exception e) { + return new VspResourceAnswer(cmd, e); + } + } + + private Answer executeRequest(ImplementNetworkVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.implement(cmd.getNetworkDomainName(), cmd.getNetworkDomainPath(), cmd.getNetworkDomainUuid(), cmd.getNetworkAccountName(), + cmd.getNetworkAccountUuid(), cmd.getNetworkName(), cmd.getNetworkCidr(), cmd.getNetworkGateway(), cmd.getNetworkUuid(), cmd.isL3Network(), cmd.getVpcName(), + cmd.getVpcUuid(), cmd.isDefaultEgressPolicy(), cmd.getIpAddressRange()); + return new ImplementNetworkVspAnswer(cmd, true, "Created Nuage VSP network mapping to " + cmd.getNetworkName()); + } catch (Exception e) { + return new ImplementNetworkVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ReserveVmInterfaceVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + List> vmInterfaceInfo = _nuageVspGuruClient.reserve(cmd.getNicUuid(), cmd.getNicMacAddress(), cmd.getNetworkUuid(), cmd.isL3Network(), + cmd.getVpcUuid(), cmd.getNetworkDomainUuid(), cmd.getNetworksAccountUuid(), cmd.isDomainRouter(), cmd._getDomainRouterIp(), cmd._getVmInstanceName(), + cmd._getVmUuid()); + return new ReserveVmInterfaceVspAnswer(cmd, vmInterfaceInfo, "Created NIC in VSP that maps to nicUuid" + cmd.getNicUuid()); + } catch (Exception e) { + return new ReserveVmInterfaceVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ReleaseVmVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.release(cmd.getNetworkUuid(), cmd.getVmUuid(), cmd.getVmInstanceName()); + return new ReleaseVmVspAnswer(cmd, true, "VM has been deleted from VSP."); + } catch (Exception e) { + return new ReleaseVmVspAnswer(cmd, e); + } + } + + private Answer executeRequest(DeallocateVmVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.deallocate(cmd.getNetworkUuid(), cmd.getNicFrmDdUuid(), cmd.getNicMacAddress(), cmd.getNicIp4Address(), cmd.isL3Network(), cmd.getVpcUuid(), + cmd.getNetworksDomainUuid(), cmd.getVmInstanceName(), cmd.getVmUuid()); + return new DeallocateVmVspAnswer(cmd, true, "Deallocated VM from Nuage VSP."); + } catch (Exception e) { + return new DeallocateVmVspAnswer(cmd, e); + } + } + + private Answer executeRequest(TrashNetworkVspCommand cmd) { + try { + isNuageVspGuruLoaded(); + _nuageVspGuruClient.trash(cmd.getDomainUuid(), cmd.getNetworkUuid(), cmd.isL3Network(), cmd.getVpcUuid()); + return new TrashNetworkVspAnswer(cmd, true, "Deleted Nuage VSP network mapping to " + cmd.getNetworkUuid()); + } catch (Exception e) { + return new TrashNetworkVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ApplyStaticNatVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.applyStaticNats(cmd.getNetworkDomainUuid(), cmd.getVpcOrSubnetUuid(), cmd.isL3Network(), cmd.getStaticNatDetails()); + return new ApplyStaticNatVspAnswer(cmd, true, "Applied Static NAT to VSP network mapping to " + cmd.getVpcOrSubnetUuid()); + } catch (Exception e) { + return new ApplyStaticNatVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ApplyAclRuleVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.applyAclRules(cmd.getNetworkUuid(), cmd.getNetworkDomainUuid(), cmd.getVpcOrSubnetUuid(), cmd.isL3Network(), cmd.getAclRules(), cmd.isVpc(), + cmd.getNetworkId()); + return new ApplyAclRuleVspAnswer(cmd, true, "Applied ACL Rule to VSP network mapping to " + cmd.getVpcOrSubnetUuid()); + } catch (Exception e) { + return new ApplyAclRuleVspAnswer(cmd, e); + } + } + + private Answer executeRequest(ShutDownVpcVspCommand cmd) { + try { + isNuageVspElementLoaded(); + _nuageVspElementClient.shutDownVpc(cmd.getDomainUuid(), cmd.getVpcUuid()); + return new ShutDownVpcVspAnswer(cmd, true, "Shutdown VPC " + cmd.getVpcUuid()); + } catch (Exception e) { + return new ShutDownVpcVspAnswer(cmd, e); + } + } + + private Answer executeRequest(SyncVspCommand cmd) { + try { + isNuageVspSyncLoaded(); + _nuageVspSyncClient.syncWithNuageVsp(cmd.getNuageVspEntity()); + return new SyncVspAnswer(cmd, true, "Synced " + cmd.getNuageVspEntity() + " in VSP"); + } catch (Exception e) { + return new SyncVspAnswer(cmd, e); + } + } + + protected void isNuageVspApiLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspApiClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspGuruLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspGuruClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspElementLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspElementClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } + + protected void isNuageVspSyncLoaded() throws Exception { + if (!_isNuageVspClientLoaded || _nuageVspSyncClient == null) { + throw new Exception(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); + } + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java new file mode 100644 index 00000000000..4e1cc431e7e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSync.java @@ -0,0 +1,26 @@ +// +// 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.sync; + + +public interface NuageVspSync { + + public void syncWithNuageVsp(String nuageVspEntity); +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java new file mode 100644 index 00000000000..f3d19c16355 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/sync/NuageVspSyncImpl.java @@ -0,0 +1,72 @@ +// +// 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.sync; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; + +@Component +public class NuageVspSyncImpl implements NuageVspSync { + + private static final Logger s_logger = Logger.getLogger(NuageVspSyncImpl.class); + + @Inject + NuageVspDao _nuageVspDao; + @Inject + HostDao _hostDao; + @Inject + AgentManager _agentMgr; + + public void syncWithNuageVsp(String nuageVspEntity) { + //Get the NuageVspDevice and get the host information. + //This information is used to query VSP and synch the corresponding + //entities + List nuageVspDevices = _nuageVspDao.listAll(); + for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) { + + try { + HostVO nuageVspHost = _hostDao.findById(nuageVspDevice.getHostId()); + _hostDao.loadDetails(nuageVspHost); + SyncVspCommand cmd = new SyncVspCommand(nuageVspEntity); + SyncVspAnswer answer = (SyncVspAnswer)_agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("SyncNuageVspCommand for Nuage VSP Host " + nuageVspHost.getUuid() + " failed"); + if ((null != answer) && (null != answer.getDetails())) { + s_logger.error(answer.getDetails()); + } + } + } catch (Exception e) { + s_logger.warn("Failed to clean up " + nuageVspEntity + " in Vsp " + e.getMessage()); + } + } + } +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java new file mode 100644 index 00000000000..76b98234a0a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java @@ -0,0 +1,46 @@ +// +// 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 net.nuage.vsp.acs; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public class NuageVspPluginClientLoader { + + private static NuageVspPluginClientLoader nuageVspPluginClientClassloader; + private ClassLoader loader = null; + + private NuageVspPluginClientLoader(String nuagePluginClientJarLocation) { + try { + loader = URLClassLoader.newInstance(new URL[] {new URL("jar:file:" + nuagePluginClientJarLocation + "!/")}, + getClass().getClassLoader()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + public static ClassLoader getClassLoader(String nuagePluginClientJarLocation) { + if (nuageVspPluginClientClassloader == null) { + nuageVspPluginClientClassloader = new NuageVspPluginClientLoader(nuagePluginClientJarLocation); + } + return nuageVspPluginClientClassloader.loader; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java new file mode 100644 index 00000000000..d584c6f5369 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspApiClient.java @@ -0,0 +1,30 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package net.nuage.vsp.acs.client; + +public interface NuageVspApiClient { + + public void login() throws Exception; + + public void setNuageVspHost(String restRelativePath, String[] cmsUserInfo, int noofRetry, int retryInterval); + + public String executeRestApi(String method, String resource, String resourceId, String childResource, Object entityDetails, String resourceFilter, String proxyUserUuid, + String proxyUserDomainuuid) throws Exception; +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java new file mode 100644 index 00000000000..27c613b3c11 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspElementClient.java @@ -0,0 +1,36 @@ +// +// 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 net.nuage.vsp.acs.client; + +import java.util.List; +import java.util.Map; + +public interface NuageVspElementClient { + + public void applyStaticNats(String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> staticNatDetails) throws Exception; + + public void applyAclRules(String networkUuid, String networkDomainUuid, String vpcOrSubnetUuid, boolean isL3Network, List> aclRules, boolean isVpc, long networkId) + throws Exception; + + public void shutDownVpc(String domainUuid, String vpcUuid) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); + +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java new file mode 100644 index 00000000000..3c7f33d878e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspGuruClient.java @@ -0,0 +1,44 @@ +// +// 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 net.nuage.vsp.acs.client; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface NuageVspGuruClient { + + public void implement(String networkDomainName, String networkDomainPath, String networkDomainUuid, String networkAccountName, String networkAccountUuid, String networkName, + String networkCidr, String networkGateway, String networkUuid, boolean isL3Network, String vpcName, String vpcUuid, boolean defaultEgressPolicy, + Collection ipAddressRange) throws Exception; + + public List> reserve(String nicUuid, String nicMacAddress, String networkUuid, boolean isL3Network, String vpcUuid, String networkDomainUuid, + String networksAccountUuid, boolean isDomainRouter, String domainRouterIp, String vmInstanceName, String vmUuid) throws Exception; + + public void release(String networkUuid, String vmUuid, String vmInstanceName) throws Exception; + + public void deallocate(String networkUuid, String nicFrmDdUuid, String nicMacAddress, String nicIp4Address, boolean isL3Network, String vpcUuid, String networksDomainUuid, + String vmInstanceName, String vmUuid) throws Exception; + + public void trash(String domainUuid, String networkUuid, boolean isL3Network, String vpcUuid) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); + +} diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java new file mode 100644 index 00000000000..b9400f15158 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/client/NuageVspSyncClient.java @@ -0,0 +1,27 @@ +// +// 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 net.nuage.vsp.acs.client; + +public interface NuageVspSyncClient { + + public void syncWithNuageVsp(String nuageVspEntity) throws Exception; + + public void setNuageVspApiClient(NuageVspApiClient nuageVspApiClient); +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java new file mode 100644 index 00000000000..08d685f4599 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java @@ -0,0 +1,280 @@ +// +// 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.CloudException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.resource.ResourceManager; +import com.cloud.user.Account; +import com.cloud.vm.ReservationContext; + +public class NuageVspElementTest { + + private static final long NETWORK_ID = 42L; + NuageVspElement element = new NuageVspElement(); + NetworkOrchestrationService networkManager = mock(NetworkOrchestrationService.class); + NetworkModel networkModel = mock(NetworkModel.class); + NetworkServiceMapDao ntwkSrvcDao = mock(NetworkServiceMapDao.class); + AgentManager agentManager = mock(AgentManager.class); + HostDao hostDao = mock(HostDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + DomainDao domainDao = mock(DomainDao.class); + NetworkOfferingDao ntwkOfferingDao = mock(NetworkOfferingDao.class); + NetworkOfferingServiceMapDao ntwkOfferingSrvcDao = mock(NetworkOfferingServiceMapDao.class); + + Answer genericAnswer = new Answer() { + public Object answer(InvocationOnMock invocation) { + return null; + } + }; + + @Before + public void setUp() throws ConfigurationException { + element._resourceMgr = mock(ResourceManager.class); + element._ntwkSrvcDao = ntwkSrvcDao; + element._networkModel = networkModel; + element._agentMgr = agentManager; + element._hostDao = hostDao; + element._nuageVspDao = nuageVspDao; + element._ntwkOfferingSrvcDao = ntwkOfferingSrvcDao; + element._domainDao = domainDao; + element._ntwkOfferingDao = ntwkOfferingDao; + + // Standard responses + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + + element.configure("NuageVspTestElement", Collections. emptyMap()); + } + + @Test + public void testCcanHandle() { + final Network net = mock(Network.class); + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(net.getId()).thenReturn(NETWORK_ID); + + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + // Golden path + assertTrue(element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vlan); + // Only broadcastdomaintype Vsp is supported + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(net.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(false); + // No NuageVsp provider in the network + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(false); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + // NusageVsp provider does not provide Connectivity for this network + assertFalse(element.canHandle(net, Service.Connectivity)); + + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + // Only service Connectivity is supported + assertFalse(element.canHandle(net, Service.Dhcp)); + + } + + @Test + public void testImplement() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException { + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getBroadcastUri()).thenReturn(new URI("")); + when(networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + DeployDestination deployDest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + assertTrue(element.implement(network, offering, deployDest, context)); + } + + @Test + public void testVerifyServiceCombination() { + Set services = new HashSet(); + services.add(Service.Dhcp); + services.add(Service.StaticNat); + services.add(Service.SourceNat); + services.add(Service.Connectivity); + services.add(Service.Firewall); + assertTrue(element.verifyServicesCombination(services)); + + services = new HashSet(); + services.add(Service.Dhcp); + services.add(Service.StaticNat); + services.add(Service.Connectivity); + services.add(Service.Firewall); + assertFalse(element.verifyServicesCombination(services)); + } + + @Test + public void testApplyStaticNats() throws CloudException { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final DomainVO domVo = mock(DomainVO.class); + when(domainDao.findById(41l)).thenReturn(domVo); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + when(element.isL3Network(NETWORK_ID)).thenReturn(true); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ApplyStaticNatVspAnswer answer = mock(ApplyStaticNatVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyStaticNats(network, new ArrayList())); + } + + @Test + public void testApplyFWRules() throws Exception { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + + final ApplyAclRuleVspAnswer answer = mock(ApplyAclRuleVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyFWRules(network, new ArrayList())); + } + + @Test + public void testApplyNetworkACL() throws Exception { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getVpcId()).thenReturn(null); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + + final NetworkOfferingVO ntwkoffer = mock(NetworkOfferingVO.class); + when(ntwkoffer.getId()).thenReturn(NETWORK_ID); + when(ntwkoffer.getEgressDefaultPolicy()).thenReturn(true); + when(ntwkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ApplyAclRuleVspAnswer answer = mock(ApplyAclRuleVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + assertTrue(element.applyNetworkACLs(network, new ArrayList())); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java new file mode 100644 index 00000000000..f879f09b148 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java @@ -0,0 +1,386 @@ +// +// 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.junit.Before; +import org.junit.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapacityException; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.Mode; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicDao; + +public class NuageVspGuestNetworkGuruTest { + private static final long NETWORK_ID = 42L; + PhysicalNetworkDao physnetdao = mock(PhysicalNetworkDao.class); + DataCenterDao dcdao = mock(DataCenterDao.class); + NetworkOfferingServiceMapDao nosd = mock(NetworkOfferingServiceMapDao.class); + AgentManager agentManager = mock(AgentManager.class); + NetworkOrchestrationService netmgr = mock(NetworkOrchestrationService.class); + NetworkModel networkModel = mock(NetworkModel.class); + AccountDao accountDao = mock(AccountDao.class); + DomainDao domainDao = mock(DomainDao.class); + NicDao nicDao = mock(NicDao.class); + NetworkOfferingDao ntwkOfferDao = mock(NetworkOfferingDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + HostDao hostDao = mock(HostDao.class); + NetworkDao networkDao = mock(NetworkDao.class); + + NetworkDao netdao = mock(NetworkDao.class); + NuageVspGuestNetworkGuru guru; + + @Before + public void setUp() { + guru = new NuageVspGuestNetworkGuru(); + ((GuestNetworkGuru)guru)._physicalNetworkDao = physnetdao; + guru._physicalNetworkDao = physnetdao; + guru._nuageVspDao = nuageVspDao; + guru._dcDao = dcdao; + guru._ntwkOfferingSrvcDao = nosd; + guru._networkModel = networkModel; + guru._hostDao = hostDao; + guru._agentMgr = agentManager; + guru._networkDao = netdao; + guru._networkDao = networkDao; + guru._accountDao = accountDao; + guru._domainDao = domainDao; + guru._nicDao = nicDao; + guru._ntwkOfferingDao = ntwkOfferDao; + + final DataCenterVO dc = mock(DataCenterVO.class); + when(dc.getNetworkType()).thenReturn(NetworkType.Advanced); + when(dc.getGuestNetworkCidr()).thenReturn("10.1.1.1/24"); + + when(dcdao.findById((Long)any())).thenReturn(dc); + } + + @Test + public void testCanHandle() { + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VSP"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported TrafficType != Guest + when(offering.getTrafficType()).thenReturn(TrafficType.Management); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: GuestType Shared + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + // Not supported: Basic networking + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + assertFalse(guru.canHandle(offering, NetworkType.Basic, physnet) == true); + + // Not supported: IsolationMethod != STT + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + + } + + @Test + public void testDesign() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VSP"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + when(nosd.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork != null); + assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vsp); + } + + @Test + public void testDesignNoElementOnPhysicalNetwork() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"STT"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections. emptyList()); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testDesignNoIsolationMethodVSP() { + final PhysicalNetworkVO physnet = mock(PhysicalNetworkVO.class); + when(physnetdao.findById((Long)any())).thenReturn(physnet); + when(physnet.getIsolationMethods()).thenReturn(Arrays.asList(new String[] {"VLAN"})); + when(physnet.getId()).thenReturn(NETWORK_ID); + + mock(NuageVspDeviceVO.class); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Collections. emptyList()); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Isolated); + + final DeploymentPlan plan = mock(DeploymentPlan.class); + final Network network = mock(Network.class); + final Account account = mock(Account.class); + + final Network designednetwork = guru.design(offering, plan, network, account); + assertTrue(designednetwork == null); + } + + @Test + public void testReserve() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, URISyntaxException { + final Network network = mock(Network.class); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + when(network.getAccountId()).thenReturn(NETWORK_ID); + when(network.getVpcId()).thenReturn(null); + when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1")); + + final DataCenterVO dataCenter = mock(DataCenterVO.class); + when(dcdao.findById(NETWORK_ID)).thenReturn(dataCenter); + final AccountVO networksAccount = mock(AccountVO.class); + when(networksAccount.getUuid()).thenReturn("aaaa-abbbb"); + when(networksAccount.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL); + when(accountDao.findById(NETWORK_ID)).thenReturn(networksAccount); + final DomainVO networksDomain = mock(DomainVO.class); + when(networksDomain.getUuid()).thenReturn("aaaaa-bbbbb"); + when(domainDao.findById(NETWORK_ID)).thenReturn(networksDomain); + + final NicVO nicvo = mock(NicVO.class); + when(nicvo.getId()).thenReturn(NETWORK_ID); + when(nicvo.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa"); + when(nicvo.getUuid()).thenReturn("aaaa-fffff"); + when(nicDao.findById(NETWORK_ID)).thenReturn(nicvo); + + final VirtualMachineProfile vm = mock(VirtualMachineProfile.class); + when(vm.getType()).thenReturn(VirtualMachine.Type.User); + when(vm.getInstanceName()).thenReturn(""); + when(vm.getUuid()).thenReturn("aaaa-bbbbb"); + + NicProfile nicProfile = mock(NicProfile.class); + when(nicProfile.getUuid()).thenReturn("aaa-bbbb"); + when(nicProfile.getId()).thenReturn(NETWORK_ID); + when(nicProfile.getMacAddress()).thenReturn("aa-aa-aa-aa-aa-aa"); + + final NetworkOfferingVO ntwkoffering = mock(NetworkOfferingVO.class); + when(ntwkoffering.getId()).thenReturn(NETWORK_ID); + when(ntwkOfferDao.findById(NETWORK_ID)).thenReturn(ntwkoffering); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + when(domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); + final ReserveVmInterfaceVspAnswer answer = mock(ReserveVmInterfaceVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(answer.getInterfaceDetails()).thenReturn(new ArrayList>()); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.reserve(nicProfile, network, vm, mock(DeployDestination.class), mock(ReservationContext.class)); + } + + @Test + public void testRelease() { + final NicProfile nicProfile = mock(NicProfile.class); + when(nicProfile.getNetworkId()).thenReturn(NETWORK_ID); + final NetworkVO network = mock(NetworkVO.class); + when(network.getUuid()).thenReturn("aaaaaa-ffffff"); + when(network.getName()).thenReturn("aaaaaa"); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(networkDao.findById(NETWORK_ID)).thenReturn(network); + + final VirtualMachineProfile vm = mock(VirtualMachineProfile.class); + when(vm.getType()).thenReturn(VirtualMachine.Type.User); + when(vm.getInstanceName()).thenReturn(""); + when(vm.getUuid()).thenReturn("aaaa-bbbbb"); + + final VirtualMachine virtualMachine = mock(VirtualMachine.class); + when(vm.getVirtualMachine()).thenReturn(virtualMachine); + when(virtualMachine.getState()).thenReturn(State.Stopping); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final ReleaseVmVspAnswer answer = mock(ReleaseVmVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + guru.release(nicProfile, vm, "aaaaa-fffff"); + } + + @Test + public void testImplementNetwork() throws URISyntaxException, InsufficientVirtualNetworkCapacityException { + final Network network = mock(Network.class); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getUuid()).thenReturn("aaaaaa"); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); + when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDomainId()).thenReturn(NETWORK_ID); + when(network.getAccountId()).thenReturn(NETWORK_ID); + when(network.getVpcId()).thenReturn(null); + when(network.getState()).thenReturn(com.cloud.network.Network.State.Implementing); + when(network.getTrafficType()).thenReturn(TrafficType.Guest); + when(network.getMode()).thenReturn(Mode.Static); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Vsp); + when(network.getBroadcastUri()).thenReturn(new URI("vsp://aaaaaa-aavvv/10.1.1.1")); + when(network.getGateway()).thenReturn("10.1.1.1"); + when(network.getCidr()).thenReturn("10.1.1.0/24"); + when(network.getName()).thenReturn("iso"); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getTags()).thenReturn("aaaa"); + when(offering.getEgressDefaultPolicy()).thenReturn(true); + + when(networkModel.findPhysicalNetworkId(NETWORK_ID, "aaa", TrafficType.Guest)).thenReturn(NETWORK_ID); + + final ReservationContext reserveContext = mock(ReservationContext.class); + final Domain domain = mock(Domain.class); + when(reserveContext.getDomain()).thenReturn(domain); + when(domain.getName()).thenReturn("aaaaa"); + final Account account = mock(Account.class); + when(account.getAccountId()).thenReturn(NETWORK_ID); + when(reserveContext.getAccount()).thenReturn(account); + final DomainVO domainVo = mock(DomainVO.class); + when(domainDao.findById(NETWORK_ID)).thenReturn(domainVo); + final AccountVO accountVo = mock(AccountVO.class); + when(accountDao.findById(NETWORK_ID)).thenReturn(accountVo); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final ImplementNetworkVspAnswer answer = mock(ImplementNetworkVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + final DataCenter dc = mock(DataCenter.class); + when(dc.getId()).thenReturn(NETWORK_ID); + final DeployDestination deployDest = mock(DeployDestination.class); + when(deployDest.getDataCenter()).thenReturn(dc); + guru.implement(network, offering, deployDest, reserveContext); + } + +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java new file mode 100644 index 00000000000..a8bed6d1199 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/manager/NuageVspManagerTest.java @@ -0,0 +1,111 @@ +// +// 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.manager; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; + +import javax.naming.ConfigurationException; + +import org.junit.Before; +import org.junit.Test; + +import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.ListNuageVspDevicesCmd; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NuageVspDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.resource.ResourceManager; + +public class NuageVspManagerTest { + private static final long NETWORK_ID = 42L; + + PhysicalNetworkDao physicalNetworkDao = mock(PhysicalNetworkDao.class); + PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao = mock(PhysicalNetworkServiceProviderDao.class); + ResourceManager resourceMgr = mock(ResourceManager.class); + HostDetailsDao hostDetailsDao = mock(HostDetailsDao.class); + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + NetworkDao networkDao = mock(NetworkDao.class); + HostDao hostDao = mock(HostDao.class); + + NuageVspManagerImpl manager; + + @Before + public void setUp() { + manager = new NuageVspManagerImpl(); + + manager._physicalNetworkServiceProviderDao = physicalNetworkServiceProviderDao; + manager._physicalNetworkDao = physicalNetworkDao; + manager._resourceMgr = resourceMgr; + manager._hostDetailsDao = hostDetailsDao; + manager._nuageVspDao = nuageVspDao; + manager._networkDao = networkDao; + manager._hostDao = hostDao; + } + + @Test + public void testDeleteNuageVspDevice() throws ConfigurationException { + + final PhysicalNetworkVO physicalNetwork = mock(PhysicalNetworkVO.class); + when(physicalNetwork.getDataCenterId()).thenReturn(NETWORK_ID); + when(physicalNetwork.getId()).thenReturn(NETWORK_ID); + when(physicalNetworkDao.findById(NETWORK_ID)).thenReturn(physicalNetwork); + + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDao.findById(NETWORK_ID)).thenReturn(nuageVspDevice); + + when(networkDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(new ArrayList()); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final DeleteNuageVspDeviceCmd cmd = mock(DeleteNuageVspDeviceCmd.class); + when(cmd.getNuageVspDeviceId()).thenReturn(NETWORK_ID); + + manager.deleteNuageVspDevice(cmd); + } + + @Test + public void testListNuageVspDevices() { + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + + final PhysicalNetworkVO phyNtwkVO = mock(PhysicalNetworkVO.class); + when(physicalNetworkDao.findById(NETWORK_ID)).thenReturn(phyNtwkVO); + when(nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(new ArrayList()); + + final ListNuageVspDevicesCmd cmd = mock(ListNuageVspDevicesCmd.class); + when(cmd.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(cmd.getNuageVspDeviceId()).thenReturn(null); + manager.listNuageVspDevices(cmd); + } +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java new file mode 100644 index 00000000000..db359b6768a --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java @@ -0,0 +1,252 @@ +// +// 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.assertTrue; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import net.nuage.vsp.acs.client.NuageVspApiClient; +import net.nuage.vsp.acs.client.NuageVspElementClient; +import net.nuage.vsp.acs.client.NuageVspGuruClient; +import net.nuage.vsp.acs.client.NuageVspSyncClient; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.element.ApplyAclRuleVspAnswer; +import com.cloud.agent.api.element.ApplyAclRuleVspCommand; +import com.cloud.agent.api.element.ApplyStaticNatVspAnswer; +import com.cloud.agent.api.element.ApplyStaticNatVspCommand; +import com.cloud.agent.api.element.ShutDownVpcVspAnswer; +import com.cloud.agent.api.element.ShutDownVpcVspCommand; +import com.cloud.agent.api.guru.DeallocateVmVspAnswer; +import com.cloud.agent.api.guru.DeallocateVmVspCommand; +import com.cloud.agent.api.guru.ImplementNetworkVspAnswer; +import com.cloud.agent.api.guru.ImplementNetworkVspCommand; +import com.cloud.agent.api.guru.ReleaseVmVspAnswer; +import com.cloud.agent.api.guru.ReleaseVmVspCommand; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspAnswer; +import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; +import com.cloud.agent.api.guru.TrashNetworkVspAnswer; +import com.cloud.agent.api.guru.TrashNetworkVspCommand; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.agent.api.sync.SyncVspCommand; +import com.cloud.host.Host; + +public class NuageVspResourceTest { + NuageVspResource _resource; + NuageVspApiClient _mockNuageVspApiClient = mock(NuageVspApiClient.class); + NuageVspElementClient _mockNuageVspElementClient = mock(NuageVspElementClient.class); + NuageVspGuruClient _mockNuageVspGuruClient = mock(NuageVspGuruClient.class); + NuageVspSyncClient _mockNuageVspSyncClient = mock(NuageVspSyncClient.class); + Map _parameters; + + Answer genericAnswer = new Answer() { + public Object answer(InvocationOnMock invocation) { + return null; + } + }; + + @Before + public void setUp() throws Exception { + _resource = new NuageVspResource() { + + @Override + protected void loadNuageClient() { + _isNuageVspClientLoaded = true; + _nuageVspApiClient = _mockNuageVspApiClient; + _nuageVspElementClient = _mockNuageVspElementClient; + _nuageVspGuruClient = _mockNuageVspGuruClient; + _nuageVspSyncClient = _mockNuageVspSyncClient; + + } + + protected void isNuageVspApiLoaded() throws Exception { + } + + protected void isNuageVspGuruLoaded() throws Exception { + } + + protected void isNuageVspElementLoaded() throws Exception { + } + + protected void isNuageVspSyncLoaded() throws Exception { + } + + protected void login() throws Exception { + } + + }; + + _parameters = new HashMap(); + _parameters.put("name", "nuagevsptestdevice"); + _parameters.put("guid", "aaaaa-bbbbb-ccccc"); + _parameters.put("zoneId", "blublub"); + _parameters.put("hostname", "nuagevsd"); + _parameters.put("cmsuser", "cmsuser"); + _parameters.put("cmsuserpass", "cmsuserpass"); + _parameters.put("port", "8443"); + _parameters.put("apirelativepath", "nuage/api/v1_0"); + _parameters.put("retrycount", "3"); + _parameters.put("retryinterval", "3"); + } + + @Test(expected = Exception.class) + public void resourceConfigureFailure() throws Exception { + _resource.configure("NuageVspResource", Collections. emptyMap()); + } + + @Test + public void resourceConfigure() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + assertTrue("nuagevsptestdevice".equals(_resource.getName())); + assertTrue(_resource.getType() == Host.Type.L2Networking); + } + + @Test + public void testInitialization() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + StartupCommand[] sc = _resource.initialize(); + assertTrue(sc.length == 1); + assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid())); + assertTrue("nuagevsptestdevice".equals(sc[0].getName())); + assertTrue("blublub".equals(sc[0].getDataCenter())); + } + + @Test + public void testPingCommandStatus() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + PingCommand ping = _resource.getCurrentStatus(42); + assertTrue(ping != null); + assertTrue(ping.getHostId() == 42); + assertTrue(ping.getHostType() == Host.Type.L2Networking); + } + + @Test + public void testImplementNetworkVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ImplementNetworkVspCommand impNtwkCmd = new ImplementNetworkVspCommand("networkDomainName", "networkDomainPath", "networkDomainUuid", "networkAccountName", + "networkAccountUuid", "networkName", "networkCidr", "networkGateway", "networkUuid", true, "vpcName", "vpcUuid", true, new ArrayList()); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).implement("networkDomainName", "networkDomainPath", "networkDomainUuid", "networkAccountName", "networkAccountUuid", + "networkName", "networkCidr", "networkGateway", "networkUuid", true, "vpcName", "vpcUuid", true, new ArrayList()); + ImplementNetworkVspAnswer implNtwkAns = (ImplementNetworkVspAnswer)_resource.executeRequest(impNtwkCmd); + assertTrue(implNtwkAns.getResult()); + } + + @Test + public void testReserveVmInterfaceVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ReserveVmInterfaceVspCommand rsrvVmInfCmd = new ReserveVmInterfaceVspCommand("nicUuid", "nicMacAddress", "networkUuid", true, "vpcUuid", "networkDomainUuid", + "networksAccountUuid", false, "domainRouterIp", "vmInstanceName", "vmUuid", "vmUserName", "vmUserDomainName"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).reserve("nicUuid", "nicMacAddress", "networkUuid", true, "vpcUuid", "networkDomainUuid", "networksAccountUuid", + false, "domainRouterIp", "vmInstanceName", "vmUuid"); + ReserveVmInterfaceVspAnswer rsrvVmInfAns = (ReserveVmInterfaceVspAnswer)_resource.executeRequest(rsrvVmInfCmd); + assertTrue(rsrvVmInfAns.getResult()); + } + + @Test + public void testReleaseVmVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ReleaseVmVspCommand releaseVmCmd = new ReleaseVmVspCommand("networkUuid", "vmUuid", "vmInstanceName"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).release("networkUuid", "vmUuid", "vmInstanceName"); + ReleaseVmVspAnswer releaseVmAns = (ReleaseVmVspAnswer)_resource.executeRequest(releaseVmCmd); + assertTrue(releaseVmAns.getResult()); + } + + @Test + public void testDeallocateVmVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + DeallocateVmVspCommand dellocateVmCmd = new DeallocateVmVspCommand("networkUuid", "nicFrmDdUuid", "nicMacAddress", "nicIp4Address", true, "vpcUuid", "networksDomainUuid", + "vmInstanceName", "vmUuid"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).deallocate("networkUuid", "nicFrmDdUuid", "nicMacAddress", "nicIp4Address", true, "vpcUuid", "networksDomainUuid", + "vmInstanceName", "vmUuid"); + DeallocateVmVspAnswer dellocateVmAns = (DeallocateVmVspAnswer)_resource.executeRequest(dellocateVmCmd); + assertTrue(dellocateVmAns.getResult()); + } + + @Test + public void testTrashNetworkVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + TrashNetworkVspCommand trashNtwkCmd = new TrashNetworkVspCommand("domainUuid", "networkUuid", true, "vpcUuid"); + doAnswer(genericAnswer).when(_mockNuageVspGuruClient).trash("domainUuid", "networkUuid", true, "vpcUuid"); + TrashNetworkVspAnswer trashNtwkAns = (TrashNetworkVspAnswer)_resource.executeRequest(trashNtwkCmd); + assertTrue(trashNtwkAns.getResult()); + } + + @Test + public void testApplyStaticNatVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ApplyStaticNatVspCommand applyNatCmd = new ApplyStaticNatVspCommand("networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>()); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyStaticNats("networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>()); + ApplyStaticNatVspAnswer applyNatAns = (ApplyStaticNatVspAnswer)_resource.executeRequest(applyNatCmd); + assertTrue(applyNatAns.getResult()); + } + + @Test + public void testApplyAclRuleVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ApplyAclRuleVspCommand applyAclCmd = new ApplyAclRuleVspCommand("networkUuid", "networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>(), false, + 100); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyAclRules("networkUuid", "networkDomainUuid", "vpcOrSubnetUuid", true, new ArrayList>(), + false, 100); + ApplyAclRuleVspAnswer applyAclAns = (ApplyAclRuleVspAnswer)_resource.executeRequest(applyAclCmd); + assertTrue(applyAclAns.getResult()); + } + + @Test + public void testShutDownVpcVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + ShutDownVpcVspCommand shutVpcCmd = new ShutDownVpcVspCommand("domainUuid", "vpcUuid"); + doAnswer(genericAnswer).when(_mockNuageVspElementClient).shutDownVpc("domainUuid", "vpcUuid"); + ShutDownVpcVspAnswer shutVpcAns = (ShutDownVpcVspAnswer)_resource.executeRequest(shutVpcCmd); + assertTrue(shutVpcAns.getResult()); + } + + @Test + public void testSyncVspCommand() throws Exception { + _resource.configure("NuageVspResource", _parameters); + + SyncVspCommand shutVpcCmd = new SyncVspCommand("nuageVspEntity"); + doAnswer(genericAnswer).when(_mockNuageVspSyncClient).syncWithNuageVsp("nuageVspEntity"); + SyncVspAnswer shutVpcAns = (SyncVspAnswer)_resource.executeRequest(shutVpcCmd); + assertTrue(shutVpcAns.getResult()); + } +} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java new file mode 100644 index 00000000000..f9e503d5aeb --- /dev/null +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/sync/NuageVspSyncTest.java @@ -0,0 +1,73 @@ +// +// 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.sync; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.sync.SyncVspAnswer; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.network.NuageVspDeviceVO; +import com.cloud.network.dao.NuageVspDao; + +public class NuageVspSyncTest { + private static final long NETWORK_ID = 42L; + NuageVspDao nuageVspDao = mock(NuageVspDao.class); + AgentManager agentManager = mock(AgentManager.class); + HostDao hostDao = mock(HostDao.class); + + NuageVspSyncImpl sync; + + @Before + public void setUp() { + sync = new NuageVspSyncImpl(); + sync._nuageVspDao = nuageVspDao; + sync._agentMgr = agentManager; + sync._hostDao = hostDao; + } + + @Test + public void testSyncWithNuageVsp() { + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(nuageVspDevice.getId()).thenReturn(NETWORK_ID); + when(nuageVspDao.listAll()).thenReturn(Arrays.asList(new NuageVspDeviceVO[] {nuageVspDevice})); + + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + when(hostDao.findById(NETWORK_ID)).thenReturn(host); + + final SyncVspAnswer answer = mock(SyncVspAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + sync.syncWithNuageVsp("users"); + } +} diff --git a/plugins/pom.xml b/plugins/pom.xml index 802e2ea3755..eff5a01856e 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -163,6 +163,17 @@ network-elements/juniper-srx + + nuagevsp + + + noredist + + + + network-elements/nuage-vsp + + vmware diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 51122e0c9e9..013da0b70bd 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2304,7 +2304,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.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp)) { continue; } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1940f4839a8..42ac19fb98c 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -4496,7 +4496,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override public boolean isOfferingForVpc(NetworkOffering offering) { boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter) || - _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter); + _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter) || + _ntwkOffServiceMapDao.getDistinctProviders(offering.getId()).contains(Provider.NuageVsp.getName()); return vpcProvider; } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index c7237c1541c..9971bd5583d 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -207,7 +207,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter, - Provider.Ovs); + Provider.Ovs, Provider.NuageVsp); int _cleanupInterval; int _maxNetworks; @@ -320,6 +320,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis Set sdnProviders = new HashSet(); sdnProviders.add(Provider.NiciraNvp); sdnProviders.add(Provider.JuniperContrailVpcRouter); + sdnProviders.add(Provider.NuageVsp); boolean sourceNatSvc = false; boolean firewallSvs = false; diff --git a/setup/db/db/schema-440to450.sql b/setup/db/db/schema-440to450.sql index d047060d26e..6cb81c65fa1 100644 --- a/setup/db/db/schema-440to450.sql +++ b/setup/db/db/schema-440to450.sql @@ -63,6 +63,18 @@ CREATE VIEW `cloud`.`disk_offering_view` AS where disk_offering.state='ACTIVE'; +DROP TABLE IF EXISTS `cloud`.`external_nuage_vsp_devices`; +CREATE TABLE `cloud`.`external_nuage_vsp_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 nuage vsp is added', + `provider_name` varchar(255) NOT NULL COMMENT 'the service provider name corresponding to this nuage vsp device', + `device_name` varchar(255) NOT NULL COMMENT 'the name of the nuage vsp device', + `host_id` bigint unsigned NOT NULL COMMENT 'host id corresponding to the external nuage vsp device', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_nuage_vsp_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_nuage_vsp_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP VIEW IF EXISTS `cloud`.`service_offering_view`; CREATE VIEW `cloud`.`service_offering_view` AS diff --git a/test/integration/component/test_nuage_vsp.py b/test/integration/component/test_nuage_vsp.py new file mode 100644 index 00000000000..143fe391a71 --- /dev/null +++ b/test/integration/component/test_nuage_vsp.py @@ -0,0 +1,312 @@ +# 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. + +""" P1 tests for NuageVsp network Plugin +""" +#Import Local Modules +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * +from marvin.lib.utils import (cleanup_resources, + random_gen, validateList) +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Host, + Network, + NATRule, + Configurations) +from marvin.lib.common import (get_domain, + get_zone, + get_template) +from marvin.sshClient import SshClient +from marvin.codes import PASS +import time + + +class Services: + """Test NuageVsp plugin + """ + + def __init__(self): + self.services = { + "account": { + "email": "cloudstack@cloudmonkey.com", + "firstname": "cloudstack", + "lastname": "bob", + "username": "bobbuilder", + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, # in MHz + "memory": 128, # In MBs + }, + "virtual_machine": { + "displayname": "TestVM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "nuage_vsp_device": { + "hostname": '192.168.0.7', + "username": 'testusername', + "password": 'testpassword', + "port": '8443', + "apiversion": 'v1_0', + "retrycount": '4', + "retryinterval": '60' + }, + #services supported by Nuage for isolated networks. + "network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "UserData": 'VirtualRouter', + "Dhcp" : 'NuageVsp', + "Connectivity" : 'NuageVsp', + "StaticNat" : 'NuageVsp', + "SourceNat" : 'NuageVsp', + "Firewall" : 'NuageVsp' + }, + }, + "network": { + "name": "nuage", + "displaytext": "nuage", + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + "timeout": 10 + } + +class TestNuageVsp(cloudstackTestCase): + + + @classmethod + def setUpClass(cls): + cls._cleanup = [] + cls.testClient = super(TestNuageVsp, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + #nuage vsp device brings the Nuage virtual service platform into play + cls.nuage_services = cls.services["nuage_vsp_device"] + try: + + resp = listPhysicalNetworks.listPhysicalNetworksCmd() + resp.zoneid = cls.zone.id + physical_networks = cls.api_client.listPhysicalNetworks(resp) + if isinstance(physical_networks, list): + physical_network = physical_networks[1] + resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd() + resp.name = 'NuageVsp' + resp.physicalnetworkid = physical_network.id + nw_service_providers = cls.api_client.listNetworkServiceProviders(resp) + if isinstance(nw_service_providers, list): + nuage_provider = nw_service_providers[0] + else: + #create network service provider and add nuage vsp device + resp_add_nsp = addNetworkServiceProvider.addNetworkServiceProviderCmd() + resp_add_nsp.name = 'NuageVsp' + resp_add_nsp.physicalnetworkid = physical_network.id + nuage_provider = cls.api_client.addNetworkServiceProvider(resp_add_nsp) + resp_add_device = addNuageVspDevice.addNuageVspDeviceCmd() + resp_add_device.physicalnetworkid = physical_network.id + resp_add_device.username = cls.nuage_services["username"] + resp_add_device.password = cls.nuage_services["password"] + resp_add_device.hostname = cls.nuage_services["hostname"] + resp_add_device.apiversion = cls.nuage_services["apiversion"] + resp_add_device.retrycount = cls.nuage_services["retrycount"] + resp_add_device.retryinterval = cls.nuage_services["retryinterval"] + cls.nuage = cls.api_client.addNuageVspDevice(resp_add_device) + + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + cls._cleanup.append(cls.network_offering) + + cls.network_offering.update(cls.api_client, state='Enabled') + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + except Exception as e: + cls.tearDownClass() + raise Exception ("Warning: Exception in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + self.debug("Cleaning up the resources") + cleanup_resources(self.apiclient, self.cleanup) + interval = Configurations.list( + self.apiclient, + name='network.gc.interval' + ) + wait = Configurations.list( + self.apiclient, + name='network.gc.wait' + ) + #time.sleep(int(interval[0].value) + int(wait[0].value)) + self.debug("Cleanup complete!") + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + + @attr(tags = ["advancedns"]) + def test_network_vsp(self): + """Test nuage Network and VM Creation + """ + + + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % self.network.id) + + self.debug("Deploying VM in account: %s" % self.account.name) + + virtual_machine_1 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_1.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_1.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Deploying another VM in account: %s" % + self.account.name) + + virtual_machine_2 = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(self.network.id)] + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=virtual_machine_2.id + ) + + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" \ + % virtual_machine_2.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list" + ) + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + VirtualMachine.delete(virtual_machine_1, self.apiclient) + + # Deleting a single VM + VirtualMachine.delete(virtual_machine_2, self.apiclient) + + # Delete Network + Network.delete(self.network, self.apiclient) + + return diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index 827d6bf4e48..bcc8417c3c5 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -133,6 +133,7 @@ known_categories = { 'Tags': 'Resource tags', 'NiciraNvpDevice': 'Nicira NVP', 'BigSwitchVnsDevice': 'BigSwitch VNS', + 'NuageVsp': 'Nuage VSP', 'AutoScale': 'AutoScale', 'Counter': 'AutoScale', 'Condition': 'AutoScale', diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index e9d84de9b2d..c84d0ddea0e 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -351,6 +351,7 @@ dictionary = { 'label.add.new.PA': '', 'label.add.new.tier': '', 'label.add.NiciraNvp.device': '', +'label.add.NuageVsp.device': '', 'label.add.pod': '', 'label.add.port.forwarding.rule': '', 'label.add.primary.storage': '', @@ -399,6 +400,7 @@ dictionary = { 'label.anti.affinity.group': '', 'label.anti.affinity.groups': '', 'label.api.key': '', +'label.api.version': '', 'label.apply': '', 'label.assign': '', 'label.assign.to.load.balancer': '', @@ -506,6 +508,7 @@ dictionary = { 'label.delete.gateway': '', 'label.delete.NetScaler': '', 'label.delete.NiciraNvp': '', +'label.delete.NuageVsp': '', 'label.delete.project': '', 'label.delete.SRX': '', 'label.delete.PA': '', @@ -998,6 +1001,7 @@ dictionary = { 'label.restart.required': '', 'label.restart.vpc': '', 'label.restore': '', +'label.retry.interval': '', 'label.review': '', 'label.revoke.project.invite': '', 'label.role': '', @@ -1430,6 +1434,7 @@ dictionary = { 'message.confirm.action.force.reconnect': '', 'message.confirm.delete.F5': '', 'message.confirm.delete.NetScaler': '', +'message.confirm.delete.NuageVsp': '', 'message.confirm.delete.SRX': '', 'message.confirm.delete.PA': '', 'message.confirm.destroy.router': '', diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 9311e378425..895f8e86d43 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -2176,7 +2176,7 @@ //p.s. Netscaler is supported in both vpc and non-vpc if ($useVpc.is(':visible') && $useVpcCb.is(':checked')) { //*** vpc *** $optionsOfProviders.each(function(index) { - if ($(this).val() == 'InternalLbVm' || $(this).val() == 'VpcVirtualRouter' || $(this).val() == 'Netscaler') { + if ($(this).val() == 'InternalLbVm' || $(this).val() == 'VpcVirtualRouter' || $(this).val() == 'Netscaler' || $(this).val() == 'NuageVsp' || $(this).val() == 'NuageVspVpc') { $(this).attr('disabled', false); } else { $(this).attr('disabled', true); @@ -3456,7 +3456,9 @@ var networkServiceObjs = []; networkServiceObjs.push({ name: 'Dhcp', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'Dns', @@ -3472,15 +3474,21 @@ }); networkServiceObjs.push({ name: 'StaticNat', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'SourceNat', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'NetworkACL', - provider: [{name: 'VpcVirtualRouter'}] + provider: [ + {name: 'VpcVirtualRouter'}, + {name: 'NuageVsp'}] }); networkServiceObjs.push({ name: 'PortForwarding', @@ -3500,7 +3508,8 @@ provider: [ {name: 'NiciraNvp'}, {name: 'Ovs'}, - {name: 'JuniperContrailVpcRouter'} + {name: 'JuniperContrailVpcRouter'}, + {name: 'NuageVsp'} ] }); diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 74a08bc8db8..2075e30f02d 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -1250,5 +1250,34 @@ cloudStack.docs = { helpVpcOfferingDescription: { desc: 'A short description of the offering that can be displayed to users', externalLink: '' + }, + // Add Nuage VSP + helpVspHostname: { + desc: 'The hostname/IP address of Nuage VSD', + externalLink: '' + }, + helpVspUsername: { + desc: 'A name of the CMS user in Nuage VSD.', + externalLink: '' + }, + helpVspPassword: { + desc: 'The password for the CMS user in Nuage VSD.', + externalLink: '' + }, + helpVspPort: { + desc: 'The port to communicate with Nuage VSD. e.g. Unspecified/0 if using HAProxy for load balancing or 8443 if connecting directly to a VSD server.', + externalLink: '' + }, + helpVspApiVersion: { + desc: 'The API version of Nuage VSD', + externalLink: '' + }, + helpVspRetries: { + desc: 'Number of times to attempt a command on Nuage VSD before considering the operation failed. Valid values [1 - 10].', + externalLink: '' + }, + helpVspRetryInterval: { + desc: 'The interval of time in milliseconds to wait on failure before attempting to resend the command to Nuage VSD. Valid values [0 - 10000].', + externalLink: '' } }; diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 9012580189c..502007f5017 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -6689,6 +6689,249 @@ } } }, + // Nuage Vsp provider detail view + nuageVsp: { + type: 'detailView', + id: 'nuageVspProvider', + label: 'label.nuageVsp', + viewAll: { + label: 'label.devices', + path: '_zone.nuageVspDevices' + }, + tabs: { + details: { + title: 'label.details', + fields: [{ + name: { + label: 'label.name' + } + }, { + state: { + label: 'label.state' + } + }], + dataProvider: function(args) { + refreshNspData("NuageVsp"); + var providerObj; + $(nspHardcodingArray).each(function() { + if (this.id == "nuageVsp") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('nuageVsp') + }); + } + } + }, + actions: { + add: { + label: 'label.add.NuageVsp.device', + createForm: { + title: 'label.add.NuageVsp.device', + preFilter: function(args) {}, + fields: { + hostname: { + label: 'label.host.name', + validation: { + required: true + }, + docID: 'helpVspHostname' + }, + username: { + label: 'label.username', + validation: { + required: true + }, + docID: 'helpVspUsername' + }, + password: { + label: 'label.password', + isPassword: true, + validation: { + required: true + }, + docID: 'helpVspPassword' + }, + port: { + label: 'label.port', + validation: { + required: false, + number: true + }, + docID: 'helpVspPort' + }, + apiversion: { + label: 'label.api.version', + defaultValue: 'v1_0', + validation: { + required: true + }, + docID: 'helpVspApiVersion' + }, + retrycount: { + label: 'label.numretries', + defaultValue: '4', + validation: { + required: true, + number: true + }, + docID: 'helpVspRetries' + }, + retryinterval: { + label: 'label.retry.interval', + defaultValue: '60', + validation: { + required: false, + number: true + }, + docID: 'helpVspRetryInterval' + } + } + }, + action: function(args) { + if (nspMap["nuageVsp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NuageVsp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNuageVspProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + clearInterval(addNuageVspProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["nuageVsp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } else { + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } + }, + messages: { + notification: function(args) { + return 'label.add.NuageVsp.device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["nuageVsp"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["nuageVsp"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + }); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["nuageVsp"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + } + }, Opendaylight: { type: 'detailView', id: 'openDaylightProvider', @@ -11953,6 +12196,202 @@ } } }, + nuageVspDevices: { + id: 'nuageVspDevices', + title: 'label.devices', + listView: { + id: 'nuageVspDevices', + fields: { + hostname: { + label: 'label.host.name' + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version' + }, + retrycount: { + label: 'label.numretries', + }, + retryinterval: { + label: 'label.retry.interval' + } + }, + actions: { + add: { + label: 'label.add.NuageVsp.device', + createForm: { + title: 'label.add.NuageVsp.device', + preFilter: function(args) {}, + fields: { + hostname: { + label: 'label.host.name' + }, + username: { + label: 'label.username' + }, + password: { + label: 'label.password', + isPassword: true + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version', + defaultValue: 'v1_0' + }, + retrycount: { + label: 'label.numretries', + defaultValue: '4' + }, + retryinterval: { + label: 'label.retry.interval', + defaultValue: '60' + } + } + }, + action: function(args) { + if (nspMap["nuageVsp"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=NuageVsp&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNuageVspProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; + } else { + clearInterval(addNuageVspProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["nuageVsp"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=NuageVsp failed. Error: " + errorMsg); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } else { + addNuageVspDevice(args, selectedPhysicalNetworkObj, "addNuageVspDevice", "addnuagevspdeviceresponse", "nuagevspdevice") + } + }, + + messages: { + notification: function(args) { + return 'Added new Nuage Vsp Controller'; + } + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + dataProvider: function(args) { + $.ajax({ + url: createURL("listNuageVspDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + data: { + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listnuagevspdeviceresponse.nuagevspdevice; + args.response.success({ + data: items + }); + } + }); + }, + detailView: { + name: 'Nuage Vsp details', + actions: { + 'remove': { + label: 'label.delete.NuageVsp', + messages: { + confirm: function(args) { + return 'message.confirm.delete.NuageVsp'; + }, + notification: function(args) { + return 'label.delete.NuageVsp'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteNuageVspDevice&vspdeviceid=" + args.context.nuageVspDevices[0].vspdeviceid), + dataType: "json", + async: true, + success: function(json) { + var jid = json.deletenuagevspdeviceresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + } + }, + tabs: { + details: { + title: 'label.details', + fields: [{ + vspdeviceid: { + label: 'label.id' + }, + hostname: { + label: 'label.host.name' + }, + port: { + label: 'label.port' + }, + apiversion: { + label: 'label.api.version' + }, + retrycount: { + label: 'label.numretries', + }, + retryinterval: { + label: 'label.retry.interval' + } + }], + dataProvider: function(args) { + $.ajax({ + url: createURL("listNuageVspDevices&vspdeviceid=" + args.context.nuageVspDevices[0].vspdeviceid), + dataType: "json", + async: true, + success: function(json) { + var item = json.listnuagevspdeviceresponse.nuagevspdevice[0]; + args.response.success({ + data: item + }); + } + }); + } + } + } + } + } + }, pods: { title: 'label.pods', listView: { @@ -18817,8 +19256,39 @@ }); } - var afterCreateZonePhysicalNetworkTrafficTypes = function (args, newZoneObj, newPhysicalnetwork) { + function addNuageVspDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { + var array1 = []; + array1.push("&physicalnetworkid=" + physicalNetworkObj.id); + array1.push("&hostname=" + todb(args.data.hostname)); + array1.push("&username=" + todb(args.data.username)); + array1.push("&password=" + todb(args.data.password)); + array1.push("&port=" + todb(args.data.port)); + array1.push("&apiversion=" + todb(args.data.apiversion)); + array1.push("&retrycount=" + todb(args.data.retrycount)); + array1.push("&retryinterval=" + todb(args.data.retryinterval)); + $.ajax({ + url: createURL(apiCmd + array1.join("")), + dataType: "json", + type: "POST", + success: function(json) { + var jid = json[apiCmdRes].jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult[apiCmdObj]; + + return item; + } + } + }); + } + }); + } + + var afterCreateZonePhysicalNetworkTrafficTypes = function (args, newZoneObj, newPhysicalnetwork) { + $.ajax({ url: createURL("updatePhysicalNetwork&state=Enabled&id=" + newPhysicalnetwork.id), dataType: "json", success: function (json) { @@ -19495,6 +19965,9 @@ case "Opendaylight": nspMap[ "Opendaylight"] = items[i]; break; + case "NuageVsp": + nspMap["nuageVsp"] = items[i]; + break; } } } @@ -19560,6 +20033,12 @@ name: 'MidoNet', state: nspMap.midoNet ? nspMap.midoNet.state: 'Disabled' }); + + nspHardcodingArray.push({ + id: 'nuageVsp', + name: 'Nuage Vsp', + state: nspMap.nuageVsp ? nspMap.nuageVsp.state : 'Disabled' + }); nspHardcodingArray.push({ id: 'InternalLbVm', diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 4091c035a19..645c2b1b949 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -726,7 +726,10 @@ }).html('ODL'), $('