CLOUDSTACK-6697: bigswitch networking plugin update

1. provide compatibility with the Big Cloud Fabric (BCF) controller
   L2 Connectivity Service in both VPC and non-VPC modes
2. virtual network terminology updates: VNS --> BCF_SEGMENT
3. uses HTTPS with trust-always certificate handling
4. topology sync support with BCF controller
5. support multiple (two) BCF controllers with HA
6. support VM migration
7. support Firewall, Static NAT, and Source NAT with NAT enabled option
8. add VifDriver for Indigo Virtual Switch (IVS)

This closes #151

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
KC Wang 2014-09-26 14:09:30 -07:00 committed by Rohit Yadav
parent 72430247ed
commit 01864ef77c
96 changed files with 7189 additions and 2467 deletions

View File

@ -138,6 +138,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
public static final Provider BrocadeVcs = new Provider("BrocadeVcs", false);
// add GloboDns provider
public static final Provider GloboDns = new Provider("GloboDns", true);
// add Big Switch Bcf Provider
public static final Provider BigSwitchBcf = new Provider("BigSwitchBcf", false);
private final String name;
private final boolean isExternal;

View File

@ -33,7 +33,7 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
}
public enum IsolationMethod {
VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN, VSP, VCS;
VLAN, L3, GRE, STT, BCF_SEGMENT, MIDO, SSP, VXLAN, ODL, L3VPN, VSP, VCS;
}
public enum BroadcastDomainRange {

View File

@ -28,5 +28,7 @@ public interface StaticNat {
String getDestIpAddress();
String getSourceMacAddress();
boolean isForRevoke();
}

View File

@ -302,7 +302,7 @@ label.add.accounts.to=Add accounts to
label.add.accounts=Add accounts
label.add.ACL=Add ACL
label.add.affinity.group=Add new affinity group
label.add.BigSwitchVns.device=Add BigSwitch Vns Controller
label.add.BigSwitchBcf.device=Add BigSwitch BCF Controller
label.add.by.cidr=Add By CIDR
label.add.by.group=Add By Group
label.add.by=Add by
@ -415,7 +415,7 @@ label.back=Back
label.bandwidth=Bandwidth
label.basic.mode=Basic Mode
label.basic=Basic
label.bigswitch.controller.address=BigSwitch Vns Controller Address
label.bigswitch.controller.address=BigSwitch BCF Controller Address
label.bootable=Bootable
label.broadcast.domain.range=Broadcast domain range
label.broadcast.domain.type=Broadcast Domain Type
@ -509,7 +509,7 @@ label.default.use=Default Use
label.default.view=Default View
label.default=Default
label.delete.affinity.group=Delete Affinity Group
label.delete.BigSwitchVns=Remove BigSwitch Vns Controller
label.delete.BigSwitchBcf=Remove BigSwitch BCF Controller
label.delete.F5=Delete F5
label.delete.gateway=Delete gateway
label.delete.NetScaler=Delete NetScaler
@ -1450,8 +1450,9 @@ label.added.nicira.nvp.controller=Added new Nicira NVP Controller
label.nicira.nvp.details=Nicira NVP details
label.added.brocade.vcs.switch=Added new Brocade Vcs Switch
label.brocade.vcs.details=Brocade Vcs Switch details
label.added.new.bigswitch.vns.controller=Added new BigSwitch VNS Controller
label.bigswitch.vns.details=BigSwitch VNS details
label.added.new.bigswitch.bcf.controller=Added new BigSwitch BCF Controller
label.bigswitch.bcf.details=BigSwitch BCF details
label.bigswitch.bcf.nat=BigSwitch BCF NAT Enabled
label.dedicate=Dedicate
label.dedicate.pod=Dedicate Pod
label.pod.dedicated=Pod Dedicated
@ -1733,6 +1734,7 @@ message.configuring.public.traffic=Configuring public traffic
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.BigSwitchBcf=Please confirm that you would like to delete this BigSwitch BCF Controller
message.confirm.delete.BrocadeVcs=Please confirm that you would like to delete Brocade Vcs Switch
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

View File

@ -257,8 +257,8 @@ label.add.acl.list=Ajouter Liste ACL
label.add.affinity.group=Ajouter nouveau groupe d\\'affinit\u00e9
label.add=Ajouter
label.add.baremetal.dhcp.device=Ajouter un DHCP Baremetal
label.add.BigSwitchVns.device=Ajouter contr\u00f4leur BigSwitch Vns
label.add.BrocadeVcs.device=Ajouter Switch Brocade Vcs
label.add.BigSwitchBcf.device=Ajouter contr\u00f4leur BigSwitch BCF
label.add.by=Ajout\u00e9 par
label.add.by.cidr=Ajouter par CIDR
label.add.by.group=Ajouter par groupe
@ -269,7 +269,7 @@ label.add.direct.iprange=Ajouter une plage d\\'adresse IP directe
label.add.disk.offering=Ajouter Offre Disque
label.add.domain=Ajouter un domaine
label.added.brocade.vcs.switch=Ajout d\\'un nouveau switch Brocade Vcs
label.added.new.bigswitch.vns.controller=Ajout du nouveau contr\u00f4leur BigSwitch VNS
label.added.new.bigswitch.bcf.controller=Ajout du nouveau contr\u00f4leur BigSwitch BCF
label.added.nicira.nvp.controller=Ajout d\\'un nouveau contr\u00f4leur Nicira NVP
label.add.egress.rule=Ajouter la r\u00e8gle sortante
label.addes.new.f5=Ajout d\\'un nouveau F5
@ -403,8 +403,8 @@ label.baremetal.pxe.devices=\u00c9quipements PXE Baremetal
label.baremetal.pxe.provider=Fournisseur PXE Baremetal
label.basic=Basique
label.basic.mode=Mode basique
label.bigswitch.controller.address=Adresse du contr\u00f4leur BigSwitch Vns
label.bigswitch.vns.details=D\u00e9tails BigSwitch VNS
label.bigswitch.controller.address=Adresse du contr\u00f4leur BigSwitch BCF
label.bigswitch.bcf.details=D\u00e9tails BigSwitch BCF
label.blade.id=ID Lame
label.blades=Lames
label.bootable=Amor\u00e7able
@ -527,9 +527,9 @@ label.default.view=Vue par d\u00e9faut
label.delete.acl.list=Supprimer Liste ACL
label.delete.affinity.group=Supprimer le groupe d\\'affinit\u00e9
label.delete.alerts=Supprimer alertes
label.delete.BigSwitchVns=Supprimer contr\u00f4leur BigSwitch Vns
label.delete.BrocadeVcs=Supprimer Brocade Vcs Switch
label.delete.ciscoASA1000v=Supprimer CiscoASA1000v
label.delete.BigSwitchBcf=Supprimer contr\u00f4leur BigSwitch BCF
label.delete.ciscovnmc.resource=Supprimer ressource CiscoVNMC
label.delete.events=Supprimer \u00e9v\u00e9nements
label.delete.F5=Supprimer F5

View File

@ -300,7 +300,7 @@ label.add.accounts.to=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0\u5148\:
label.add.accounts=\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u8ffd\u52a0
label.add.ACL=ACL \u306e\u8ffd\u52a0
label.add.affinity.group=\u65b0\u3057\u3044\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u8ffd\u52a0
label.add.BigSwitchVns.device=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0
label.add.BigSwitchBcf.device=Big Switch BCF \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u8ffd\u52a0
label.add.by.cidr=CIDR \u3067\u8ffd\u52a0
label.add.by.group=\u30b0\u30eb\u30fc\u30d7\u3067\u8ffd\u52a0
label.add.by=\u8ffd\u52a0\u5358\u4f4d
@ -309,6 +309,7 @@ label.add.compute.offering=\u30b3\u30f3\u30d4\u30e5\u30fc\u30c6\u30a3\u30f3\u30b
label.add.direct.iprange=\u76f4\u63a5 IP \u30a2\u30c9\u30ec\u30b9\u306e\u7bc4\u56f2\u306e\u8ffd\u52a0
label.add.disk.offering=\u30c7\u30a3\u30b9\u30af \u30aa\u30d5\u30a1\u30ea\u30f3\u30b0\u306e\u8ffd\u52a0
label.add.domain=\u30c9\u30e1\u30a4\u30f3\u306e\u8ffd\u52a0
label.added.new.bigswitch.bcf.controller=\u65b0\u3057\u3044 Big Switch BCF \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f
label.add.egress.rule=\u9001\u4fe1\u898f\u5247\u306e\u8ffd\u52a0
label.add.F5.device=F5 \u30c7\u30d0\u30a4\u30b9\u306e\u8ffd\u52a0
label.add.firewall=\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u898f\u5247\u306e\u8ffd\u52a0
@ -410,7 +411,8 @@ label.back=\u623b\u308b
label.bandwidth=\u5e2f\u57df\u5e45
label.basic.mode=\u57fa\u672c\u30e2\u30fc\u30c9
label.basic=\u57fa\u672c
label.bigswitch.controller.address=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc \u30a2\u30c9\u30ec\u30b9
label.bigswitch.controller.address=Big Switch BCF \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u30a2\u30c9\u30ec\u30b9
label.bigswitch.bcf.details=Big Switch BCF \u306e\u8a73\u7d30
label.bootable=\u8d77\u52d5\u53ef\u80fd
label.broadcast.domain.range=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7bc4\u56f2
label.broadcast.domain.type=\u30d6\u30ed\u30fc\u30c9\u30ad\u30e3\u30b9\u30c8 \u30c9\u30e1\u30a4\u30f3\u306e\u7a2e\u985e
@ -503,7 +505,7 @@ label.default.use=\u30c7\u30d5\u30a9\u30eb\u30c8\u4f7f\u7528
label.default.view=\u30c7\u30d5\u30a9\u30eb\u30c8 \u30d3\u30e5\u30fc
label.default=\u30c7\u30d5\u30a9\u30eb\u30c8
label.delete.affinity.group=\u30a2\u30d5\u30a3\u30cb\u30c6\u30a3 \u30b0\u30eb\u30fc\u30d7\u306e\u524a\u9664
label.delete.BigSwitchVns=Big Switch VNS \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664
label.delete.BigSwitchBcf=Big Switch BCF \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u306e\u524a\u9664
label.delete.F5=F5 \u306e\u524a\u9664
label.delete.gateway=\u30b2\u30fc\u30c8\u30a6\u30a7\u30a4\u306e\u524a\u9664
label.delete.NetScaler=NetScaler \u306e\u524a\u9664

View File

@ -241,7 +241,7 @@ label.add.accounts=\uacc4\uc815 \uc815\ubcf4 \ucd94\uac00
label.add.account.to.project=\uacc4\uc815 \uc815\ubcf4 \ud504\ub85c\uc81d\ud2b8\uc5d0 \ucd94\uac00
label.add.account=\uacc4\uc815 \uc815\ubcf4 \ucd94\uac00
label.add.ACL=\uad8c\ud55c \uad00\ub9ac(ACL) \ucd94\uac00
label.add.BigSwitchVns.device=BigSwitch Vns \ucf58\ud2b8\ub864\ub7ec
label.add.BigSwitchBcf.device=BigSwitch BCF \ucf58\ud2b8\ub864\ub7ec
label.add.by.cidr=CIDR \ub85c \ucd94\uac00
label.add.by.group=\uadf8\ub8f9\uc5d0\uc11c \ucd94\uac00
label.add.by=\ucd94\uac00 \ub2e8\uc704

View File

@ -252,7 +252,7 @@ label.add.account=Voeg Account toe
label.add.ACL=Voeg ACL toe
label.add.affinity.group=Nieuwe affinity groep toevoegen
label.add.baremetal.dhcp.device=Voeg Baremetal DHCP Apparaat toe
label.add.BigSwitchVns.device=Voeg BigSwitch Vns Controller toe
label.add.BigSwitchBcf.device=Voeg BigSwitch BCF Controller toe
label.add.by.cidr=Voeg toe door middel van CIDR
label.add.by.group=Voeg toe door middel van Groep
label.add.by=Voeg toe door middel van
@ -261,7 +261,7 @@ label.add.compute.offering=Voeg Compute aanbieding toe
label.add.direct.iprange=Voeg Direct IP Range toe
label.add.disk.offering=Voeg Schijf Aanbieding toe
label.add.domain=Voeg Domein toe
label.added.new.bigswitch.vns.controller=Nieuwe BigSwitch VNS Controller toegevoegd
label.added.new.bigswitch.bcf.controller=Nieuwe BigSwitch BCF Controller toegevoegd
label.added.nicira.nvp.controller=Nieuwe Nicira NVP Controller toegevoegd
label.add.egress.rule=Voeg uitgaande regel toe
label.addes.new.f5=Nieuwe F5 toegevoegd
@ -384,8 +384,8 @@ label.baremetal.pxe.device=Voeg Baremetal PXE Apparaat toe
label.baremetal.pxe.provider=Baremetal PXE Provider
label.basic=Basis
label.basic.mode=Basis Modus
label.bigswitch.controller.address=BigSwitch Vns Controller Adres
label.bigswitch.vns.details=BigSwitch VNS details
label.bigswitch.controller.address=BigSwitch BCF Controller Adres
label.bigswitch.bcf.details=BigSwitch BCF details
label.blade.id=Blade ID
label.blades=Blades
label.bootable=Bootable
@ -502,7 +502,7 @@ label.default.use=Standaard Gebruik
label.default.view=Standaard Weergave
label.delete.affinity.group=Verwijder Affinity Groep
label.delete.alerts=Verwijder waarschuwingen
label.delete.BigSwitchVns=Verwijder BigSwitch Vns Controller
label.delete.BigSwitchBcf=Verwijder BigSwitch Bcf Controller
label.delete.ciscovnmc.resource=CiscoVNMC resource verwijderen
label.delete.events=Verwijder gebeurtenissen
label.delete.F5=Verwijder F5

View File

@ -249,7 +249,7 @@ label.add.account.to.project=Adicionar conta ao projeto
label.add.ACL=Adicionar ACL
label.add=Adicionar
label.add.affinity.group=Adicionar um grupo de afinidade
label.add.BigSwitchVns.device=Adicionar BigSwitch Vns Controller
label.add.BigSwitchBcf.device=Adicionar BigSwitch BCF Controller
label.add.by=Adicionado por
label.add.by.cidr=Adicionar por CIDR
label.add.by.group=Adicionar por Grupo
@ -360,7 +360,7 @@ label.back=Voltar
label.bandwidth=Bandwidth
label.basic=B\u00e1sico
label.basic.mode=Modo B\u00e1sico
label.bigswitch.controller.address=Endere\u00e7o do Controlador BigSwitch Vns
label.bigswitch.controller.address=Endere\u00e7o do Controlador BigSwitch BCF
label.bootable=Inicializ\u00e1vel
label.broadcast.domain.range=Range do dom\u00ednio de Broadcast
label.broadcast.domain.type=Tipo de Dom\u00ednio Broadcast
@ -456,7 +456,7 @@ label.default.use=Uso padr\u00e3o
label.default.view=Vis\u00e3o Padr\u00e3o
label.delete.affinity.group=Deletar Grupo de Afinidade
label.delete.alerts=Remover alertas
label.delete.BigSwitchVns=Remover Controlador BigSwitch Vns
label.delete.BigSwitchBcf=Remover Controlador BigSwitch BCF
label.delete.events=Remover eventos
label.delete.F5=Remover F5
label.delete.gateway=delete gateway

View File

@ -245,7 +245,7 @@ label.add.account.to.project=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u
label.add.account=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u043a\u043a\u0430\u0443\u043d\u0442
label.add.ACL=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c ACL
label.add.affinity.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e affinity group
label.add.BigSwitchVns.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c BigSwitch Vns Controller
label.add.BigSwitchBcf.device=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c BigSwitch BCF Controller
label.add.by.cidr=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a CIDR
label.add.by.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0433\u0440\u0443\u043f\u043f\u0435
label.add.by=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
@ -442,7 +442,7 @@ label.default.use=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\
label.default.view=\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u0432\u0438\u0434
label.delete.affinity.group=\u0423\u0434\u0430\u043b\u0438\u0442\u044c affinity group
label.delete.alerts=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438
label.delete.BigSwitchVns=\u0423\u0434\u0430\u043b\u0438\u0442\u044c BigSwitch VNC \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440
label.delete.BigSwitchBcf=\u0423\u0434\u0430\u043b\u0438\u0442\u044c BigSwitch BCF \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440
label.delete.events=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f
label.delete.F5=\u0423\u0434\u0430\u043b\u0438\u0442\u044c F5
label.delete.gateway=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0448\u043b\u044e\u0437

View File

@ -300,7 +300,7 @@ label.add.accounts.to=\u6dfb\u52a0\u5e10\u6237\u81f3
label.add.accounts=\u6dfb\u52a0\u5e10\u6237
label.add.ACL=\u6dfb\u52a0 ACL
label.add.affinity.group=\u6dfb\u52a0\u65b0\u5173\u8054\u6027\u7ec4
label.add.BigSwitchVns.device=\u6dfb\u52a0 BigSwitch Vns \u63a7\u5236\u5668
label.add.BigSwitchBcf.device=\u6dfb\u52a0 BigSwitch BCF \u63a7\u5236\u5668
label.add.by.cidr=\u6309 CIDR \u6dfb\u52a0
label.add.by.group=\u6309\u7ec4\u6dfb\u52a0
label.add.by=\u6dfb\u52a0\u65b9\u5f0f
@ -309,6 +309,7 @@ label.add.compute.offering=\u6dfb\u52a0\u8ba1\u7b97\u65b9\u6848
label.add.direct.iprange=\u6dfb\u52a0\u76f4\u63a5 IP \u8303\u56f4
label.add.disk.offering=\u6dfb\u52a0\u78c1\u76d8\u65b9\u6848
label.add.domain=\u6dfb\u52a0\u57df
label.added.new.bigswitch.bcf.controller=\u5df2\u6dfb\u52a0\u65b0 BigSwitch BCF \u63a7\u5236\u5668
label.add.egress.rule=\u6dfb\u52a0\u51fa\u53e3\u89c4\u5219
label.add.F5.device=\u6dfb\u52a0 F5 \u8bbe\u5907
label.add.firewall=\u6dfb\u52a0\u9632\u706b\u5899\u89c4\u5219
@ -410,7 +411,8 @@ label.back=\u540e\u9000
label.bandwidth=\u5e26\u5bbd
label.basic.mode=\u57fa\u672c\u6a21\u5f0f
label.basic=\u57fa\u672c
label.bigswitch.controller.address=BigSwitch Vns \u63a7\u5236\u5668\u5730\u5740
label.bigswitch.controller.address=BigSwitch BCF \u63a7\u5236\u5668\u5730\u5740
label.bigswitch.bcf.details=BigSwitch BCF \u8be6\u7ec6\u4fe1\u606f
label.bootable=\u53ef\u542f\u52a8
label.broadcast.domain.range=\u5e7f\u64ad\u57df\u8303\u56f4
label.broadcast.domain.type=\u5e7f\u64ad\u57df\u7c7b\u578b
@ -503,7 +505,7 @@ label.default.use=\u9ed8\u8ba4\u4f7f\u7528
label.default.view=\u9ed8\u8ba4\u89c6\u56fe
label.default=\u9ed8\u8ba4\u8bbe\u7f6e
label.delete.affinity.group=\u5220\u9664\u5173\u8054\u6027\u7ec4
label.delete.BigSwitchVns=\u79fb\u9664 BigSwitch Vns \u63a7\u5236\u5668
label.delete.BigSwitchBcf=\u79fb\u9664 BigSwitch BCF \u63a7\u5236\u5668
label.delete.F5=\u5220\u9664 F5
label.delete.gateway=\u5220\u9664\u7f51\u5173
label.delete.NetScaler=\u5220\u9664 NetScaler

View File

@ -127,7 +127,7 @@
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-vns</artifactId>
<artifactId>cloud-plugin-network-bigswitch</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>

View File

@ -626,11 +626,11 @@ deleteBrocadeVcsDevice=1
listBrocadeVcsDevices=1
listBrocadeVcsDeviceNetworks=1
#### bigswitch vns commands
#### bigswitch bcf commands
addBigSwitchVnsDevice=1
deleteBigSwitchVnsDevice=1
listBigSwitchVnsDevices=1
addBigSwitchBcfDevice=1
deleteBigSwitchBcfDevice=1
listBigSwitchBcfDevices=1
#### stratosphere ssp commands

View File

@ -40,8 +40,8 @@ import com.cloud.utils.db.TransactionLegacy;
public class VmDiskStatisticsDaoImpl extends GenericDaoBase<VmDiskStatisticsVO, Long> implements VmDiskStatisticsDao {
private static final Logger s_logger = Logger.getLogger(VmDiskStatisticsDaoImpl.class);
private static final String ACTIVE_AND_RECENTLY_DELETED_SEARCH =
"SELECT vns.id, vns.data_center_id, vns.account_id, vns.vm_id, vns.volume_id, vns.agg_io_read, vns.agg_io_write, vns.agg_bytes_read, vns.agg_bytes_write "
+ "FROM vm_disk_statistics vns, account a " + "WHERE vns.account_id = a.id AND (a.removed IS NULL OR a.removed >= ?) " + "ORDER BY vns.id";
"SELECT bcf.id, bcf.data_center_id, bcf.account_id, bcf.vm_id, bcf.volume_id, bcf.agg_io_read, bcf.agg_io_write, bcf.agg_bytes_read, bcf.agg_bytes_write "
+ "FROM vm_disk_statistics bcf, account a " + "WHERE bcf.account_id = a.id AND (a.removed IS NULL OR a.removed >= ?) " + "ORDER BY bcf.id";
private static final String UPDATED_VM_NETWORK_STATS_SEARCH = "SELECT id, current_io_read, current_io_write, net_io_read, net_io_write, agg_io_read, agg_io_write, "
+ "current_bytes_read, current_bytes_write, net_bytes_read, net_bytes_write, agg_bytes_read, agg_bytes_write " + "from vm_disk_statistics "
+ "where (agg_io_read < net_io_read + current_io_read) OR (agg_io_write < net_io_write + current_io_write) OR "

View File

@ -1 +1,2 @@
/target
/target

View File

@ -0,0 +1,286 @@
/*
* 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.hypervisor.kvm.resource;
import java.io.File;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.libvirt.LibvirtException;
import com.cloud.agent.api.to.NicTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef;
import com.cloud.network.Networks;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script;
public class IvsVifDriver extends VifDriverBase {
private static final Logger s_logger = Logger.getLogger(IvsVifDriver.class);
private int _timeout;
private final Object _vnetBridgeMonitor = new Object();
private String _modifyVlanPath;
private String _modifyVxlanPath;
private String _ivsIfUpPath;
private Long libvirtVersion;
@Override
public void configure(Map<String, Object> params) throws ConfigurationException {
super.configure(params);
String networkScriptsDir = (String)params.get("network.scripts.dir");
if (networkScriptsDir == null) {
networkScriptsDir = "scripts/vm/network/vnet";
}
String utilScriptsDir = "scripts/util/";
String value = (String)params.get("scripts.timeout");
_timeout = NumbersUtil.parseInt(value, 30 * 60) * 1000;
_modifyVlanPath = Script.findScript(networkScriptsDir, "modifyvlan.sh");
if (_modifyVlanPath == null) {
throw new ConfigurationException("Unable to find modifyvlan.sh");
}
_modifyVxlanPath = Script.findScript(networkScriptsDir, "modifyvxlan.sh");
if (_modifyVxlanPath == null) {
throw new ConfigurationException("Unable to find modifyvxlan.sh");
}
_ivsIfUpPath = Script.findScript(utilScriptsDir, "qemu-ivs-ifup");
libvirtVersion = (Long) params.get("libvirtVersion");
if (libvirtVersion == null) {
libvirtVersion = 0L;
}
createControlNetwork(_bridges.get("linklocal"));
}
@Override
public InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter) throws InternalErrorException, LibvirtException {
LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
String vNetId = null;
String protocol = null;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
}
String vlanId = null;
String logicalSwitchUuid = null;
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) {
vlanId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
logicalSwitchUuid = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) {
// TODO consider moving some of this functionality from NetUtils to Networks....
vlanId = NetUtils.getPrimaryPvlanFromUri(nic.getBroadcastUri());
}
String trafficLabel = nic.getName();
Integer networkRateKBps = (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) ? nic.getNetworkRateMbps().intValue() * 128 : 0;
if (nic.getType() == Networks.TrafficType.Guest) {
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Pvlan) &&
!vlanId.equalsIgnoreCase("untagged")) {
if (trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vlan dev and bridge for guest traffic per traffic label " + trafficLabel);
intf.defEthernet("ivsnet-" + nic.getUuid().substring(0, 5), nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), _ivsIfUpPath, networkRateKBps);
} else {
throw new InternalErrorException("no traffic label ");
}
}
} else if (nic.getType() == Networks.TrafficType.Control) {
/* Make sure the network is still there */
createControlNetwork();
intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
} else if (nic.getType() == Networks.TrafficType.Public) {
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) ||
(nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) {
if (trafficLabel != null && !trafficLabel.isEmpty()) {
s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
String brName = createVnetBr(vNetId, trafficLabel, protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
} else {
String brName = createVnetBr(vNetId, "public", protocol);
intf.defBridgeNet(brName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
}
} else {
intf.defBridgeNet(_bridges.get("public"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter), networkRateKBps);
}
} else if (nic.getType() == Networks.TrafficType.Management) {
intf.defBridgeNet(_bridges.get("private"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
} else if (nic.getType() == Networks.TrafficType.Storage) {
String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
}
if (nic.getPxeDisable() == true) {
intf.setPxeDisable(true);
}
return intf;
}
@Override
public void unplug(InterfaceDef iface) {
}
private void createControlNetwork() throws LibvirtException {
createControlNetwork(_bridges.get("linklocal"));
}
private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
String nic = _pifs.get(pifKey);
if (nic == null) {
// if not found in bridge map, maybe traffic label refers to pif already?
File pif = new File("/sys/class/net/" + pifKey);
if (pif.isDirectory()) {
nic = pifKey;
}
}
String brName = "";
brName = setVnetBrName(nic, vNetId);
createVnet(vNetId, nic, brName, protocol);
return brName;
}
private String setVnetBrName(String pifName, String vnetId) {
return "br" + pifName + "-" + vnetId;
}
private void createVnet(String vnetId, String pif, String brName, String protocol) throws InternalErrorException {
synchronized (_vnetBridgeMonitor) {
String script = _modifyVlanPath;
if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
script = _modifyVxlanPath;
}
final Script command = new Script(script, _timeout, s_logger);
command.add("-v", vnetId);
command.add("-p", pif);
command.add("-b", brName);
command.add("-o", "add");
final String result = command.execute();
if (result != null) {
throw new InternalErrorException("Failed to create vnet " + vnetId + ": " + result);
}
}
}
private void deleteVnetBr(String brName) {
synchronized (_vnetBridgeMonitor) {
String cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName);
if (cmdout == null)
// Bridge does not exist
return;
cmdout = Script.runSimpleBashScript("ls /sys/class/net/" + brName + "/brif | tr '\n' ' '");
if (cmdout != null && cmdout.contains("vnet")) {
// Active VM remains on that bridge
return;
}
Pattern oldStyleBrNameRegex = Pattern.compile("^cloudVirBr(\\d+)$");
Pattern brNameRegex = Pattern.compile("^br(\\S+)-(\\d+)$");
Matcher oldStyleBrNameMatcher = oldStyleBrNameRegex.matcher(brName);
Matcher brNameMatcher = brNameRegex.matcher(brName);
String pName = null;
String vNetId = null;
if (oldStyleBrNameMatcher.find()) {
// Actually modifyvlan.sh doesn't require pif name when deleting its bridge so far.
pName = "undefined";
vNetId = oldStyleBrNameMatcher.group(1);
} else if (brNameMatcher.find()) {
if (brNameMatcher.group(1) != null || !brNameMatcher.group(1).isEmpty()) {
pName = brNameMatcher.group(1);
} else {
pName = "undefined";
}
vNetId = brNameMatcher.group(2);
}
if (vNetId == null || vNetId.isEmpty()) {
s_logger.debug("unable to get a vNet ID from name " + brName);
return;
}
String scriptPath = null;
if (cmdout != null && cmdout.contains("vxlan")) {
scriptPath = _modifyVxlanPath;
} else {
scriptPath = _modifyVlanPath;
}
final Script command = new Script(scriptPath, _timeout, s_logger);
command.add("-o", "delete");
command.add("-v", vNetId);
command.add("-p", pName);
command.add("-b", brName);
final String result = command.execute();
if (result != null) {
s_logger.debug("Delete bridge " + brName + " failed: " + result);
}
}
}
private void deleteExitingLinkLocalRouteTable(String linkLocalBr) {
Script command = new Script("/bin/bash", _timeout);
command.add("-c");
command.add("ip route | grep " + NetUtils.getLinkLocalCIDR());
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser);
boolean foundLinkLocalBr = false;
if (result == null && parser.getLines() != null) {
String[] lines = parser.getLines().split("\\n");
for (String line : lines) {
String[] tokens = line.split(" ");
if (!tokens[2].equalsIgnoreCase(linkLocalBr)) {
Script.runSimpleBashScript("ip route del " + NetUtils.getLinkLocalCIDR());
} else {
foundLinkLocalBr = true;
}
}
}
if (!foundLinkLocalBr) {
Script.runSimpleBashScript("ifconfig " + linkLocalBr + " 169.254.0.1;" + "ip route add " + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr + " src " +
NetUtils.getLinkLocalGateway());
}
}
private void createControlNetwork(String privBrName) {
deleteExitingLinkLocalRouteTable(privBrName);
if (!isBridgeExists(privBrName)) {
Script.runSimpleBashScript("brctl addbr " + privBrName + "; ifconfig " + privBrName + " up; ifconfig " + privBrName + " 169.254.0.1", _timeout);
}
}
private boolean isBridgeExists(String bridgeName) {
File f = new File("/sys/devices/virtual/net/" + bridgeName);
if (f.exists()) {
return true;
} else {
return false;
}
}
}

View File

@ -1,29 +0,0 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-network-vns</artifactId>
<name>Apache CloudStack Plugin - BigSwitch Virtual Network Segment</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.6.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
</project>

View File

@ -1,36 +0,0 @@
<!--
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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<bean id="bigSwitchVnsDaoImpl" class="com.cloud.network.dao.BigSwitchVnsDaoImpl" />
<bean id="bigSwitchVnsElement" class="com.cloud.network.element.BigSwitchVnsElement">
<property name="name" value="BigSwitchVnsElement" />
</bean>
</beans>

View File

@ -1,28 +0,0 @@
// 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 CreateVnsNetworkAnswer extends Answer {
public CreateVnsNetworkAnswer(Command command, boolean success, String details) {
super(command, success, details);
}
public CreateVnsNetworkAnswer(Command command, Exception e) {
super(command, e);
}
}

View File

@ -1,315 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.bigswitch;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.log4j.Logger;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class BigSwitchVnsApi {
private static final Logger s_logger = Logger.getLogger(BigSwitchVnsApi.class);
private final static String s_protocol = "http";
private final static String s_nsBaseUri = "/networkService/v1.1";
private final static String CONTENT_TYPE = "Content-Type";
private final static String ACCEPT = "Accept";
private final static String CONTENT_JSON = "application/json";
private final static String HTTP_HEADER_INSTANCE_ID = "INSTANCE_ID";
private final static String CLOUDSTACK_INSTANCE_ID = "org.apache.cloudstack";
private final static MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
private String _host;
private HttpClient _client;
/* This factory method is protected so we can extend this
* in the unittests.
*/
protected HttpClient createHttpClient() {
return new HttpClient(s_httpClientManager);
}
protected HttpMethod createMethod(String type, String uri, int port) throws BigSwitchVnsApiException {
String url;
try {
url = new URL(s_protocol, _host, port, uri).toString();
} catch (MalformedURLException e) {
s_logger.error("Unable to build BigSwitch API URL", e);
throw new BigSwitchVnsApiException("Unable to build v API URL", e);
}
if ("post".equalsIgnoreCase(type)) {
return new PostMethod(url);
} else if ("get".equalsIgnoreCase(type)) {
return new GetMethod(url);
} else if ("delete".equalsIgnoreCase(type)) {
return new DeleteMethod(url);
} else if ("put".equalsIgnoreCase(type)) {
return new PutMethod(url);
} else {
throw new BigSwitchVnsApiException("Requesting unknown method type");
}
}
public BigSwitchVnsApi() {
_client = createHttpClient();
_client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
}
public void setControllerAddress(String address) {
this._host = address;
}
/**
* Logs into the BigSwitch API. The cookie is stored in the <code>_authcookie<code> variable.
* <p>
* The method returns false if the login failed or the connection could not be made.
*
*/
protected void login() throws BigSwitchVnsApiException {
return;
}
public void createNetwork(NetworkData network) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + network.getNetwork().getTenantId() + "/networks";
executeCreateObject(network, new TypeToken<NetworkData>() {
}.getType(), uri, Collections.<String, String> emptyMap());
}
public void deleteNetwork(String tenantId, String networkId) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId;
executeDeleteObject(uri);
}
public void createPort(String networkUuid, PortData port) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + port.getPort().getTenantId() + "/networks/" + networkUuid + "/ports";
executeCreateObject(port, new TypeToken<PortData>() {
}.getType(), uri, Collections.<String, String> emptyMap());
}
public void modifyPort(String networkId, PortData port) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + port.getPort().getTenantId() + "/networks/" + networkId + "/ports";
executeUpdateObject(port, uri, Collections.<String, String> emptyMap());
}
public void deletePort(String tenantId, String networkId, String portId) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + portId;
executeDeleteObject(uri);
}
public void modifyPortAttachment(String tenantId, String networkId, String portId, AttachmentData attachment) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + portId + "/attachment";
executeUpdateObject(attachment, uri, Collections.<String, String> emptyMap());
}
public void deletePortAttachment(String tenantId, String networkId, String portId) throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + portId + "/attachment";
executeDeleteObject(uri);
}
public ControlClusterStatus getControlClusterStatus() throws BigSwitchVnsApiException {
String uri = s_nsBaseUri + "/health";
ControlClusterStatus ccs = executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), uri, 80, null);
ccs.setStatus(true);
return ccs;
}
protected <T> void executeUpdateObject(T newObject, String uri, Map<String, String> parameters) throws BigSwitchVnsApiException {
if (_host == null || _host.isEmpty()) {
throw new BigSwitchVnsApiException("Hostname is null or empty");
}
Gson gson = new Gson();
PutMethod pm = (PutMethod)createMethod("put", uri, 80);
pm.setRequestHeader(CONTENT_TYPE, CONTENT_JSON);
pm.setRequestHeader(ACCEPT, CONTENT_JSON);
pm.setRequestHeader(HTTP_HEADER_INSTANCE_ID, CLOUDSTACK_INSTANCE_ID);
try {
pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), CONTENT_JSON, null));
} catch (UnsupportedEncodingException e) {
throw new BigSwitchVnsApiException("Failed to encode json request body", e);
}
executeMethod(pm);
if (pm.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(pm);
pm.releaseConnection();
s_logger.error("Failed to update object : " + errorMessage);
throw new BigSwitchVnsApiException("Failed to update object : " + errorMessage);
}
pm.releaseConnection();
}
protected <T> void executeCreateObject(T newObject, Type returnObjectType, String uri, Map<String, String> parameters) throws BigSwitchVnsApiException {
if (_host == null || _host.isEmpty()) {
throw new BigSwitchVnsApiException("Hostname is null or empty");
}
Gson gson = new Gson();
PostMethod pm = (PostMethod)createMethod("post", uri, 80);
pm.setRequestHeader(CONTENT_TYPE, CONTENT_JSON);
pm.setRequestHeader(ACCEPT, CONTENT_JSON);
pm.setRequestHeader(HTTP_HEADER_INSTANCE_ID, CLOUDSTACK_INSTANCE_ID);
try {
pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), CONTENT_JSON, null));
} catch (UnsupportedEncodingException e) {
throw new BigSwitchVnsApiException("Failed to encode json request body", e);
}
executeMethod(pm);
if (pm.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(pm);
pm.releaseConnection();
s_logger.error("Failed to create object : " + errorMessage);
throw new BigSwitchVnsApiException("Failed to create object : " + errorMessage);
}
pm.releaseConnection();
return;
}
protected void executeDeleteObject(String uri) throws BigSwitchVnsApiException {
if (_host == null || _host.isEmpty()) {
throw new BigSwitchVnsApiException("Hostname is null or empty");
}
DeleteMethod dm = (DeleteMethod)createMethod("delete", uri, 80);
dm.setRequestHeader(CONTENT_TYPE, CONTENT_JSON);
dm.setRequestHeader(ACCEPT, CONTENT_JSON);
dm.setRequestHeader(HTTP_HEADER_INSTANCE_ID, CLOUDSTACK_INSTANCE_ID);
executeMethod(dm);
if (dm.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(dm);
dm.releaseConnection();
s_logger.error("Failed to delete object : " + errorMessage);
throw new BigSwitchVnsApiException("Failed to delete object : " + errorMessage);
}
dm.releaseConnection();
}
@SuppressWarnings("unchecked")
protected <T> T executeRetrieveObject(Type returnObjectType, String uri, int port, Map<String, String> parameters) throws BigSwitchVnsApiException {
if (_host == null || _host.isEmpty()) {
throw new BigSwitchVnsApiException("Hostname is null or empty");
}
GetMethod gm = (GetMethod)createMethod("get", uri, port);
gm.setRequestHeader(CONTENT_TYPE, CONTENT_JSON);
gm.setRequestHeader(ACCEPT, CONTENT_JSON);
gm.setRequestHeader(HTTP_HEADER_INSTANCE_ID, CLOUDSTACK_INSTANCE_ID);
if (parameters != null && !parameters.isEmpty()) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(parameters.size());
for (Entry<String, String> e : parameters.entrySet()) {
nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue()));
}
gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0]));
}
executeMethod(gm);
if (gm.getStatusCode() != HttpStatus.SC_OK) {
String errorMessage = responseToErrorMessage(gm);
gm.releaseConnection();
s_logger.error("Failed to retrieve object : " + errorMessage);
throw new BigSwitchVnsApiException("Failed to retrieve object : " + errorMessage);
}
Gson gson = new Gson();
T returnValue;
try {
returnValue = (T)gson.fromJson(gm.getResponseBodyAsString(), returnObjectType);
} catch (IOException e) {
s_logger.error("IOException while retrieving response body", e);
throw new BigSwitchVnsApiException(e);
} finally {
gm.releaseConnection();
}
return returnValue;
}
protected void executeMethod(HttpMethodBase method) throws BigSwitchVnsApiException {
try {
_client.executeMethod(method);
if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
method.releaseConnection();
// login and try again
login();
_client.executeMethod(method);
}
} catch (HttpException e) {
s_logger.error("HttpException caught while trying to connect to the BigSwitch Controller", e);
method.releaseConnection();
throw new BigSwitchVnsApiException("API call to BigSwitch Controller Failed", e);
} catch (IOException e) {
s_logger.error("IOException caught while trying to connect to the BigSwitch Controller", e);
method.releaseConnection();
throw new BigSwitchVnsApiException("API call to BigSwitch Controller Failed", e);
}
}
private String responseToErrorMessage(HttpMethodBase method) {
assert method.isRequestSent() : "no use getting an error message unless the request is sent";
if ("text/html".equals(method.getResponseHeader(CONTENT_TYPE).getValue())) {
// The error message is the response content
// Safety margin of 1024 characters, anything longer is probably useless
// and will clutter the logs
try {
return method.getResponseBodyAsString(1024);
} catch (IOException e) {
s_logger.debug("Error while loading response body", e);
}
}
// The default
return method.getStatusText();
}
}

View File

@ -1,86 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.bigswitch;
public class NetworkData {
private final Network network;
public Network getNetwork() {
return network;
}
public NetworkData() {
network = new Network();
}
public class Network {
private String id;
private String name;
private String tenantId;
private int vlan;
private String gateway;
private String state;
public String getUuid() {
return id;
}
public void setUuid(String id) {
this.id = id;
}
public String getDisplayName() {
return name;
}
public void setDisplay_name(String displayName) {
name = displayName;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public int getVlan() {
return vlan;
}
public void setVlan(int vlan) {
this.vlan = vlan;
}
public String getGateway() {
return gateway;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
}

View File

@ -1,68 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.bigswitch;
public class PortData {
private Port port;
public Port getPort() {
return this.port;
}
public PortData() {
this.port = new Port();
}
public class Port {
private String id;
private String name;
private String tenantId;
private String state;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
}

View File

@ -1,472 +0,0 @@
// 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 java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.CreateVnsPortAnswer;
import com.cloud.agent.api.CreateVnsPortCommand;
import com.cloud.agent.api.DeleteVnsPortAnswer;
import com.cloud.agent.api.DeleteVnsPortCommand;
import com.cloud.agent.api.StartupBigSwitchVnsCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.AddBigSwitchVnsDeviceCmd;
import com.cloud.api.commands.DeleteBigSwitchVnsDeviceCmd;
import com.cloud.api.commands.ListBigSwitchVnsDevicesCmd;
import com.cloud.api.commands.VnsConstants;
import com.cloud.api.response.BigSwitchVnsDeviceResponse;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.network.BigSwitchVnsDeviceVO;
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.Networks.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.dao.BigSwitchVnsDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
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.BigSwitchVnsResource;
import com.cloud.offering.NetworkOffering;
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.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
@Component
@Local(value = {NetworkElement.class, ConnectivityProvider.class})
public class BigSwitchVnsElement extends AdapterBase implements BigSwitchVnsElementService, ConnectivityProvider, ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(BigSwitchVnsElement.class);
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@Inject
ResourceManager _resourceMgr;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@Inject
BigSwitchVnsDao _bigswitchVnsDao;
@Inject
HostDetailsDao _hostDetailsDao;
@Inject
HostDao _hostDao;
@Inject
AgentManager _agentMgr;
@Inject
NetworkDao _networkDao;
@Inject
NetworkModel _networkModel;
@Inject
ConfigurationManager _configMgr;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@Inject
VlanDao _vlanDao;
@Override
public Map<Service, Map<Capability, String>> getCapabilities() {
return capabilities;
}
@Override
public Provider getProvider() {
return VnsConstants.BigSwitchVns;
}
private boolean canHandle(Network network, Service service) {
s_logger.debug("Checking if BigSwitchVnsElement can handle service " + service.getName() + " on network " + network.getDisplayText());
if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) {
return false;
}
if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
s_logger.debug("BigSwitchVnsElement is not a provider for network " + network.getDisplayText());
return false;
}
if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, VnsConstants.BigSwitchVns)) {
s_logger.debug("BigSwitchVnsElement can't provide the " + service.getName() + " service on network " + network.getDisplayText());
return false;
}
return true;
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
_resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
return true;
}
@Override
public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException {
s_logger.debug("entering BigSwitchVnsElement implement function for network " + network.getDisplayText() + " (state " + network.getState() + ")");
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 LSwitch Uuid");
return false;
}
String mac = nic.getMacAddress();
String tenantId = context.getDomain().getName();
List<BigSwitchVnsDeviceVO> devices = _bigswitchVnsDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
if (devices.isEmpty()) {
s_logger.error("No BigSwitch Controller on physical network " + network.getPhysicalNetworkId());
return false;
}
BigSwitchVnsDeviceVO bigswitchVnsDevice = devices.get(0);
HostVO bigswitchVnsHost = _hostDao.findById(bigswitchVnsDevice.getHostId());
CreateVnsPortCommand cmd = new CreateVnsPortCommand(BroadcastDomainType.getValue(network.getBroadcastUri()), vm.getUuid(), tenantId, nic.getName(), mac);
CreateVnsPortAnswer answer = (CreateVnsPortAnswer)_agentMgr.easySend(bigswitchVnsHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("CreatePortCommand failed");
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 LSwitch Uuid");
return false;
}
String tenantId = context.getDomain().getName();
List<BigSwitchVnsDeviceVO> devices = _bigswitchVnsDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
if (devices.isEmpty()) {
s_logger.error("No BigSwitch Controller on physical network " + network.getPhysicalNetworkId());
return false;
}
BigSwitchVnsDeviceVO bigswitchVnsDevice = devices.get(0);
HostVO bigswitchVnsHost = _hostDao.findById(bigswitchVnsDevice.getHostId());
DeleteVnsPortCommand cmd = new DeleteVnsPortCommand(BroadcastDomainType.getValue(network.getBroadcastUri()), vm.getUuid(), tenantId);
DeleteVnsPortAnswer answer = (DeleteVnsPortAnswer)_agentMgr.easySend(bigswitchVnsHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("DeletePortCommand failed");
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 destroy(Network network, ReservationContext context) 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 {
// Nothing to do here.
return true;
}
@Override
public boolean canEnableIndividualServices() {
return true;
}
@Override
public boolean verifyServicesCombination(Set<Service> services) {
if (!services.contains(Service.Connectivity)) {
s_logger.warn("Unable to provide services without Connectivity service enabled for this element");
return false;
}
return true;
}
private static Map<Service, Map<Capability, String>> setCapabilities() {
Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
// L2 Support : SDN provisioning
capabilities.put(Service.Connectivity, null);
return capabilities;
}
@Override
@DB
public BigSwitchVnsDeviceVO addBigSwitchVnsDevice(AddBigSwitchVnsDeviceCmd cmd) {
ServerResource resource = new BigSwitchVnsResource();
final String deviceName = VnsConstants.BigSwitchVns.getName();
NetworkDevice networkDevice = 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 enabled in the physical network: " +
physicalNetworkId + "to add this device");
} else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + " is in shutdown state in the physical network: " +
physicalNetworkId + "to add this device");
}
if (_bigswitchVnsDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) {
throw new CloudRuntimeException("A BigSwitch controller device is already configured on this physical network");
}
Map<String, String> params = new HashMap<String, String>();
params.put("guid", UUID.randomUUID().toString());
params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
params.put("name", "BigSwitch Controller - " + cmd.getHost());
params.put("ip", cmd.getHost());
// FIXME What to do with multiple isolation types
params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase());
Map<String, Object> hostdetails = new HashMap<String, Object>();
hostdetails.putAll(params);
try {
resource.configure(cmd.getHost(), hostdetails);
final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params);
if (host != null) {
return Transaction.execute(new TransactionCallback<BigSwitchVnsDeviceVO>() {
@Override
public BigSwitchVnsDeviceVO doInTransaction(TransactionStatus status) {
BigSwitchVnsDeviceVO bigswitchVnsDevice =
new BigSwitchVnsDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName);
_bigswitchVnsDao.persist(bigswitchVnsDevice);
DetailVO detail = new DetailVO(host.getId(), "bigswitchvnsdeviceid", String.valueOf(bigswitchVnsDevice.getId()));
_hostDetailsDao.persist(detail);
return bigswitchVnsDevice;
}
});
} else {
throw new CloudRuntimeException("Failed to add BigSwitch Vns Device due to internal error.");
}
} catch (ConfigurationException e) {
throw new CloudRuntimeException(e.getMessage());
}
}
@Override
public BigSwitchVnsDeviceResponse createBigSwitchVnsDeviceResponse(BigSwitchVnsDeviceVO bigswitchVnsDeviceVO) {
HostVO bigswitchVnsHost = _hostDao.findById(bigswitchVnsDeviceVO.getHostId());
_hostDao.loadDetails(bigswitchVnsHost);
BigSwitchVnsDeviceResponse response = new BigSwitchVnsDeviceResponse();
response.setDeviceName(bigswitchVnsDeviceVO.getDeviceName());
PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(bigswitchVnsDeviceVO.getPhysicalNetworkId());
if (pnw != null) {
response.setPhysicalNetworkId(pnw.getUuid());
}
response.setId(bigswitchVnsDeviceVO.getUuid());
response.setProviderName(bigswitchVnsDeviceVO.getProviderName());
response.setHostName(bigswitchVnsHost.getDetail("ip"));
response.setObjectName("bigswitchvnsdevice");
return response;
}
@Override
public boolean deleteBigSwitchVnsDevice(DeleteBigSwitchVnsDeviceCmd cmd) {
Long bigswitchVnsDeviceId = cmd.getBigSwitchVnsDeviceId();
BigSwitchVnsDeviceVO bigswitchVnsDevice = _bigswitchVnsDao.findById(bigswitchVnsDeviceId);
if (bigswitchVnsDevice == null) {
throw new InvalidParameterValueException("Could not find a BigSwitch Controller with id " + bigswitchVnsDevice);
}
// Find the physical network we work for
Long physicalNetworkId = bigswitchVnsDevice.getPhysicalNetworkId();
PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (physicalNetwork != null) {
List<NetworkVO> networkList = _networkDao.listByPhysicalNetwork(physicalNetworkId);
// Networks with broadcast type lswitch are ours
for (NetworkVO network : networkList) {
if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Lswitch) {
if ((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy)) {
throw new CloudRuntimeException("This BigSwitch Controller device can not be deleted as there are one or more "
+ "logical networks provisioned by cloudstack.");
}
}
}
}
HostVO bigswitchHost = _hostDao.findById(bigswitchVnsDevice.getHostId());
Long hostId = bigswitchHost.getId();
//bigswitchHost.setResourceState(ResourceState.Maintenance);
//_hostDao.update(hostId, bigswitchHost);
_hostDao.remove(hostId);
_resourceMgr.deleteHost(hostId, false, false);
_bigswitchVnsDao.remove(bigswitchVnsDeviceId);
return true;
}
@Override
public List<BigSwitchVnsDeviceVO> listBigSwitchVnsDevices(ListBigSwitchVnsDevicesCmd cmd) {
Long physicalNetworkId = cmd.getPhysicalNetworkId();
Long bigswitchVnsDeviceId = cmd.getBigSwitchVnsDeviceId();
List<BigSwitchVnsDeviceVO> responseList = new ArrayList<BigSwitchVnsDeviceVO>();
if (physicalNetworkId == null && bigswitchVnsDeviceId == null) {
throw new InvalidParameterValueException("Either physical network Id or bigswitch device Id must be specified");
}
if (bigswitchVnsDeviceId != null) {
BigSwitchVnsDeviceVO bigswitchVnsDevice = _bigswitchVnsDao.findById(bigswitchVnsDeviceId);
if (bigswitchVnsDevice == null) {
throw new InvalidParameterValueException("Could not find BigSwitch controller with id: " + bigswitchVnsDevice);
}
responseList.add(bigswitchVnsDevice);
} else {
PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (physicalNetwork == null) {
throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId);
}
responseList = _bigswitchVnsDao.listByPhysicalNetwork(physicalNetworkId);
}
return responseList;
}
@Override
public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
// TODO Auto-generated method stub
return null;
}
@Override
public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
if (!(startup[0] instanceof StartupBigSwitchVnsCommand)) {
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);
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(AddBigSwitchVnsDeviceCmd.class);
cmdList.add(DeleteBigSwitchVnsDeviceCmd.class);
cmdList.add(ListBigSwitchVnsDevicesCmd.class);
return cmdList;
}
}

View File

@ -1,240 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.cloud.network.guru;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.CreateVnsNetworkAnswer;
import com.cloud.agent.api.CreateVnsNetworkCommand;
import com.cloud.agent.api.DeleteVnsNetworkCommand;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.network.BigSwitchVnsDeviceVO;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.BigSwitchVnsDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.resource.ResourceManager;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
@Local(value = NetworkGuru.class)
public class BigSwitchVnsGuestNetworkGuru extends GuestNetworkGuru {
private static final Logger s_logger = Logger.getLogger(BigSwitchVnsGuestNetworkGuru.class);
@Inject
DataCenterDao _zoneDao;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
AccountDao _accountDao;
@Inject
BigSwitchVnsDao _bigswitchVnsDao;
@Inject
HostDao _hostDao;
@Inject
ResourceManager _resourceMgr;
@Inject
AgentManager _agentMgr;
@Inject
HostDetailsDao _hostDetailsDao;
public BigSwitchVnsGuestNetworkGuru() {
super();
_isolationMethods = new IsolationMethod[] {IsolationMethod.VNS};
}
@Override
protected boolean canHandle(NetworkOffering offering, NetworkType networkType, 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 Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
// Check of the isolation type of the related physical network is VNS
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
if (physnet == null || physnet.getIsolationMethods() == null || !physnet.getIsolationMethods().contains("VNS")) {
s_logger.debug("Refusing to design this network, the physical isolation type is not VNS");
return null;
}
List<BigSwitchVnsDeviceVO> devices = _bigswitchVnsDao.listByPhysicalNetwork(physnet.getId());
if (devices.isEmpty()) {
s_logger.error("No BigSwitxh Controller on physical network " + physnet.getName());
return null;
}
s_logger.debug("BigSwitch Controller " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());
s_logger.debug("Physical isolation type is VNS, asking GuestNetworkGuru to design this network");
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
if (networkObject == null) {
return null;
}
// Override the broadcast domain type
networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch);
return networkObject;
}
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapacityException {
assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
long dcId = dest.getDataCenter().getId();
//get physical network id
long 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, offering.getRedundantRouter());
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
String vnet =
_dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), context.getReservationId(), UseSystemGuestVlans.valueIn(network.getAccountId()));
if (vnet == null) {
throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, dcId);
}
// when supporting more types of networks this need to become
// int vlan = Integer.parseInt(BroadcastDomainType.getValue(vnet));
int vlan = Integer.parseInt(vnet);
// Name is either the given name or the uuid
String name = network.getName();
String networkUuid = implemented.getUuid();
if (name == null || name.isEmpty()) {
name = ((NetworkVO)network).getUuid();
}
if (name.length() > 64) {
name = name.substring(0, 63); // max length 64
}
String tenantId = context.getDomain().getName();
List<BigSwitchVnsDeviceVO> devices = _bigswitchVnsDao.listByPhysicalNetwork(physicalNetworkId);
if (devices.isEmpty()) {
s_logger.error("No BigSwitch Controller on physical network " + physicalNetworkId);
return null;
}
BigSwitchVnsDeviceVO bigswitchVnsDevice = devices.get(0);
HostVO bigswitchVnsHost = _hostDao.findById(bigswitchVnsDevice.getHostId());
_hostDao.loadDetails(bigswitchVnsHost);
CreateVnsNetworkCommand cmd = new CreateVnsNetworkCommand(networkUuid, name, tenantId, vlan);
CreateVnsNetworkAnswer answer = (CreateVnsNetworkAnswer)_agentMgr.easySend(bigswitchVnsHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("CreateNetworkCommand failed");
return null;
}
try {
implemented.setBroadcastUri(new URI("vns", cmd.getNetworkUuid(), null));
implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch);
s_logger.info("Implemented OK, network " + networkUuid + " in tenant " + tenantId + " linked to " + implemented.getBroadcastUri().toString());
} catch (URISyntaxException e) {
s_logger.error("Unable to store network id in broadcast uri, uuid = " + implemented.getUuid(), e);
}
return implemented;
}
@Override
public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
// TODO Auto-generated method stub
super.reserve(nic, network, vm, dest, context);
}
@Override
public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
// TODO Auto-generated method stub
return super.release(nic, vm, reservationId);
}
@Override
public void shutdown(NetworkProfile profile, NetworkOffering offering) {
NetworkVO networkObject = _networkDao.findById(profile.getId());
if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Lswitch || networkObject.getBroadcastUri() == null) {
s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
return;
}
List<BigSwitchVnsDeviceVO> devices = _bigswitchVnsDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId());
if (devices.isEmpty()) {
s_logger.error("No BigSwitch Controller on physical network " + networkObject.getPhysicalNetworkId());
return;
}
BigSwitchVnsDeviceVO bigswitchVnsDevice = devices.get(0);
HostVO bigswitchVnsHost = _hostDao.findById(bigswitchVnsDevice.getHostId());
String tenantId = profile.getNetworkDomain();
DeleteVnsNetworkCommand cmd = new DeleteVnsNetworkCommand(tenantId, BroadcastDomainType.getValue(networkObject.getBroadcastUri()));
_agentMgr.easySend(bigswitchVnsHost.getId(), cmd);
super.shutdown(profile, offering);
}
@Override
public boolean trash(Network network, NetworkOffering offering) {
return super.trash(network, offering);
}
}

View File

@ -1,309 +0,0 @@
// 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.Map;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateVnsNetworkAnswer;
import com.cloud.agent.api.CreateVnsNetworkCommand;
import com.cloud.agent.api.CreateVnsPortAnswer;
import com.cloud.agent.api.CreateVnsPortCommand;
import com.cloud.agent.api.DeleteVnsNetworkAnswer;
import com.cloud.agent.api.DeleteVnsNetworkCommand;
import com.cloud.agent.api.DeleteVnsPortAnswer;
import com.cloud.agent.api.DeleteVnsPortCommand;
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.StartupBigSwitchVnsCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.UpdateVnsPortAnswer;
import com.cloud.agent.api.UpdateVnsPortCommand;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.network.bigswitch.AttachmentData;
import com.cloud.network.bigswitch.BigSwitchVnsApi;
import com.cloud.network.bigswitch.BigSwitchVnsApiException;
import com.cloud.network.bigswitch.ControlClusterStatus;
import com.cloud.network.bigswitch.NetworkData;
import com.cloud.network.bigswitch.PortData;
import com.cloud.resource.ServerResource;
import com.cloud.utils.component.ManagerBase;
public class BigSwitchVnsResource extends ManagerBase implements ServerResource {
private static final Logger s_logger = Logger.getLogger(BigSwitchVnsResource.class);
private String _name;
private String _guid;
private String _zoneId;
private int _numRetries;
private BigSwitchVnsApi _bigswitchVnsApi;
protected BigSwitchVnsApi createBigSwitchVnsApi() {
return new BigSwitchVnsApi();
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = (String)params.get("name");
if (_name == null) {
throw new ConfigurationException("Unable to find name");
}
_guid = (String)params.get("guid");
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
_zoneId = (String)params.get("zoneId");
if (_zoneId == null) {
throw new ConfigurationException("Unable to find zone");
}
_numRetries = 2;
String ip = (String)params.get("ip");
if (ip == null) {
throw new ConfigurationException("Unable to find IP");
}
_bigswitchVnsApi = createBigSwitchVnsApi();
_bigswitchVnsApi.setControllerAddress(ip);
return true;
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return _name;
}
@Override
public Type getType() {
// Think up a better name for this Type?
return Host.Type.L2Networking;
}
@Override
public StartupCommand[] initialize() {
StartupBigSwitchVnsCommand sc = new StartupBigSwitchVnsCommand();
sc.setGuid(_guid);
sc.setName(_name);
sc.setDataCenter(_zoneId);
sc.setPod("");
sc.setPrivateIpAddress("");
sc.setStorageIpAddress("");
sc.setVersion("");
return new StartupCommand[] {sc};
}
@Override
public PingCommand getCurrentStatus(long id) {
try {
ControlClusterStatus ccs = _bigswitchVnsApi.getControlClusterStatus();
if (!ccs.getStatus()) {
s_logger.error("ControlCluster state is not ready: " + ccs.getStatus());
return null;
}
} catch (BigSwitchVnsApiException e) {
s_logger.error("getControlClusterStatus failed", e);
return null;
}
return new PingCommand(Host.Type.L2Networking, id);
}
@Override
public Answer executeRequest(Command cmd) {
return executeRequest(cmd, _numRetries);
}
public Answer executeRequest(Command cmd, int numRetries) {
if (cmd instanceof ReadyCommand) {
return executeRequest((ReadyCommand)cmd);
} else if (cmd instanceof MaintainCommand) {
return executeRequest((MaintainCommand)cmd);
} else if (cmd instanceof CreateVnsNetworkCommand) {
return executeRequest((CreateVnsNetworkCommand)cmd, numRetries);
} else if (cmd instanceof DeleteVnsNetworkCommand) {
return executeRequest((DeleteVnsNetworkCommand)cmd, numRetries);
} else if (cmd instanceof CreateVnsPortCommand) {
return executeRequest((CreateVnsPortCommand)cmd, numRetries);
} else if (cmd instanceof DeleteVnsPortCommand) {
return executeRequest((DeleteVnsPortCommand)cmd, numRetries);
} else if (cmd instanceof UpdateVnsPortCommand) {
return executeRequest((UpdateVnsPortCommand)cmd, numRetries);
}
s_logger.debug("Received unsupported command " + cmd.toString());
return Answer.createUnsupportedCommandAnswer(cmd);
}
@Override
public void disconnected() {
}
@Override
public IAgentControl getAgentControl() {
return null;
}
@Override
public void setAgentControl(IAgentControl agentControl) {
}
private Answer executeRequest(CreateVnsNetworkCommand cmd, int numRetries) {
NetworkData network = new NetworkData();
network.getNetwork().setTenantId(cmd.getTenantUuid());
network.getNetwork().setUuid(cmd.getNetworkUuid());
network.getNetwork().setDisplay_name(truncate("vns-cloudstack-" + cmd.getName(), 64));
network.getNetwork().setVlan(cmd.getVlan());
try {
_bigswitchVnsApi.createNetwork(network);
return new CreateVnsNetworkAnswer(cmd, true, "VNS " + network.getNetwork().getUuid() + " created");
} catch (BigSwitchVnsApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new CreateVnsNetworkAnswer(cmd, e);
}
}
}
private Answer executeRequest(DeleteVnsNetworkCommand cmd, int numRetries) {
try {
_bigswitchVnsApi.deleteNetwork(cmd.get_tenantUuid(), cmd.getNetworkUuid());
return new DeleteVnsNetworkAnswer(cmd, true, "VNS " + cmd.getNetworkUuid() + " deleted");
} catch (BigSwitchVnsApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new DeleteVnsNetworkAnswer(cmd, e);
}
}
}
private Answer executeRequest(CreateVnsPortCommand cmd, int numRetries) {
PortData port = new PortData();
port.getPort().setId(cmd.getPortUuid());
port.getPort().setName(cmd.getPortName());
port.getPort().setTenantId(cmd.getTenantUuid());
try {
_bigswitchVnsApi.createPort(cmd.getNetworkUuid(), port);
try {
AttachmentData attachment = new AttachmentData();
attachment.getAttachment().setId(cmd.getPortUuid());
attachment.getAttachment().setMac(cmd.getMac());
_bigswitchVnsApi.modifyPortAttachment(cmd.getTenantUuid(), cmd.getNetworkUuid(), cmd.getPortUuid(), attachment);
} catch (BigSwitchVnsApiException ex) {
s_logger.warn("modifyPortAttachment failed after switchport was created, removing switchport");
_bigswitchVnsApi.deletePort(cmd.getTenantUuid(), cmd.getNetworkUuid(), cmd.getPortUuid());
throw (ex); // Rethrow the original exception
}
return new CreateVnsPortAnswer(cmd, true, "network port " + cmd.getPortUuid() + " created");
} catch (BigSwitchVnsApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new CreateVnsPortAnswer(cmd, e);
}
}
}
private Answer executeRequest(DeleteVnsPortCommand cmd, int numRetries) {
try {
_bigswitchVnsApi.deletePortAttachment(cmd.getTenantUuid(), cmd.getNetworkUuid(), cmd.getPortUuid());
try {
_bigswitchVnsApi.deletePort(cmd.getTenantUuid(), cmd.getNetworkUuid(), cmd.getPortUuid());
} catch (BigSwitchVnsApiException ex) {
s_logger.warn("deletePort failed after portAttachment was removed");
throw (ex); // Rethrow the original exception
}
return new DeleteVnsPortAnswer(cmd, true, "network port " + cmd.getPortUuid() + " deleted");
} catch (BigSwitchVnsApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new DeleteVnsPortAnswer(cmd, e);
}
}
}
private Answer executeRequest(UpdateVnsPortCommand cmd, int numRetries) {
PortData port = new PortData();
port.getPort().setId(cmd.getPortUuid());
port.getPort().setName(cmd.getPortName());
port.getPort().setTenantId(cmd.getTenantUuid());
try {
_bigswitchVnsApi.modifyPort(cmd.getNetworkUuid(), port);
return new UpdateVnsPortAnswer(cmd, true, "Network Port " + cmd.getPortUuid() + " updated");
} catch (BigSwitchVnsApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new UpdateVnsPortAnswer(cmd, e);
}
}
}
private Answer executeRequest(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer executeRequest(MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
private Answer retry(Command cmd, int numRetries) {
s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries);
return executeRequest(cmd, numRetries);
}
private String truncate(String string, int length) {
if (string.length() <= length) {
return string;
} else {
return string.substring(0, length);
}
}
}

View File

@ -1,232 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.bigswitch;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.Collections;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.http.HttpStatus;
import org.junit.Before;
import org.junit.Test;
public class BigSwitchApiTest {
BigSwitchVnsApi _api;
HttpClient _client = mock(HttpClient.class);
HttpMethod _method;
@Before
public void setUp() {
HttpClientParams hmp = mock(HttpClientParams.class);
when(_client.getParams()).thenReturn(hmp);
_api = new BigSwitchVnsApi() {
@Override
protected HttpClient createHttpClient() {
return _client;
}
@Override
protected HttpMethod createMethod(String type, String uri, int port) {
return _method;
}
};
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteUpdateObjectWithoutHostname() throws BigSwitchVnsApiException {
_api.setControllerAddress(null);
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteCreateObjectWithoutHostname() throws BigSwitchVnsApiException {
_api.setControllerAddress(null);
_api.executeCreateObject(new String(), String.class, "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteDeleteObjectWithoutHostname() throws BigSwitchVnsApiException {
_api.setControllerAddress(null);
_api.executeDeleteObject("/");
}
@Test
public void executeMethodTest() throws BigSwitchVnsApiException {
GetMethod gm = mock(GetMethod.class);
when(gm.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeMethod(gm);
verify(gm, times(1)).getStatusCode();
}
/* Bit of a roundabout way to ensure that login is called after an un authorized result
* It not possible to properly mock login()
*/
@Test(expected = BigSwitchVnsApiException.class)
public void executeMethodTestWithLogin() throws BigSwitchVnsApiException, HttpException, IOException {
GetMethod gm = mock(GetMethod.class);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
when(gm.getStatusCode()).thenReturn(HttpStatus.SC_UNAUTHORIZED).thenReturn(HttpStatus.SC_UNAUTHORIZED);
_api.executeMethod(gm);
verify(gm, times(1)).getStatusCode();
}
@Test
public void testExecuteCreateObject() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeCreateObject(network, NetworkData.class, "/", Collections.<String, String> emptyMap());
verify(_method, times(1)).releaseConnection();
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteCreateObjectFailure() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-Type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeCreateObject(network, NetworkData.class, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteCreateObjectException() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-Type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
try {
_api.executeCreateObject(network, NetworkData.class, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test
public void testExecuteUpdateObject() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteUpdateObjectFailure() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-Type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteUpdateObjectException() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new IOException());
try {
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test
public void testExecuteDeleteObject() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeDeleteObject("/");
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteDeleteObjectFailure() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-Type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeDeleteObject("/");
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchVnsApiException.class)
public void testExecuteDeleteObjectException() throws BigSwitchVnsApiException, IOException {
_api.setControllerAddress("10.10.0.10");
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
try {
_api.executeDeleteObject("/");
} finally {
verify(_method, times(1)).releaseConnection();
}
}
}

View File

@ -1,271 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.resource;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.junit.Before;
import org.junit.Test;
import com.cloud.agent.api.CreateVnsNetworkAnswer;
import com.cloud.agent.api.CreateVnsNetworkCommand;
import com.cloud.agent.api.CreateVnsPortAnswer;
import com.cloud.agent.api.CreateVnsPortCommand;
import com.cloud.agent.api.DeleteVnsNetworkAnswer;
import com.cloud.agent.api.DeleteVnsNetworkCommand;
import com.cloud.agent.api.DeleteVnsPortAnswer;
import com.cloud.agent.api.DeleteVnsPortCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.UpdateVnsPortAnswer;
import com.cloud.agent.api.UpdateVnsPortCommand;
import com.cloud.host.Host;
import com.cloud.network.bigswitch.AttachmentData;
import com.cloud.network.bigswitch.BigSwitchVnsApi;
import com.cloud.network.bigswitch.BigSwitchVnsApiException;
import com.cloud.network.bigswitch.ControlClusterStatus;
import com.cloud.network.bigswitch.NetworkData;
import com.cloud.network.bigswitch.PortData;
public class BigSwitchVnsResourceTest {
BigSwitchVnsApi _bigswitchVnsApi = mock(BigSwitchVnsApi.class);
BigSwitchVnsResource _resource;
Map<String, Object> _parameters;
@Before
public void setUp() throws ConfigurationException {
_resource = new BigSwitchVnsResource() {
@Override
protected BigSwitchVnsApi createBigSwitchVnsApi() {
return _bigswitchVnsApi;
}
};
_parameters = new HashMap<String, Object>();
_parameters.put("name", "bigswitchvnstestdevice");
_parameters.put("ip", "127.0.0.1");
_parameters.put("guid", "aaaaa-bbbbb-ccccc");
_parameters.put("zoneId", "blublub");
}
@Test(expected = ConfigurationException.class)
public void resourceConfigureFailure() throws ConfigurationException {
_resource.configure("BigSwitchVnsResource", Collections.<String, Object> emptyMap());
}
@Test
public void resourceConfigure() throws ConfigurationException {
_resource.configure("BigSwitchVnsResource", _parameters);
verify(_bigswitchVnsApi).setControllerAddress("127.0.0.1");
assertTrue("bigswitchvnstestdevice".equals(_resource.getName()));
/* Pretty lame test, but here to assure this plugin fails
* if the type name ever changes from L2Networking
*/
assertTrue(_resource.getType() == Host.Type.L2Networking);
}
@Test
public void testInitialization() throws ConfigurationException {
_resource.configure("BigSwitchVnsResource", _parameters);
StartupCommand[] sc = _resource.initialize();
assertTrue(sc.length == 1);
assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid()));
assertTrue("bigswitchvnstestdevice".equals(sc[0].getName()));
assertTrue("blublub".equals(sc[0].getDataCenter()));
}
@Test
public void testPingCommandStatusOk() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(true);
when(_bigswitchVnsApi.getControlClusterStatus()).thenReturn(ccs);
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping != null);
assertTrue(ping.getHostId() == 42);
assertTrue(ping.getHostType() == Host.Type.L2Networking);
}
@Test
public void testPingCommandStatusFail() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(false);
when(_bigswitchVnsApi.getControlClusterStatus()).thenReturn(ccs);
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping == null);
}
@Test
public void testPingCommandStatusApiException() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(false);
when(_bigswitchVnsApi.getControlClusterStatus()).thenThrow(new BigSwitchVnsApiException());
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping == null);
}
@Test
public void testRetries() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
NetworkData networkdata = mock(NetworkData.class);
NetworkData.Network network = mock(NetworkData.Network.class);
when(networkdata.getNetwork()).thenReturn(network);
when(network.getUuid()).thenReturn("cccc").thenReturn("cccc");
CreateVnsNetworkCommand cntkc = new CreateVnsNetworkCommand((String)_parameters.get("guid"), "networkName", "tenantid", 1);
CreateVnsNetworkAnswer cntka = (CreateVnsNetworkAnswer)_resource.executeRequest(cntkc);
assertTrue(cntka.getResult());
}
@Test
public void testCreateNetwork() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
NetworkData networkdata = mock(NetworkData.class);
NetworkData.Network network = mock(NetworkData.Network.class);
when(networkdata.getNetwork()).thenReturn(network);
when(network.getUuid()).thenReturn("cccc").thenReturn("cccc");
CreateVnsNetworkCommand cntkc = new CreateVnsNetworkCommand((String)_parameters.get("guid"), "networkName", "tenantid", 1);
CreateVnsNetworkAnswer cntka = (CreateVnsNetworkAnswer)_resource.executeRequest(cntkc);
assertTrue(cntka.getResult());
}
@Test
public void testCreateNetworkApiException() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
NetworkData networkdata = mock(NetworkData.class);
NetworkData.Network network = mock(NetworkData.Network.class);
when(networkdata.getNetwork()).thenReturn(network);
when(network.getUuid()).thenReturn("cccc").thenReturn("cccc");
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).createNetwork((NetworkData)any());
CreateVnsNetworkCommand cntkc = new CreateVnsNetworkCommand((String)_parameters.get("guid"), "networkName", "tenantid", 1);
CreateVnsNetworkAnswer cntka = (CreateVnsNetworkAnswer)_resource.executeRequest(cntkc);
assertFalse(cntka.getResult());
}
@Test
public void testDeleteNetwork() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
DeleteVnsNetworkCommand dntkc = new DeleteVnsNetworkCommand("tenantid", "networkid");
DeleteVnsNetworkAnswer dntka = (DeleteVnsNetworkAnswer)_resource.executeRequest(dntkc);
assertTrue(dntka.getResult());
}
@Test
public void testDeleteNetworkApiException() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).deleteNetwork((String)any(), (String)any());
DeleteVnsNetworkCommand dntkc = new DeleteVnsNetworkCommand("tenantid", "networkid");
DeleteVnsNetworkAnswer dntka = (DeleteVnsNetworkAnswer)_resource.executeRequest(dntkc);
assertFalse(dntka.getResult());
}
@Test
public void testCreatePort() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
PortData portdata = mock(PortData.class);
PortData.Port port = mock(PortData.Port.class);
when(portdata.getPort()).thenReturn(port);
when(port.getId()).thenReturn("eeee");
CreateVnsPortCommand cntkc = new CreateVnsPortCommand("networkid", "portid", "tenantid", "portname", "aa:bb:cc:dd:ee:ff");
CreateVnsPortAnswer cntka = (CreateVnsPortAnswer)_resource.executeRequest(cntkc);
assertTrue(cntka.getResult());
}
@Test
public void testCreatePortApiExceptionInCreate() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
PortData portdata = mock(PortData.class);
PortData.Port port = mock(PortData.Port.class);
when(portdata.getPort()).thenReturn(port);
when(port.getId()).thenReturn("eeee");
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).createPort((String)any(), (PortData)any());
CreateVnsPortCommand cntkc = new CreateVnsPortCommand("networkid", "portid", "tenantid", "portname", "aa:bb:cc:dd:ee:ff");
CreateVnsPortAnswer cntka = (CreateVnsPortAnswer)_resource.executeRequest(cntkc);
assertFalse(cntka.getResult());
}
@Test
public void testCreatePortApiExceptionInModify() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
PortData portdata = mock(PortData.class);
PortData.Port port = mock(PortData.Port.class);
when(portdata.getPort()).thenReturn(port);
when(port.getId()).thenReturn("eeee");
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).modifyPortAttachment((String)any(), (String)any(), (String)any(), (AttachmentData)any());
CreateVnsPortCommand cntkc = new CreateVnsPortCommand("networkid", "portid", "tenantid", "portname", "aa:bb:cc:dd:ee:ff");
CreateVnsPortAnswer cntka = (CreateVnsPortAnswer)_resource.executeRequest(cntkc);
assertFalse(cntka.getResult());
verify(_bigswitchVnsApi, atLeastOnce()).deletePort((String)any(), (String)any(), (String)any());
}
@Test
public void testDeletePortException() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).deletePort((String)any(), (String)any(), (String)any());
DeleteVnsPortAnswer dntkpa = (DeleteVnsPortAnswer)_resource.executeRequest(new DeleteVnsPortCommand("networkId", "portid", "tenantid"));
assertFalse(dntkpa.getResult());
}
@Test
public void testUpdatePortException() throws ConfigurationException, BigSwitchVnsApiException {
_resource.configure("BigSwitchVnsResource", _parameters);
doThrow(new BigSwitchVnsApiException()).when(_bigswitchVnsApi).modifyPort((String)any(), (PortData)any());
UpdateVnsPortAnswer dntkpa = (UpdateVnsPortAnswer)_resource.executeRequest(new UpdateVnsPortCommand("networkId", "portId", "tenantId", "portname"));
assertFalse(dntkpa.getResult());
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<FindBugsFilter>
</FindBugsFilter>

View File

@ -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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-network-bigswitch</artifactId>
<name>Apache CloudStack Plugin - BigSwitch Virtual Network Segment</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.6.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>cloudstack-checklicence</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,3 +1,4 @@
#
# 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
@ -14,5 +15,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
name=vns
parent=network
#
name=bigswitch
parent=network

View File

@ -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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<bean id="bigSwitchBcfDaoImpl" class="com.cloud.network.dao.BigSwitchBcfDaoImpl" />
<bean id="BigSwitchBcfGuestNetworkGuru" class="com.cloud.network.guru.BigSwitchBcfGuestNetworkGuru">
<property name="name" value="BigSwitchBcfGuestNetworkGuru" />
</bean>
<bean id="BigSwitchBcf" class="com.cloud.network.element.BigSwitchBcfElement">
<property name="name" value="BigSwitchBcf" />
</bean>
</beans>

View File

@ -0,0 +1,43 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api;
public class BcfAnswer extends Answer{
private final String hash;
public BcfAnswer(Command command, boolean success, String details) {
super(command, success, details);
this.hash = "";
}
public BcfAnswer(Command command, boolean success, String details, String hash) {
super(command, success, details);
this.hash = hash;
}
public BcfAnswer(Command command, Exception e) {
super(command, e);
this.hash = "";
}
public String getHash() {
return hash;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,35 +15,34 @@
// 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 DeleteVnsPortCommand extends Command {
import com.cloud.network.bigswitch.TopologyData;
private String _networkUuid;
private String _portUuid;
private String _tenantUuid;
public DeleteVnsPortCommand(String networkUuid, String portUuid, String tenantUuid) {
this._networkUuid = networkUuid;
this._portUuid = portUuid;
this._tenantUuid = tenantUuid;
}
public String getNetworkUuid() {
return _networkUuid;
}
public String getPortUuid() {
return _portUuid;
}
public String getTenantUuid() {
return _tenantUuid;
}
public class BcfCommand extends Command {
private TopologyData topology = null;
private boolean _topologySyncRequested = false;
@Override
public boolean executeInSequence() {
return false;
}
public TopologyData getTopology() {
return topology;
}
public void setTopology(TopologyData topology) {
this.topology = topology;
}
public boolean is_topologySyncRequested() {
return _topologySyncRequested;
}
public void set_topologySyncRequested(boolean requested) {
this._topologySyncRequested = requested;
}
}

View File

@ -0,0 +1,39 @@
//
// 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.network.bigswitch.TopologyData;
public class CacheBcfTopologyCommand extends Command{
private final TopologyData topology;
public CacheBcfTopologyCommand(TopologyData topology){
this.topology = topology;
}
@Override
public boolean executeInSequence() {
return false;
}
public TopologyData getTopology() {
return topology;
}
}

View File

@ -0,0 +1,75 @@
//
// 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 CreateBcfAttachmentCommand extends BcfCommand {
private String _tenantId;
private String _tenantName;
private String _networkId;
private String _portId;
private String _nicId;
private Integer _vlan;
private String _ipv4;
private String _mac;
public CreateBcfAttachmentCommand(String tenantId, String tenantName,
String networkId, String portId, String nicId,
Integer vlan, String ipv4, String mac) {
this._tenantId = tenantId;
this._tenantName = tenantName;
this._networkId = networkId;
this._portId = portId;
this._nicId = nicId;
this._vlan = vlan;
this._ipv4 = ipv4;
this._mac = mac;
}
public String getTenantId() {
return _tenantId;
}
public String getTenantName() {
return _tenantName;
}
public String getNetworkId() {
return _networkId;
}
public String getPortId() {
return _portId;
}
public String getNicId() {
return _nicId;
}
public Integer getVlan() {
return _vlan;
}
public String getIpv4() {
return _ipv4;
}
public String getMac() {
return _mac;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,16 +15,18 @@
// 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 CreateVnsPortAnswer extends Answer {
public class CreateBcfRouterCommand extends BcfCommand {
private final String _tenantId;
public CreateVnsPortAnswer(Command command, boolean success, String details) {
super(command, success, details);
public CreateBcfRouterCommand(String tenantId){
this._tenantId = tenantId;
}
public CreateVnsPortAnswer(Command command, Exception e) {
super(command, e);
public String get_tenantId() {
return _tenantId;
}
}

View File

@ -0,0 +1,57 @@
//
// 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 CreateBcfRouterInterfaceCommand extends BcfCommand{
private final String _tenantId;
private final String _networkId;
private final String _cidr;
private final String _gateway;
private final String _networkName;
public CreateBcfRouterInterfaceCommand(String tenantId, String networkId, String cidr,
String gateway, String networkName){
this._tenantId = tenantId;
this._networkId = networkId;
this._networkName = networkName;
this._cidr = cidr;
this._gateway = gateway;
}
public String get_tenantId() {
return _tenantId;
}
public String get_networkId() {
return _networkId;
}
public String get_networkName() {
return _networkName;
}
public String get_cidr() {
return _cidr;
}
public String get_gateway() {
return _gateway;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,39 +15,43 @@
// 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 CreateVnsNetworkCommand extends Command {
private String _networkUuid;
private String _name;
private String _tenantUuid;
private int _vlan;
public class CreateBcfSegmentCommand extends BcfCommand {
private String _tenantId;
private String _tenantName;
private String _networkId;
private String _networkName;
private Integer _vlan;
public CreateVnsNetworkCommand(String networkUuid, String name, String tenantUuid, int vlan) {
this._networkUuid = networkUuid;
this._name = name;
this._tenantUuid = tenantUuid;
public CreateBcfSegmentCommand(String tenantId, String tenantName,
String networkId, String networkName, Integer vlan) {
this._tenantId = tenantId;
this._tenantName = tenantName;
this._networkId = networkId;
this._networkName = networkName;
this._vlan = vlan;
}
@Override
public boolean executeInSequence() {
return false;
public String getNetworkId() {
return _networkId;
}
public String getNetworkUuid() {
return _networkUuid;
public String getNetworkName() {
return _networkName;
}
public String getName() {
return _name;
public String getTenantId() {
return _tenantId;
}
public String getTenantUuid() {
return _tenantUuid;
public String getTenantName() {
return _tenantName;
}
public int getVlan() {
public Integer getVlan() {
return _vlan;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,46 +15,43 @@
// 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 CreateVnsPortCommand extends Command {
private String _networkUuid;
private String _portUuid;
private String _tenantUuid;
private String _portName;
private String _mac;
public class CreateBcfStaticNatCommand extends BcfCommand {
private final String _tenantId;
private final String _networkId;
private final String _privateIp;
private final String _publicIp;
private final String _mac;
public CreateVnsPortCommand(String networkUuid, String portUuid, String tenantUuid, String portName, String mac) {
this._networkUuid = networkUuid;
this._portUuid = portUuid;
this._tenantUuid = tenantUuid;
this._portName = portName;
public CreateBcfStaticNatCommand(String tenantId, String networkId,
String privateIp, String publicIp, String mac){
this._tenantId = tenantId;
this._networkId = networkId;
this._privateIp = privateIp;
this._publicIp = publicIp;
this._mac = mac;
}
public String getNetworkUuid() {
return _networkUuid;
public String get_tenantId() {
return _tenantId;
}
public String getPortUuid() {
return _portUuid;
public String get_networkId() {
return _networkId;
}
public String getTenantUuid() {
return _tenantUuid;
public String get_privateIp() {
return _privateIp;
}
public String getPortName() {
return _portName;
public String get_publicIp() {
return _publicIp;
}
public String getMac() {
public String get_mac() {
return _mac;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,45 @@
//
// 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 DeleteBcfAttachmentCommand extends BcfCommand {
private String _tenantId;
private String _networkId;
private String _attachmentId;
public DeleteBcfAttachmentCommand(String tenantId,
String networkId, String attachmentId) {
this._tenantId = tenantId;
this._networkId = networkId;
this._attachmentId = attachmentId;
}
public String getTenantId() {
return _tenantId;
}
public String getNetworkId() {
return _networkId;
}
public String getAttachmentId() {
return _attachmentId;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,23 +15,20 @@
// 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 DeleteVnsNetworkCommand extends Command {
public class DeleteBcfSegmentCommand extends BcfCommand {
private String _tenantUuid;
private String _networkUuid;
public DeleteVnsNetworkCommand(String tenantUuid, String networkUuid) {
public DeleteBcfSegmentCommand(String tenantUuid, String networkUuid) {
this._tenantUuid = tenantUuid;
this._networkUuid = networkUuid;
}
@Override
public boolean executeInSequence() {
return false;
}
public String get_tenantUuid() {
return _tenantUuid;
}
@ -38,4 +36,4 @@ public class DeleteVnsNetworkCommand extends Command {
public String getNetworkUuid() {
return _networkUuid;
}
}
}

View File

@ -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;
public class DeleteBcfStaticNatCommand extends BcfCommand {
private final String _tenantId;
private final String _publicIp;
private final String _floatingIpId;
public DeleteBcfStaticNatCommand(String tenantId, String publicIp){
this._tenantId = tenantId;
this._publicIp = publicIp;
this._floatingIpId = publicIp.replace(".", "-");
}
public String get_tenantId() {
return _tenantId;
}
public String get_publicIp() {
return _publicIp;
}
public String get_floatingIpId() {
return _floatingIpId;
}
}

View File

@ -0,0 +1,45 @@
//
// 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 GetControllerDataAnswer extends Answer {
private final String ipAddress;
private final boolean isMaster;
public GetControllerDataAnswer(GetControllerDataCommand cmd,
String ipAddress, boolean isMaster){
this.ipAddress = ipAddress;
this.isMaster = isMaster;
}
public GetControllerDataAnswer(Command command, Exception e) {
super(command, e);
this.ipAddress = null;
this.isMaster = false;
}
public String getIpAddress() {
return ipAddress;
}
public boolean isMaster() {
return isMaster;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,16 +15,11 @@
// 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 UpdateVnsPortAnswer extends Answer {
public UpdateVnsPortAnswer(Command command, boolean success, String details) {
super(command, success, details);
public class GetControllerDataCommand extends BcfCommand {
public GetControllerDataCommand() {
}
public UpdateVnsPortAnswer(Command command, Exception e) {
super(command, e);
}
}

View File

@ -0,0 +1,40 @@
//
// 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.HostVO;
public class GetControllerHostsAnswer {
private HostVO master;
private HostVO slave;
public HostVO getMaster() {
return master;
}
public void setMaster(HostVO master) {
this.master = master;
}
public HostVO getSlave() {
return slave;
}
public void setSlave(HostVO slave) {
this.slave = slave;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,16 +15,11 @@
// 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 DeleteVnsPortAnswer extends Answer {
public DeleteVnsPortAnswer(Command command, boolean success, String details) {
super(command, success, details);
public class GetControllerHostsCommand extends BcfCommand {
public GetControllerHostsCommand() {
}
public DeleteVnsPortAnswer(Command command, Exception e) {
super(command, e);
}
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,13 +15,15 @@
// 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 StartupBigSwitchVnsCommand extends StartupCommand {
public class StartupBigSwitchBcfCommand extends StartupCommand {
public StartupBigSwitchVnsCommand() {
public StartupBigSwitchBcfCommand() {
super(Host.Type.L2Networking);
}

View File

@ -0,0 +1,38 @@
//
// 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 SyncBcfTopologyCommand extends BcfCommand {
private final boolean networkIncluded;
private final boolean routerIncluded;
public SyncBcfTopologyCommand(boolean networkIncluded, boolean routerIncluded) {
this.networkIncluded = networkIncluded;
this.routerIncluded = routerIncluded;
}
public boolean isNetworkIncluded() {
return networkIncluded;
}
public boolean isRouterIncluded() {
return routerIncluded;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,40 +15,36 @@
// 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 UpdateVnsPortCommand extends Command {
private String _networkUuid;
private String _portUuid;
private String _tenantUuid;
private String _portName;
public class UpdateBcfAttachmentCommand extends BcfCommand {
private String _networkId;
private String _attachmentId;
private String _tenantId;
private String _attachmentName;
public UpdateVnsPortCommand(String networkUuid, String portUuid, String tenantUuid, String portName) {
this._networkUuid = networkUuid;
this._portUuid = portUuid;
this._tenantUuid = tenantUuid;
this._portName = portName;
public UpdateBcfAttachmentCommand(String networkId, String attachmentId, String tenantId, String attachmentName) {
this._networkId = networkId;
this._attachmentId = attachmentId;
this._tenantId = tenantId;
this._attachmentName = attachmentName;
}
public String getNetworkUuid() {
return _networkUuid;
public String getNetworkId() {
return _networkId;
}
public String getPortUuid() {
return _portUuid;
public String getAttachmentId() {
return _attachmentId;
}
public String getTenantUuid() {
return _tenantUuid;
public String getTenantId() {
return _tenantId;
}
public String getPortName() {
return _portName;
return _attachmentName;
}
@Override
public boolean executeInSequence() {
return false;
}
}

View File

@ -0,0 +1,61 @@
//
// 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 java.util.ArrayList;
import java.util.List;
import com.cloud.network.bigswitch.AclData;
public class UpdateBcfRouterCommand extends BcfCommand {
private String tenantId;
private String publicIp;
private List<AclData> acls;
public UpdateBcfRouterCommand(String tenantId){
this.tenantId = tenantId;
this.publicIp = null;
this.acls = new ArrayList<AclData>();
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getPublicIp() {
return publicIp;
}
public void setPublicIp(String publicIp) {
this.publicIp = publicIp;
}
public List<AclData> getAcls() {
return acls;
}
public void addAcl(AclData acl){
this.acls.add(acl);
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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;
@ -27,22 +30,22 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.api.response.BigSwitchVnsDeviceResponse;
import com.cloud.api.response.BigSwitchBcfDeviceResponse;
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.BigSwitchVnsDeviceVO;
import com.cloud.network.element.BigSwitchVnsElementService;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.element.BigSwitchBcfElementService;
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = "addBigSwitchVnsDevice", responseObject = BigSwitchVnsDeviceResponse.class, description = "Adds a BigSwitch VNS device", since = "4.1.0",
@APICommand(name = "addBigSwitchBcfDevice", responseObject = BigSwitchBcfDeviceResponse.class, description = "Adds a BigSwitch BCF Controller device", since = "4.6.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
private static final String s_name = "addbigswitchvnsdeviceresponse";
public class AddBigSwitchBcfDeviceCmd extends BaseAsyncCmd {
private static final String s_name = "addbigswitchbcfdeviceresponse";
@Inject
BigSwitchVnsElementService _bigswitchVnsElementService;
BigSwitchBcfElementService _bigswitchBcfElementService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -55,9 +58,21 @@ public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
description = "the Physical Network ID")
private Long physicalNetworkId;
@Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "Hostname of ip address of the BigSwitch VNS Controller.")
@Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "Hostname of ip address of the BigSwitch BCF Controller.")
private String host;
@Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required=true,
description="Username of the BigSwitch BCF Controller.")
private String username;
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=true,
description="Password of the BigSwitch BCF Controller.")
private String password;
@Parameter(name=BcfConstants.BIGSWITCH_BCF_DEVICE_NAT, type=CommandType.BOOLEAN, required=true,
description="NAT support of the BigSwitch BCF Controller.")
private Boolean nat;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -70,6 +85,18 @@ public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
return host;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public Boolean getNat() {
return nat;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -78,14 +105,14 @@ public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
BigSwitchVnsDeviceVO bigswitchVnsDeviceVO = _bigswitchVnsElementService.addBigSwitchVnsDevice(this);
if (bigswitchVnsDeviceVO != null) {
BigSwitchVnsDeviceResponse response = _bigswitchVnsElementService.createBigSwitchVnsDeviceResponse(bigswitchVnsDeviceVO);
response.setObjectName("bigswitchvnsdevice");
BigSwitchBcfDeviceVO bigswitchBcfDeviceVO = _bigswitchBcfElementService.addBigSwitchBcfDevice(this);
if (bigswitchBcfDeviceVO != null) {
BigSwitchBcfDeviceResponse response = _bigswitchBcfElementService.createBigSwitchBcfDeviceResponse(bigswitchBcfDeviceVO);
response.setObjectName("bigswitchbcfdevice");
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add BigSwitch VNS device due to internal error.");
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add BigSwitch BCF Controller device due to internal error.");
}
} catch (InvalidParameterValueException invalidParamExcp) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
@ -106,11 +133,11 @@ public class AddBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
@Override
public String getEventType() {
return VnsConstants.EVENT_EXTERNAL_VNS_CONTROLLER_ADD;
return BcfConstants.EVENT_EXTERNAL_BCF_CONTROLLER_ADD;
}
@Override
public String getEventDescription() {
return "Adding a BigSwitch VNS Controller";
return "Adding a BigSwitch BCF Controller";
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.api.commands;
@ -21,15 +23,15 @@ import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import com.cloud.network.Network.Provider;
public class VnsConstants {
public static final String BIGSWITCH_VNS_DEVICE_ID = "vnsdeviceid";
public static final String BIGSWITCH_VNS_DEVICE_NAME = "bigswitchdevicename";
public class BcfConstants {
public static final String BIGSWITCH_BCF_DEVICE_ID = "bcfdeviceid";
public static final String BIGSWITCH_BCF_DEVICE_NAME = "bigswitchdevicename";
public static final String BIGSWITCH_BCF_DEVICE_NAT = "nat";
public static final String EVENT_EXTERNAL_BCF_CONTROLLER_ADD = "PHYSICAL.BCFCONTROLLER.ADD";
public static final String EVENT_EXTERNAL_BCF_CONTROLLER_DELETE = "PHYSICAL.BCFCONTROLLER.DELETE";
public static final String EVENT_EXTERNAL_VNS_CONTROLLER_ADD = "PHYSICAL.VNSCONTROLLER.ADD";
public static final String EVENT_EXTERNAL_VNS_CONTROLLER_DELETE = "PHYSICAL.VNSCONTROLLER.DELETE";
public static final Provider BigSwitchBcf = new Provider("BigSwitchBcf", true);
public static final Provider BigSwitchVns = new Provider("BigSwitchVns", true);
public static final NetworkDevice BigSwitchVnsDevice = new NetworkDevice("BigSwitchVns", BigSwitchVns.getName());
public static final NetworkDevice BigSwitchBcfDevice = new NetworkDevice("BigSwitchBcf", BigSwitchBcf.getName());
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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;
@ -26,39 +29,39 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.api.response.BigSwitchVnsDeviceResponse;
import com.cloud.api.response.BigSwitchBcfDeviceResponse;
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.element.BigSwitchVnsElementService;
import com.cloud.network.element.BigSwitchBcfElementService;
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = "deleteBigSwitchVnsDevice", responseObject = SuccessResponse.class, description = " delete a bigswitch vns device", since = "4.1.0",
@APICommand(name = "deleteBigSwitchBcfDevice", responseObject = SuccessResponse.class, description = " delete a BigSwitch BCF Controller device", since = "4.6.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
private static final String s_name = "deletebigswitchvnsdeviceresponse";
public class DeleteBigSwitchBcfDeviceCmd extends BaseAsyncCmd {
private static final String s_name = "deletebigswitchbcfdeviceresponse";
@Inject
BigSwitchVnsElementService _bigswitchVnsElementService;
BigSwitchBcfElementService _bigswitchBcfElementService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = VnsConstants.BIGSWITCH_VNS_DEVICE_ID,
@Parameter(name = BcfConstants.BIGSWITCH_BCF_DEVICE_ID,
type = CommandType.UUID,
entityType = BigSwitchVnsDeviceResponse.class,
entityType = BigSwitchBcfDeviceResponse.class,
required = true,
description = "BigSwitch device ID")
private Long bigswitchVnsDeviceId;
private Long bigswitchBcfDeviceId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getBigSwitchVnsDeviceId() {
return bigswitchVnsDeviceId;
public Long getBigSwitchBcfDeviceId() {
return bigswitchBcfDeviceId;
}
/////////////////////////////////////////////////////
@ -69,7 +72,7 @@ public class DeleteBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
boolean result = _bigswitchVnsElementService.deleteBigSwitchVnsDevice(this);
boolean result = _bigswitchBcfElementService.deleteBigSwitchBcfDevice(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
@ -96,12 +99,12 @@ public class DeleteBigSwitchVnsDeviceCmd extends BaseAsyncCmd {
@Override
public String getEventType() {
return VnsConstants.EVENT_EXTERNAL_VNS_CONTROLLER_DELETE;
return BcfConstants.EVENT_EXTERNAL_BCF_CONTROLLER_DELETE;
}
@Override
public String getEventDescription() {
return "Deleting BigSwitch Vns Controller";
return "Deleting BigSwitch BCF Controller";
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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;
@ -32,23 +35,23 @@ 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.BigSwitchVnsDeviceResponse;
import com.cloud.api.response.BigSwitchBcfDeviceResponse;
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.BigSwitchVnsDeviceVO;
import com.cloud.network.element.BigSwitchVnsElementService;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.element.BigSwitchBcfElementService;
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = "listBigSwitchVnsDevices", responseObject = BigSwitchVnsDeviceResponse.class, description = "Lists BigSwitch Vns devices", since = "4.1.0",
@APICommand(name = "listBigSwitchBcfDevices", responseObject = BigSwitchBcfDeviceResponse.class, description = "Lists BigSwitch BCF Controller devices", since = "4.6.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListBigSwitchVnsDevicesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListBigSwitchVnsDevicesCmd.class.getName());
private static final String s_name = "listbigswitchvnsdeviceresponse";
public class ListBigSwitchBcfDevicesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListBigSwitchBcfDevicesCmd.class.getName());
private static final String s_name = "listbigswitchbcfdeviceresponse";
@Inject
BigSwitchVnsElementService _bigswitchVnsElementService;
BigSwitchBcfElementService _bigswitchBcfElementService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -57,18 +60,18 @@ public class ListBigSwitchVnsDevicesCmd extends BaseListCmd {
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, description = "the Physical Network ID")
private Long physicalNetworkId;
@Parameter(name = VnsConstants.BIGSWITCH_VNS_DEVICE_ID,
@Parameter(name = BcfConstants.BIGSWITCH_BCF_DEVICE_ID,
type = CommandType.UUID,
entityType = BigSwitchVnsDeviceResponse.class,
description = "bigswitch vns device ID")
private Long bigswitchVnsDeviceId;
entityType = BigSwitchBcfDeviceResponse.class,
description = "bigswitch BCF controller device ID")
private Long bigswitchBcfDeviceId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getBigSwitchVnsDeviceId() {
return bigswitchVnsDeviceId;
public Long getBigSwitchBcfDeviceId() {
return bigswitchBcfDeviceId;
}
public Long getPhysicalNetworkId() {
@ -83,13 +86,13 @@ public class ListBigSwitchVnsDevicesCmd extends BaseListCmd {
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
List<BigSwitchVnsDeviceVO> bigswitchDevices = _bigswitchVnsElementService.listBigSwitchVnsDevices(this);
ListResponse<BigSwitchVnsDeviceResponse> response = new ListResponse<BigSwitchVnsDeviceResponse>();
List<BigSwitchVnsDeviceResponse> bigswitchDevicesResponse = new ArrayList<BigSwitchVnsDeviceResponse>();
List<BigSwitchBcfDeviceVO> bigswitchDevices = _bigswitchBcfElementService.listBigSwitchBcfDevices(this);
ListResponse<BigSwitchBcfDeviceResponse> response = new ListResponse<BigSwitchBcfDeviceResponse>();
List<BigSwitchBcfDeviceResponse> bigswitchDevicesResponse = new ArrayList<BigSwitchBcfDeviceResponse>();
if (bigswitchDevices != null && !bigswitchDevices.isEmpty()) {
for (BigSwitchVnsDeviceVO bigswitchDeviceVO : bigswitchDevices) {
BigSwitchVnsDeviceResponse bigswitchDeviceResponse = _bigswitchVnsElementService.createBigSwitchVnsDeviceResponse(bigswitchDeviceVO);
for (BigSwitchBcfDeviceVO bigswitchDeviceVO : bigswitchDevices) {
BigSwitchBcfDeviceResponse bigswitchDeviceResponse = _bigswitchBcfElementService.createBigSwitchBcfDeviceResponse(bigswitchDeviceVO);
bigswitchDevicesResponse.add(bigswitchDeviceResponse);
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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.google.gson.annotations.SerializedName;
@ -22,25 +25,25 @@ import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.api.commands.VnsConstants;
import com.cloud.network.BigSwitchVnsDeviceVO;
import com.cloud.api.commands.BcfConstants;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.serializer.Param;
@EntityReference(value = BigSwitchVnsDeviceVO.class)
public class BigSwitchVnsDeviceResponse extends BaseResponse {
@SerializedName(VnsConstants.BIGSWITCH_VNS_DEVICE_ID)
@Param(description = "device id of the BigSwitch Vns")
@EntityReference(value = BigSwitchBcfDeviceVO.class)
public class BigSwitchBcfDeviceResponse extends BaseResponse {
@SerializedName(BcfConstants.BIGSWITCH_BCF_DEVICE_ID)
@Param(description = "device id of the BigSwitch BCF Controller")
private String id;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID)
@Param(description = "the physical network to which this BigSwitch Vns belongs to")
@Param(description = "the physical network to which this BigSwitch BCF segment belongs to")
private String physicalNetworkId;
@SerializedName(ApiConstants.PROVIDER)
@Param(description = "name of the provider")
private String providerName;
@SerializedName(VnsConstants.BIGSWITCH_VNS_DEVICE_NAME)
@SerializedName(BcfConstants.BIGSWITCH_BCF_DEVICE_NAME)
@Param(description = "device name")
private String deviceName;
@ -48,12 +51,22 @@ public class BigSwitchVnsDeviceResponse extends BaseResponse {
@Param(description = "the controller Ip address")
private String hostName;
@SerializedName(ApiConstants.USERNAME) @Param(description="the controller username")
private String username;
@SerializedName(ApiConstants.PASSWORD) @Param(description="the controller password")
private String password;
@SerializedName(BcfConstants.BIGSWITCH_BCF_DEVICE_NAT)
@Param(description = "NAT support")
private Boolean nat;
public String getId() {
return this.id;
}
public void setId(String vnsDeviceId) {
this.id = vnsDeviceId;
public void setId(String bcfDeviceId) {
this.id = bcfDeviceId;
}
public void setPhysicalNetworkId(String physicalNetworkId) {
@ -71,4 +84,16 @@ public class BigSwitchVnsDeviceResponse extends BaseResponse {
public void setHostName(String hostName) {
this.hostName = hostName;
}
public void setUserName(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setNat(Boolean nat) {
this.nat = nat;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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;
@ -28,8 +31,8 @@ import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name = "external_bigswitch_vns_devices")
public class BigSwitchVnsDeviceVO implements InternalIdentity {
@Table(name = "external_bigswitch_bcf_devices")
public class BigSwitchBcfDeviceVO implements InternalIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ -51,17 +54,38 @@ public class BigSwitchVnsDeviceVO implements InternalIdentity {
@Column(name = "device_name")
private String deviceName;
public BigSwitchVnsDeviceVO() {
@Column(name = "hostname")
private String hostName;
@Column(name = "username")
private String userName;
@Column(name = "password")
private String password;
@Column(name = "nat")
private Boolean nat;
@Column(name = "hash")
private String hash;
public BigSwitchBcfDeviceVO() {
this.uuid = UUID.randomUUID().toString();
}
public BigSwitchVnsDeviceVO(long hostId, long physicalNetworkId, String providerName, String deviceName) {
public BigSwitchBcfDeviceVO(long hostId, long physicalNetworkId, String providerName, String deviceName,
String hostName, String username, String password, Boolean nat, String hash) {
super();
this.hostId = hostId;
this.physicalNetworkId = physicalNetworkId;
this.providerName = providerName;
this.deviceName = deviceName;
this.uuid = UUID.randomUUID().toString();
this.hostName = hostName;
this.userName = username;
this.password = password;
this.nat = nat;
this.hash = hash;
}
@Override
@ -93,4 +117,27 @@ public class BigSwitchVnsDeviceVO implements InternalIdentity {
return deviceName;
}
public String getHash() {
return hash;
}
public void setHash(String h) {
hash = h;
}
public String getHostName() {
return hostName;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public Boolean getNat() {
return nat;
}
}

View File

@ -0,0 +1,114 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import com.cloud.network.vpc.NetworkACLItem;
import com.google.gson.annotations.SerializedName;
/**
* AclData contains information expected by Big Switch Controller
* in ApplyBcfAclCommand
*/
public class AclData {
@SerializedName("id") private String id;
@SerializedName("priority") private int priority;
@SerializedName("action") private String action;
@SerializedName("ipproto") private String ipProto;
@SerializedName("source") private AclNetwork source;
@SerializedName("destination") private AclNetwork destination;
public AclData(){
this.id = null;
this.priority = 0;
this.action = null;
this.ipProto = null;
this.source = new AclNetwork();
this.destination = new AclNetwork();;
}
public class AclNetwork{
@SerializedName("cidr") private String cidr;
@SerializedName("port") private Integer port;
public AclNetwork(){
this.cidr = null;
this.port = null;
}
public AclNetwork(String cidr, Integer port){
this.cidr = cidr;
this.port = port;
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getAction() {
return action;
}
public void setAction(String action) {
if(action.equalsIgnoreCase(NetworkACLItem.Action.Allow.name())){
this.action = "permit";
} else {
this.action = "deny";
}
}
public String getIpProto() {
return ipProto;
}
public void setIpProto(String ipProto) {
if (!ipProto.equalsIgnoreCase("all")){
switch(ipProto.toLowerCase()){
case "tcp":
this.ipProto = "6";
break;
case "udp":
this.ipProto = "17";
break;
case "icmp":
this.ipProto = "1";
break;
}
}
}
public AclNetwork getSource() {
return source;
}
public void setSource(AclNetwork source) {
this.source = source;
}
public AclNetwork getDestination() {
return destination;
}
public void setDestination(AclNetwork destination) {
this.destination = destination;
}
}

View File

@ -0,0 +1,142 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.util.ArrayList;
import com.google.gson.annotations.SerializedName;
/**
* AttachmentData contains information expected by Big Switch Controller
* in CreateBcfAttachmentCommand
*/
public class AttachmentData {
@SerializedName("port") private Attachment attachment;
public Attachment getAttachment() {
return this.attachment;
}
public AttachmentData() {
this.attachment = new Attachment();
}
public class Attachment {
@SerializedName("id") private String id;
@SerializedName("tenant_name") private String tenantName;
@SerializedName("vlan") private Integer vlan;
@SerializedName("fixed_ips") private ArrayList<IpAddress> fixedIps;
@SerializedName("mac_address") private String macAddress;
@SerializedName("bound_segment") private BoundSegment boundSegment;
@SerializedName("binding:host_id") private String hostId;
public Attachment(){
this.boundSegment = new BoundSegment();
this.fixedIps = new ArrayList<IpAddress>();
}
public class BoundSegment {
@SerializedName("segmentation_id") private Integer segmentationId;
public Integer getSegmentationId() {
return segmentationId;
}
public void setSegmentationId(Integer segmentationId) {
this.segmentationId = segmentationId;
}
}
public class IpAddress {
@SerializedName("ip_address") private String ipAddress;
public IpAddress(String ipAddr) {
this.ipAddress = ipAddr;
}
public String getIpAddress(){
return ipAddress;
}
}
private String state;
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getHostId() {
return hostId;
}
public void setHostId(String hostId) {
this.hostId = hostId;
}
public Integer getVlan() {
return vlan;
}
public void setVlan(Integer vlan) {
this.vlan = vlan;
this.boundSegment.setSegmentationId(vlan);
}
public ArrayList<IpAddress> getIpv4List() {
return fixedIps;
}
public void addIpv4(String ipv4) {
this.fixedIps.add(new IpAddress(ipv4));
}
public String getMac() {
return macAddress;
}
public void setMac(String mac) {
this.macAddress = mac;
}
public BoundSegment getBoundSegment() {
return boundSegment;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
}

View File

@ -0,0 +1,459 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.log4j.Logger;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class BigSwitchBcfApi {
private static final Logger s_logger = Logger.getLogger(BigSwitchBcfApi.class);
private final static String s_protocol = "https";
private final static String s_nsBaseUri = "/networkService/v1.1";
private final static String CONTENT_TYPE = "Content-type";
private final static String ACCEPT = "Accept";
private final static String CONTENT_JSON = "application/json";
private final static String HTTP_HEADER_INSTANCE_ID = "Instance-ID";
private final static String CLOUDSTACK_INSTANCE_ID = "cloudstack";
private final static String HASH_MATCH = "X-BSN-BVS-HASH-MATCH";
private final static MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager();
private String _host;
private String _username;
private String _password;
private String _hash;
private String _zoneId;
private Boolean _nat;
private boolean _isMaster = false;
private int _port = 8000;
private HttpClient _client;
private Gson gson = new Gson();
public final static String HASH_CONFLICT = "HASH_CONFLICT";
public final static String HASH_IGNORE = "HASH_IGNORE";
/* This factory method is protected so we can extend this
* in the unittests.
*/
protected HttpClient createHttpClient() {
return new HttpClient(s_httpClientManager);
}
protected HttpMethod createMethod(String type, String uri, int port) throws BigSwitchBcfApiException {
String url;
try {
url = new URL(s_protocol, _host, port, uri).toString();
} catch (MalformedURLException e) {
s_logger.error("Unable to build Big Switch API URL", e);
throw new BigSwitchBcfApiException("Unable to build Big Switch API URL", e);
}
if ("post".equalsIgnoreCase(type)) {
return new PostMethod(url);
} else if ("get".equalsIgnoreCase(type)) {
return new GetMethod(url);
} else if ("delete".equalsIgnoreCase(type)) {
return new DeleteMethod(url);
} else if ("put".equalsIgnoreCase(type)) {
return new PutMethod(url);
} else {
throw new BigSwitchBcfApiException("Requesting unknown method type");
}
}
public BigSwitchBcfApi() {
_client = createHttpClient();
_client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
try {
// Cast to ProtocolSocketFactory to avoid the deprecated constructor with the SecureProtocolSocketFactory parameter
Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) new TrustingProtocolSocketFactory(), _port));
} catch (IOException e) {
s_logger.warn("Failed to register the TrustingProtocolSocketFactory, falling back to default SSLSocketFactory", e);
}
}
/**
* Setter used by UI to set BSN controller address
* @param address
*/
public void setControllerAddress(String address) {
this._host = address;
}
/**
* Setter used by UI to set BSN controller user name
* @param username
*/
public void setControllerUsername(String username) {
this._username = username;
}
/**
* Setter used by UI to set BSN controller password
* @param password
*/
public void setControllerPassword(String password) {
this._password = password;
}
/**
* Setter used by UI to set BSN controller NAT mode
* @param nat
*/
public void setControllerNat(Boolean nat) {
this._nat = nat;
}
public boolean isNatEnabled() {
return this._nat;
}
/**
* Setter used by UI to set BSN controller password
* @param password
*/
public void setZoneId(String zoneId) {
this._zoneId = zoneId;
}
public String createNetwork(NetworkData network) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + network.getNetwork().getTenantId() + "/networks";
return executeCreateObject(network, uri, Collections.<String, String> emptyMap());
}
public String deleteNetwork(String tenantId, String networkId) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId;
return executeDeleteObject(uri);
}
public String createAttachment(String tenantId, String networkId, AttachmentData attachment) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + attachment.getAttachment().getId() + "/attachment";
return executeCreateObject(attachment, uri, Collections.<String, String> emptyMap());
}
public String modifyAttachment(String tenantId, String networkId, AttachmentData attachment) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + attachment.getAttachment().getId() + "/attachment";
return executeUpdateObject(attachment, uri, Collections.<String, String> emptyMap());
}
public String deleteAttachment(String tenantId, String networkId, String attachmentId) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/networks/" + networkId + "/ports/" + attachmentId + "/attachment";
return executeDeleteObject(uri);
}
public String createRouter(String tenantId, RouterData router) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/routers";
return executeCreateObject(router, uri, Collections.<String, String> emptyMap());
}
public String modifyRouter(String tenantId, RouterData router) throws BigSwitchBcfApiException,
IllegalArgumentException{
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/routers";
return executeCreateObject(router, uri, Collections.<String, String> emptyMap());
}
public String createRouterInterface(String tenantId, String routerId, RouterInterfaceData routerInterface) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/routers/" + routerId + "/interfaces";
return executeCreateObject(routerInterface, uri, Collections.<String, String> emptyMap());
}
public String createFloatingIp(String tenantId, FloatingIpData fip) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/floatingips";
return executeCreateObject(fip, uri, Collections.<String, String> emptyMap());
}
public String deleteFloatingIp(String tenantId, String fipId) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/tenants/" + tenantId + "/floatingips/" + fipId;
return executeDeleteObject(uri);
}
public ControlClusterStatus getControlClusterStatus() throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/health";
ControlClusterStatus ccs = executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), uri, null);
ccs.setStatus(true);
return ccs;
}
public Capabilities getCapabilities() throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/capabilities";
List<String> capslist = executeRetrieveObject(new TypeToken<List<String>>() {
}.getType(), uri, null);
Capabilities caps = new Capabilities();
caps.setCapabilities(capslist);
return caps;
}
public String syncTopology(TopologyData topo) throws BigSwitchBcfApiException {
String uri = s_nsBaseUri + "/topology";
return executeCreateObject(topo, uri, Collections.<String, String> emptyMap());
}
public ControllerData getControllerData() {
return new ControllerData(_host, _isMaster);
}
private void checkInvariants() throws BigSwitchBcfApiException{
if (_host == null || _host.isEmpty()) {
throw new BigSwitchBcfApiException("Hostname is null or empty");
}
if (_username == null || _username.isEmpty()){
throw new BigSwitchBcfApiException("Username is null or empty");
}
if (_password == null || _password.isEmpty()){
throw new BigSwitchBcfApiException("Password is null or empty");
}
}
private String checkResponse(HttpMethodBase m, String errorMessageBase) throws BigSwitchBcfApiException,
IllegalArgumentException{
String customErrorMsg = null;
if (m.getStatusCode() == HttpStatus.SC_OK) {
String hash = "";
if (m.getResponseHeader(HASH_MATCH) != null) {
hash = m.getResponseHeader(HASH_MATCH).getValue();
set_hash(hash);
}
return hash;
}
if (m.getStatusCode() == HttpStatus.SC_CONFLICT) {
if(m instanceof GetMethod) {
return HASH_CONFLICT;
}
throw new BigSwitchBcfApiException("BCF topology sync required", true);
}
if (m.getStatusCode() == HttpStatus.SC_SEE_OTHER) {
_isMaster = false;
set_hash(HASH_IGNORE);
return HASH_IGNORE;
}
if (m.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
if (m instanceof DeleteMethod){
return "";
}
}
if (m.getStatusCode() == HttpStatus.SC_BAD_REQUEST) {
customErrorMsg = " Invalid data in BCF request";
throw new IllegalArgumentException(customErrorMsg);
}
String errorMessage = responseToErrorMessage(m);
m.releaseConnection();
s_logger.error(errorMessageBase + errorMessage);
throw new BigSwitchBcfApiException(errorMessageBase + errorMessage + customErrorMsg);
}
private void setHttpHeader(HttpMethodBase m) {
m.setRequestHeader(CONTENT_TYPE, CONTENT_JSON);
m.setRequestHeader(ACCEPT, CONTENT_JSON);
m.setRequestHeader(HTTP_HEADER_INSTANCE_ID, CLOUDSTACK_INSTANCE_ID + "-" + _zoneId);
if (_hash != "" ) {
m.setRequestHeader(HASH_MATCH, _hash);
}
String authString = _username + ":" + _password;
String encodedAuthString = "Basic " + Base64.encodeBase64String(authString.getBytes(Charset.forName("UTF-8")));
m.setRequestHeader("Authorization", encodedAuthString);
}
protected <T> String executeUpdateObject(T newObject, String uri, Map<String, String> parameters) throws BigSwitchBcfApiException,
IllegalArgumentException{
checkInvariants();
PutMethod pm = (PutMethod)createMethod("put", uri, _port);
setHttpHeader(pm);
try {
pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), CONTENT_JSON, null));
} catch (UnsupportedEncodingException e) {
throw new BigSwitchBcfApiException("Failed to encode json request body", e);
}
executeMethod(pm);
String hash = checkResponse(pm, "BigSwitch HTTP update failed: ");
pm.releaseConnection();
return hash;
}
protected <T> String executeCreateObject(T newObject, String uri, Map<String, String> parameters) throws BigSwitchBcfApiException {
checkInvariants();
PostMethod pm = (PostMethod)createMethod("post", uri, _port);
setHttpHeader(pm);
try {
pm.setRequestEntity(new StringRequestEntity(gson.toJson(newObject), CONTENT_JSON, null));
} catch (UnsupportedEncodingException e) {
throw new BigSwitchBcfApiException("Failed to encode json request body", e);
}
executeMethod(pm);
String hash = checkResponse(pm, "BigSwitch HTTP create failed: ");
pm.releaseConnection();
return hash;
}
protected String executeDeleteObject(String uri) throws BigSwitchBcfApiException {
checkInvariants();
DeleteMethod dm = (DeleteMethod)createMethod("delete", uri, _port);
setHttpHeader(dm);
executeMethod(dm);
String hash = checkResponse(dm, "BigSwitch HTTP delete failed: ");
dm.releaseConnection();
return hash;
}
@SuppressWarnings("unchecked")
protected <T> T executeRetrieveObject(Type returnObjectType,
String uri, Map<String, String> parameters) throws BigSwitchBcfApiException {
checkInvariants();
GetMethod gm = (GetMethod)createMethod("get", uri, _port);
setHttpHeader(gm);
if (parameters != null && !parameters.isEmpty()) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(parameters.size());
for (Entry<String, String> e : parameters.entrySet()) {
nameValuePairs.add(new NameValuePair(e.getKey(), e.getValue()));
}
gm.setQueryString(nameValuePairs.toArray(new NameValuePair[0]));
}
executeMethod(gm);
String hash = checkResponse(gm, "BigSwitch HTTP get failed: ");
T returnValue;
try {
// CAUTIOUS: Safety margin of 2048 characters - extend if needed.
returnValue = (T)gson.fromJson(gm.getResponseBodyAsString(2048), returnObjectType);
} catch (IOException e) {
s_logger.error("IOException while retrieving response body", e);
throw new BigSwitchBcfApiException(e);
} finally {
gm.releaseConnection();
}
if(returnValue instanceof ControlClusterStatus) {
if(hash == HASH_CONFLICT) {
_isMaster = true;
((ControlClusterStatus) returnValue).setTopologySyncRequested(true);
} else if (hash != HASH_IGNORE && !_isMaster) {
_isMaster = true;
((ControlClusterStatus) returnValue).setTopologySyncRequested(true);
}
}
return returnValue;
}
protected void executeMethod(HttpMethodBase method) throws BigSwitchBcfApiException {
try {
_client.executeMethod(method);
if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
method.releaseConnection();
}
} catch (HttpException e) {
s_logger.error("HttpException caught while trying to connect to the BigSwitch Controller", e);
method.releaseConnection();
throw new BigSwitchBcfApiException("API call to BigSwitch Controller Failed", e);
} catch (IOException e) {
s_logger.error("IOException caught while trying to connect to the BigSwitch Controller", e);
method.releaseConnection();
throw new BigSwitchBcfApiException("API call to BigSwitch Controller Failed", e);
}
}
private String responseToErrorMessage(HttpMethodBase method) {
assert method.isRequestSent() : "no use getting an error message unless the request is sent";
if ("text/html".equals(method.getResponseHeader(CONTENT_TYPE).getValue())) {
// The error message is the response content
// Safety margin of 2048 characters, anything longer is probably useless
// and will clutter the logs
try {
return method.getResponseBodyAsString(2048);
} catch (IOException e) {
s_logger.debug("Error while loading response body", e);
}
}
// The default
return method.getStatusText();
}
public static String getCloudstackInstanceId() {
return CLOUDSTACK_INSTANCE_ID;
}
public String get_hash() {
return _hash;
}
public void set_hash(String hash) {
this._hash = hash;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,37 +15,41 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
public class AttachmentData {
private Attachment attachment;
public class BigSwitchBcfApiException extends Exception {
public Attachment getAttachment() {
return attachment;
private static final long serialVersionUID = -5864952230870945604L;
private boolean topologySyncRequested = false;
public BigSwitchBcfApiException() {
}
public AttachmentData() {
this.attachment = new Attachment();
public BigSwitchBcfApiException(String message) {
super(message);
}
public class Attachment {
private String id;
private String mac;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
public BigSwitchBcfApiException(Throwable cause) {
super(cause);
}
public BigSwitchBcfApiException(String message, Throwable cause) {
super(message, cause);
}
public BigSwitchBcfApiException(String message, boolean syncRequest) {
super(message);
this.set_topologySyncRequested(syncRequest);
}
public boolean is_topologySyncRequested() {
return topologySyncRequested;
}
public void set_topologySyncRequested(boolean requested) {
this.topologySyncRequested = requested;
}
}

View File

@ -0,0 +1,571 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.util.SubnetUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.util.IPAddress;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.BcfAnswer;
import com.cloud.agent.api.BcfCommand;
import com.cloud.agent.api.CacheBcfTopologyCommand;
import com.cloud.agent.api.GetControllerDataAnswer;
import com.cloud.agent.api.GetControllerDataCommand;
import com.cloud.agent.api.SyncBcfTopologyCommand;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.bigswitch.TopologyData.Port;
import com.cloud.network.dao.BigSwitchBcfDao;
import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesCidrsVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.NetworkACLItemCidrsDao;
import com.cloud.network.vpc.NetworkACLItemCidrsVO;
import com.cloud.network.vpc.NetworkACLItemDao;
import com.cloud.network.vpc.NetworkACLItemVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.VMInstanceDao;
public class BigSwitchBcfUtils {
private static final Logger s_logger = Logger.getLogger(BigSwitchBcfUtils.class);
private final NetworkDao _networkDao;
private final NicDao _nicDao;
private final VMInstanceDao _vmDao;
private final HostDao _hostDao;
private final VpcDao _vpcDao;
private final BigSwitchBcfDao _bigswitchBcfDao;
private final AgentManager _agentMgr;
private final VlanDao _vlanDao;
private final IPAddressDao _ipAddressDao;
private final FirewallRulesDao _fwRulesDao;
private final FirewallRulesCidrsDao _fwCidrsDao;
private final NetworkACLItemDao _aclItemDao;
private final NetworkACLItemCidrsDao _aclItemCidrsDao;
private final NetworkModel _networkModel;
public BigSwitchBcfUtils(NetworkDao networkDao,
NicDao nicDao, VMInstanceDao vmDao, HostDao hostDao,
VpcDao vpcDao, BigSwitchBcfDao bigswitchBcfDao,
AgentManager agentMgr, VlanDao vlanDao, IPAddressDao ipAddressDao,
FirewallRulesDao fwRulesDao, FirewallRulesCidrsDao fwCidrsDao,
NetworkACLItemDao aclItemDao, NetworkACLItemCidrsDao aclItemCidrsDao,
NetworkModel networkModel){
_networkDao = networkDao;
_nicDao = nicDao;
_vmDao = vmDao;
_hostDao = hostDao;
_vpcDao = vpcDao;
_bigswitchBcfDao = bigswitchBcfDao;
_agentMgr = agentMgr;
_vlanDao = vlanDao;
_ipAddressDao = ipAddressDao;
_fwRulesDao = fwRulesDao;
_fwCidrsDao = fwCidrsDao;
_aclItemDao = aclItemDao;
_aclItemCidrsDao = aclItemCidrsDao;
_networkModel = networkModel;
}
public ControlClusterData getControlClusterData(long physicalNetworkId){
ControlClusterData cluster = new ControlClusterData();
// reusable command to query all devices
GetControllerDataCommand cmd = new GetControllerDataCommand();
// retrieve all registered BCF devices
List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listByPhysicalNetwork(physicalNetworkId);
for (BigSwitchBcfDeviceVO d: devices){
HostVO bigswitchBcfHost = _hostDao.findById(d.getHostId());
if (bigswitchBcfHost == null){
continue;
}
_hostDao.loadDetails(bigswitchBcfHost);
GetControllerDataAnswer answer = (GetControllerDataAnswer) _agentMgr.easySend(bigswitchBcfHost.getId(), cmd);
if (answer != null){
if (answer.isMaster()) {
cluster.setMaster(bigswitchBcfHost);
} else {
cluster.setSlave(bigswitchBcfHost);
}
}
}
return cluster;
}
public TopologyData getTopology(){
long physicalNetworkId;
List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listAll();
if(!devices.isEmpty()){
physicalNetworkId = devices.get(0).getPhysicalNetworkId();
return getTopology(physicalNetworkId);
} else {
return null;
}
}
public NetworkVO getPublicNetwork(long physicalNetworkId){
List<NetworkVO> pubNets = _networkDao.listByPhysicalNetworkTrafficType(physicalNetworkId, TrafficType.Public);
return pubNets.get(0);
}
public TopologyData getTopology(long physicalNetworkId){
List<NetworkVO> networks;
List<NicVO> nics;
networks = _networkDao.listByPhysicalNetworkTrafficType(physicalNetworkId, TrafficType.Guest);
TopologyData topo = new TopologyData();
// networks:
// - all user created networks (VPC or non-VPC)
// - one external network
// routers:
// - per VPC (handle in network loop)
// - per stand-alone network (handle in network loop)
// - one external router
// handle external network first, only if NAT service is enabled
if(networks != null) {
if(!(networks.isEmpty()) && isNatEnabled()!=null && isNatEnabled()){
// get public net info - needed to set up source nat gateway
NetworkVO pubNet = getPublicNetwork(physicalNetworkId);
// locate subnet info
SearchCriteria<VlanVO> sc = _vlanDao.createSearchCriteria();
sc.setParameters("network_id", pubNet.getId());
VlanVO vlanVO = _vlanDao.findOneBy(sc);
// add tenant external network external
TopologyData.Network network = topo.new Network();
network.setId("external");
network.setName("external");
network.setTenantId("external");
network.setTenantName("external");
String pubVlan = null;
try {
pubVlan = BroadcastDomainType.getValue(vlanVO.getVlanTag());
if(StringUtils.isNumeric(pubVlan)){
network.setVlan(Integer.valueOf(pubVlan));
} else {
// untagged
pubVlan = "0";
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
topo.addNetwork(network);
}
}
// routerMap used internally for multiple updates to same tenant's router
// add back to topo.routers after loop
HashMap<String, RouterData> routerMap = new HashMap<String, RouterData>();
for (NetworkVO netVO: networks){
TopologyData.Network network = topo.new Network();
network.setId(netVO.getUuid());
network.setName(netVO.getName());
Integer vlan = null;
if (netVO.getBroadcastUri() != null) {
String vlanStr = BroadcastDomainType.getValue(netVO.getBroadcastUri());
if(StringUtils.isNumeric(vlanStr)){
vlan = Integer.valueOf(vlanStr);
} else {
// untagged
vlan = 0;
}
}
network.setVlan(vlan);
network.setState(netVO.getState().name());
nics = _nicDao.listByNetworkId(netVO.getId());
List<Port> ports = new ArrayList<Port>();
String tenantId = null;
String tenantName = null;
// if VPC network, assign BCF tenant id with vpc uuid
Vpc vpc = null;
if(netVO.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(netVO.getVpcId());
}
if (vpc != null) {
tenantId = vpc.getUuid();
tenantName = vpc.getName();
} else {
tenantId = netVO.getUuid();
tenantName = netVO.getName();
}
for(NicVO nic: nics){
NetworkData netData = new NetworkData();
TopologyData.Port p = topo.new Port();
p.setAttachmentInfo(netData.new AttachmentInfo(nic.getUuid(),nic.getMacAddress()));
VMInstanceVO vm = _vmDao.findById(nic.getInstanceId());
HostVO host = _hostDao.findById(vm.getHostId());
// if host not found, ignore this nic
if (host == null) {
continue;
}
String hostname = host.getName();
long zoneId = netVO.getDataCenterId();
String vmwareVswitchLabel = _networkModel.getDefaultGuestTrafficLabel(zoneId, HypervisorType.VMware);
String[] labelArray = null;
String vswitchName = null;
if(vmwareVswitchLabel!=null){
labelArray=vmwareVswitchLabel.split(",");
vswitchName = labelArray[0];
}
// hypervisor type:
// kvm: ivs port name
// vmware: specific portgroup naming convention
String pgName = "";
if (host.getHypervisorType() == HypervisorType.KVM){
pgName = hostname;
} else if (host.getHypervisorType() == HypervisorType.VMware){
pgName = hostname + "-" + vswitchName;
}
p.setHostId(pgName);
p.setSegmentInfo(netData.new SegmentInfo(BroadcastDomainType.Vlan.name(), vlan));
p.setOwner(BigSwitchBcfApi.getCloudstackInstanceId());
List<AttachmentData.Attachment.IpAddress> ipList = new ArrayList<AttachmentData.Attachment.IpAddress>();
ipList.add(new AttachmentData().getAttachment().new IpAddress(nic.getIp4Address()));
p.setIpAddresses(ipList);
p.setId(nic.getUuid());
p.setMac(nic.getMacAddress());
netData.getNetwork().setId(network.getId());
netData.getNetwork().setName(network.getName());
netData.getNetwork().setTenantId(tenantId);
netData.getNetwork().setTenantName(tenantName);
netData.getNetwork().setState(netVO.getState().name());
p.setNetwork(netData.getNetwork());
ports.add(p);
}
network.setTenantId(tenantId);
network.setTenantName(tenantName);
network.setPorts(ports);
topo.addNetwork(network);
// add router for network
RouterData routerData;
if(tenantId != null){
if(!routerMap.containsKey(tenantId)){
routerData = new RouterData(tenantId);
routerMap.put(tenantId, routerData);
} else {
routerData = routerMap.get(tenantId);
}
routerData.getRouter().getAcls().addAll(listACLbyNetwork(netVO));
if(vpc != null){
routerData.getRouter().addExternalGateway(getPublicIpByVpc(vpc));
} else {
routerData.getRouter().addExternalGateway(getPublicIpByNetwork(netVO));
}
RouterInterfaceData intf = new RouterInterfaceData(tenantId, netVO.getGateway(), netVO.getCidr(),
netVO.getUuid(), netVO.getName());
routerData.getRouter().addInterface(intf);
}
}
for(RouterData rd: routerMap.values()) {
topo.addRouter(rd.getRouter());
}
return topo;
}
public String getPublicIpByNetwork(Network network){
List<IPAddressVO> allocatedIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), true);
for (IPAddressVO ip: allocatedIps){
if(ip.isSourceNat()){
return ip.getAddress().addr();
}
}
return null;
}
public String getPublicIpByVpc(Vpc vpc){
List<IPAddressVO> allocatedIps = _ipAddressDao.listByAssociatedVpc(vpc.getId(), true);
for (IPAddressVO ip: allocatedIps){
if(ip.isSourceNat()){
return ip.getAddress().addr();
}
}
return null;
}
public List<AclData> listACLbyNetwork(Network network){
List<AclData> aclList = new ArrayList<AclData>();
List<FirewallRuleVO> fwRules;
fwRules = _fwRulesDao.listByNetworkAndPurposeAndNotRevoked(network.getId(), Purpose.Firewall);
List<FirewallRulesCidrsVO> fwCidrList = null;
SubnetUtils utils;
for(FirewallRuleVO rule: fwRules){
AclData acl = new AclData();
acl.setId(rule.getUuid());
acl.setPriority((int)rule.getId()); // CloudStack Firewall interface does not have priority
acl.setIpProto(rule.getProtocol());
String cidr = null;
Integer port = rule.getSourcePortStart();
fwCidrList = _fwCidrsDao.listByFirewallRuleId(rule.getId());
if(fwCidrList != null){
if(fwCidrList.size()>1 || rule.getSourcePortEnd()!=port){
continue;
} else {
cidr = fwCidrList.get(0).getCidr();
}
}
if (cidr == null || cidr.equalsIgnoreCase("0.0.0.0/0")) {
cidr = "";
} else {
utils = new SubnetUtils(cidr);
if(!utils.getInfo().getNetworkAddress().equals(utils.getInfo().getAddress())){
continue;
}
}
acl.setSource(acl.new AclNetwork(cidr, port));
acl.setAction("permit");
aclList.add(acl);
}
List<NetworkACLItemVO> aclItems;
List<NetworkACLItemCidrsVO> aclCidrList;
if (network.getNetworkACLId() != null){
aclItems = _aclItemDao.listByACL(network.getNetworkACLId());
for(NetworkACLItem item: aclItems){
AclData acl = new AclData();
acl.setId(item.getUuid());
acl.setPriority(item.getNumber());
acl.setIpProto(item.getProtocol());
String cidr = null; // currently BCF supports single cidr policy
Integer port = item.getSourcePortStart(); // currently BCF supports single port policy
aclCidrList = _aclItemCidrsDao.listByNetworkACLItemId(item.getId());
if(aclCidrList != null){
if(aclCidrList.size()>1 || item.getSourcePortEnd()!=port){
continue;
} else {
cidr = aclCidrList.get(0).getCidr();
}
}
if (cidr == null || cidr.equalsIgnoreCase("0.0.0.0/0")) {
cidr = "";
} else {
utils = new SubnetUtils(cidr);
if(!utils.getInfo().getNetworkAddress().equals(utils.getInfo().getAddress())){
continue;
}
}
acl.setSource(acl.new AclNetwork(cidr, port));
acl.setAction(item.getAction().name());
aclList.add(acl);
}
}
return aclList;
}
public String syncTopologyToBcfHost(HostVO bigswitchBcfHost){
SyncBcfTopologyCommand syncCmd;
if(isNatEnabled()!=null && isNatEnabled()){
syncCmd = new SyncBcfTopologyCommand(true, true);
} else {
syncCmd = new SyncBcfTopologyCommand(true, false);
}
BcfAnswer syncAnswer = (BcfAnswer) _agentMgr.easySend(bigswitchBcfHost.getId(), syncCmd);
if (syncAnswer == null || !syncAnswer.getResult()) {
s_logger.error("SyncBcfTopologyCommand failed");
return null;
}
return syncAnswer.getHash();
}
public String syncTopologyToBcfHost(HostVO bigswitchBcfHost, boolean natEnabled){
SyncBcfTopologyCommand syncCmd;
if(natEnabled){
syncCmd = new SyncBcfTopologyCommand(true, true);
} else {
syncCmd = new SyncBcfTopologyCommand(true, false);
}
BcfAnswer syncAnswer = (BcfAnswer) _agentMgr.easySend(bigswitchBcfHost.getId(), syncCmd);
if (syncAnswer == null || !syncAnswer.getResult()) {
s_logger.error("SyncBcfTopologyCommand failed");
return null;
}
return syncAnswer.getHash();
}
public BcfAnswer sendBcfCommandWithNetworkSyncCheck(BcfCommand cmd, Network network)throws IllegalArgumentException{
// get registered Big Switch controller
ControlClusterData cluster = getControlClusterData(network.getPhysicalNetworkId());
if(cluster.getMaster()==null){
return new BcfAnswer(cmd, new CloudRuntimeException("Big Switch Network controller temporarily unavailable"));
}
TopologyData topo = getTopology(network.getPhysicalNetworkId());
cmd.setTopology(topo);
BcfAnswer answer = (BcfAnswer) _agentMgr.easySend(cluster.getMaster().getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error ("BCF API Command failed");
throw new IllegalArgumentException("Failed API call to Big Switch Network plugin");
}
String newHash = answer.getHash();
if (cmd.is_topologySyncRequested()) {
newHash = syncTopologyToBcfHost(cluster.getMaster());
}
if(newHash != null){
commitTopologyHash(network.getPhysicalNetworkId(), newHash);
}
HostVO slave = cluster.getSlave();
if(slave != null){
TopologyData newTopo = getTopology(network.getPhysicalNetworkId());
CacheBcfTopologyCommand cacheCmd = new CacheBcfTopologyCommand(newTopo);
_agentMgr.easySend(cluster.getSlave().getId(), cacheCmd);
}
return answer;
}
@DB
public Boolean commitTopologyHash(long physicalNetworkId, final String hash) {
final List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listByPhysicalNetwork(physicalNetworkId);
return Transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
for (BigSwitchBcfDeviceVO d: devices){
d.setHash(hash);
_bigswitchBcfDao.update(d.getId(), d);
}
return true;
}
});
}
public Boolean isNatEnabled(){
List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listAll();
if(devices != null && !devices.isEmpty()){
return devices.get(0).getNat();
} else {
return null;
}
}
public Integer getSubnetMaskLength(String maskString){
if(!IPAddress.isValidIPv4(maskString)){
return null;
}
String[] octets = maskString.split(".");
Integer bits = 0;
for (String o: octets){
switch(o){
case "255":
bits += 8;
continue;
case "254":
bits += 7;
return bits;
case "252":
bits += 6;
return bits;
case "248":
bits += 5;
return bits;
case "240":
bits += 4;
return bits;
case "224":
bits += 3;
return bits;
case "192":
bits += 2;
return bits;
case "128":
bits += 1;
return bits;
case "0":
return bits;
default:
throw new NumberFormatException("non-contiguous subnet mask not supported");
}
}
return bits;
}
}

View File

@ -0,0 +1,32 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
public class BigSwitchStatus {
private boolean topologySyncRequested = false;
public boolean isTopologySyncRequested() {
return topologySyncRequested;
}
public void setTopologySyncRequested(boolean topologySyncRequested) {
this.topologySyncRequested = topologySyncRequested;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,16 +15,20 @@
// 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 DeleteVnsNetworkAnswer extends Answer {
package com.cloud.network.bigswitch;
public DeleteVnsNetworkAnswer(Command command, boolean success, String details) {
super(command, success, details);
import java.util.List;
public class Capabilities extends BigSwitchStatus {
private List<String> capabilities;
public List<String> getCapabilities() {
return capabilities;
}
public DeleteVnsNetworkAnswer(Command command, Exception e) {
super(command, e);
public void setCapabilities(List<String> caps) {
capabilities = caps;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,25 +15,29 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
public class BigSwitchVnsApiException extends Exception {
import com.cloud.host.HostVO;
private static final long serialVersionUID = -5864952230870945604L;
public class ControlClusterData {
private HostVO master;
private HostVO slave;
public BigSwitchVnsApiException() {
public HostVO getMaster() {
return master;
}
public BigSwitchVnsApiException(String message) {
super(message);
public void setMaster(HostVO master) {
this.master = master;
}
public BigSwitchVnsApiException(Throwable cause) {
super(cause);
public HostVO getSlave() {
return slave;
}
public BigSwitchVnsApiException(String message, Throwable cause) {
super(message, cause);
public void setSlave(HostVO slave) {
this.slave = slave;
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,9 +15,11 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
public class ControlClusterStatus {
public class ControlClusterStatus extends BigSwitchStatus {
private boolean healthy;
public boolean getStatus() {

View File

@ -0,0 +1,39 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
public class ControllerData {
private final String ipAddress;
private final boolean isMaster;
public ControllerData(String ipAddress, boolean isMaster) {
this.ipAddress = ipAddress;
this.isMaster = isMaster;
}
public String getIpAddress() {
return ipAddress;
}
public boolean isMaster() {
return isMaster;
}
}

View File

@ -0,0 +1,93 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import com.google.gson.annotations.SerializedName;
public class FloatingIpData {
@SerializedName("router_id") private String routerId;
@SerializedName("tenant_id") private String tenantId;
@SerializedName("floating_network_id") private String networkId;
@SerializedName("fixed_ip_address") private String fixedIp;
@SerializedName("floating_ip_address") private String floatingIp;
@SerializedName("floating_mac_address") private String mac;
@SerializedName("id") private String id;
public FloatingIpData(){
this.mac = null;
}
public String getRouterId() {
return routerId;
}
public void setRouterId(String routerId) {
this.routerId = routerId;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getNetworkId() {
return networkId;
}
public void setNetworkId(String networkId) {
this.networkId = networkId;
}
public String getFixedIp() {
return fixedIp;
}
public void setFixedIp(String fixedIp) {
this.fixedIp = fixedIp;
}
public String getFloatingIp() {
return floatingIp;
}
/***
* current implementation auto-generates id using public ip
* replacing "." with "-"
***/
public void setFloatingIpAndId(String floatingIp) {
this.floatingIp = floatingIp;
this.id = floatingIp.replace(".", "-");
}
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
public String getId() {
return id;
}
}

View File

@ -0,0 +1,217 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.util.List;
import com.google.gson.annotations.SerializedName;
/**
* NetworkData contains information expected by Big Switch Controller
* in CreateBcfSegmentCommand
*/
public class NetworkData {
private final Network network;
public Network getNetwork() {
return network;
}
public NetworkData() {
network = new Network();
}
public class Network {
@SerializedName("id") private String id;
@SerializedName("name") private String name = null;
@SerializedName("tenant_id") private String tenantId = null;
@SerializedName("tenant_name") private String tenantName = null;
@SerializedName("state") private String state = null;
@SerializedName("subnets") private List<Segment> segments = null;
@SerializedName("provider:segmentation_id") private Integer vlan = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public List<Segment> getSegments() {
return segments;
}
public void setSegments(List<Segment> segments) {
this.segments = segments;
}
public Integer getVlan() {
return vlan;
}
public void setVlan(Integer vlan) {
this.vlan = vlan;
}
}
public class Segment {
@SerializedName("cidr") private String cidr;
@SerializedName("gateway_ip") private String gatewayIp;
@SerializedName("id") private String id;
@SerializedName("name") private String name;
@SerializedName("state") private String state;
@SerializedName("tenant_id") private String tenantId;
public String getCidr() {
return cidr;
}
public void setCidr(String cidr) {
this.cidr = cidr;
}
public String getGatewayIp() {
return gatewayIp;
}
public void setGatewayIp(String gatewayIp) {
this.gatewayIp = gatewayIp;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
}
public class AttachmentInfo {
@SerializedName("id") private String id = null;
@SerializedName("mac") private String mac = null;
public AttachmentInfo(String id, String mac){
this.id = id;
this.mac = mac;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
}
public class SegmentInfo {
@SerializedName("network_type") private String networkType = null;
@SerializedName("segmentation_id") private Integer segmentationId = 0;
public SegmentInfo(String networkType, Integer segmentationId){
this.networkType = networkType;
this.segmentationId = segmentationId;
}
public String getNetworkType() {
return networkType;
}
public void setNetworkType(String networkType) {
this.networkType = networkType;
}
public Integer getSegmentationId() {
return segmentationId;
}
public void setSegmentationId(Integer segmentationId) {
this.segmentationId = segmentationId;
}
}
}

View File

@ -0,0 +1,131 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class RouterData {
@SerializedName("router") private Router router;
public RouterData(String tenantId){
router = new Router(tenantId);
}
public class Router {
@SerializedName("tenant_id") private String tenantId;
@SerializedName("id") private String id;
@SerializedName("external_gateway_info") private ExternalGateway externalGateway;
@SerializedName("router_rules") private List<AclData> acls;
@SerializedName("interfaces") private List<RouterInterfaceData.RouterInterface> interfaces;
public Router(String tenantId){
this.tenantId = tenantId;
this.id = tenantId;
this.externalGateway = null;
this.acls = new ArrayList<AclData>();
this.interfaces = null;
}
public List<AclData> getAcls() {
return acls;
}
public class ExternalGateway{
@SerializedName("tenant_id") private String tenantId;
@SerializedName("network_id") private String networkId;
@SerializedName("external_fixed_ips") private List<ExternalIp> externalIps;
public ExternalGateway(String gatewayIp){
this.tenantId = "external";
this.networkId = "external";
this.externalIps = new ArrayList<ExternalIp>();
if(gatewayIp!=null){
this.externalIps.add(new ExternalIp(gatewayIp));
}
}
public class ExternalIp{
@SerializedName("subnet_id") private String subnetId; //assume don't care for now
@SerializedName("ip_address") private String ipAddress;
public ExternalIp(String ipAddress){
this.subnetId = "";
this.ipAddress = ipAddress;
}
public String getSubnetId() {
return subnetId;
}
public String getIpAddress() {
return ipAddress;
}
}
public String getNetworkId() {
return networkId;
}
public List<ExternalIp> getExternalIps() {
return externalIps;
}
}
public void addExternalGateway(String gatewayIp){
if(gatewayIp != null){
this.externalGateway = new ExternalGateway(gatewayIp);
}
}
public String getTenantId() {
return tenantId;
}
public String getId() {
return id;
}
public ExternalGateway getExternalGateway() {
return externalGateway;
}
public List<RouterInterfaceData.RouterInterface> getInterfaces() {
return interfaces;
}
public void addInterface(RouterInterfaceData intf){
if(this.interfaces == null){
this.interfaces = new ArrayList<RouterInterfaceData.RouterInterface>();
}
this.interfaces.add(intf.getRouterInterface());
}
public void setInterfaces(List<RouterInterfaceData.RouterInterface> interfaces) {
this.interfaces = interfaces;
}
}
public Router getRouter() {
return router;
}
}

View File

@ -0,0 +1,67 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import com.google.gson.annotations.SerializedName;
public class RouterInterfaceData {
@SerializedName("interface") private RouterInterface routerInterface;
public RouterInterfaceData(String tenantId, String gatewayIp, String cidr, String id, String name){
routerInterface = new RouterInterface(tenantId, gatewayIp, cidr, id, name);
}
public class RouterInterface {
@SerializedName("subnet") private NetworkData.Segment subnet;
@SerializedName("id") private String id;
@SerializedName("network") private NetworkData.Network network;
public RouterInterface(String tenantId, String gatewayIp, String cidr, String id, String name){
NetworkData data = new NetworkData();
this.subnet = data.new Segment();
this.subnet.setTenantId(tenantId);
this.subnet.setGatewayIp(gatewayIp);
this.subnet.setCidr(cidr);
this.id = id;
this.network = data.getNetwork();
this.network.setTenantId(tenantId);
this.network.setId(id);
this.network.setName(name);
}
public NetworkData.Segment getSubnet() {
return subnet;
}
public String getId() {
return id;
}
public NetworkData.Network getNetwork() {
return network;
}
}
public RouterInterface getRouterInterface() {
return routerInterface;
}
}

View File

@ -0,0 +1,249 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.util.ArrayList;
import java.util.List;
import com.cloud.network.bigswitch.AttachmentData.Attachment.IpAddress;
import com.cloud.network.bigswitch.NetworkData.AttachmentInfo;
import com.cloud.network.bigswitch.NetworkData.Segment;
import com.cloud.network.bigswitch.NetworkData.SegmentInfo;
import com.cloud.network.bigswitch.RouterData.Router;
import com.google.gson.annotations.SerializedName;
public class TopologyData {
@SerializedName("networks") private final List<Network> networks;
@SerializedName("routers") private final List<Router> routers;
public void addNetwork(Network network) {
networks.add(network);
}
public void setNetworks(List<Network> networks) {
this.networks.clear();
this.networks.addAll(networks);
}
public void clearNetworks() {
this.networks.clear();
}
public void addRouter(Router router) {
routers.add(router);
}
public void setRouters(List<Router> routers) {
this.routers.clear();
this.routers.addAll(routers);
}
public void clearRouters() {
this.routers.clear();
}
public TopologyData() {
networks = new ArrayList<Network>();
routers = new ArrayList<Router>();
}
public class Network {
@SerializedName("id") private String id;
@SerializedName("name") private String name;
@SerializedName("tenant_id") private String tenantId;
@SerializedName("tenant_name") private String tenantName;
@SerializedName("provider:segmentation_id") private Integer vlan = null;
@SerializedName("state") private String state;
@SerializedName("ports") private List<Port> ports;
@SerializedName("subnets") private List<Segment> segments;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
public Integer getVlan() {
return vlan;
}
public void setVlan(Integer vlan) {
this.vlan = vlan;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public List<Port> getPorts() {
return ports;
}
public void setPorts(List<Port> ports) {
this.ports = ports;
}
public List<Segment> getSegments() {
return segments;
}
public void setSegments(List<Segment> segments) {
this.segments = segments;
}
@Override
public String toString() {
return "Network [id=" + id + ", name=" + name + ", tenantId="
+ tenantId + ", tenantName=" + tenantName + ", vlan="
+ vlan + ", state=" + state + ", ports=" + ports
+ ", segments=" + segments + "]";
}
}
public class Port {
@SerializedName("attachment") private AttachmentInfo attachment;
@SerializedName("binding:host_id") private String hostId;
@SerializedName("bound_segment") private SegmentInfo segmentInfo;
@SerializedName("device_owner") private String owner;
@SerializedName("fixed_ips") private List<IpAddress> ipAddresses;
@SerializedName("id") private String id;
@SerializedName("mac_address") private String mac;
@SerializedName("network") private NetworkData.Network network;
@SerializedName("state") private String state;
@SerializedName("tenant_id") private String tenantId;
@SerializedName("tenant_name") private String tenantName;
public AttachmentInfo getAttachment() {
return attachment;
}
public void setAttachmentInfo(AttachmentInfo attachment) {
this.attachment = attachment;
}
public String getHostId() {
return hostId;
}
public void setHostId(String hostId) {
this.hostId = hostId;
}
public SegmentInfo getSegmentInfo() {
return segmentInfo;
}
public void setSegmentInfo(SegmentInfo segmentInfo) {
this.segmentInfo = segmentInfo;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public List<IpAddress> getIpAddresses() {
return ipAddresses;
}
public void setIpAddresses(List<IpAddress> ipAddresses) {
this.ipAddresses = ipAddresses;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
public NetworkData.Network getNetwork() {
return network;
}
public void setNetwork(NetworkData.Network network) {
this.network = network;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getTenantName() {
return tenantName;
}
public void setTenantName(String tenantName) {
this.tenantName = tenantName;
}
}
public List<Network> getNetworks() {
return networks;
}
public List<Router> getRouters() {
return routers;
}
@Override
public String toString() {
return "TopologyData [networks=" + networks + ", routers=" + routers
+ "]";
}
}

View File

@ -0,0 +1,114 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
/*
* The TrustingProtocolSocketFactory will accept any provided
* certificate, i.e., in a sticky mode certificate management scheme,
* when making an SSL connection to the Big Switch Controller
*/
public class TrustingProtocolSocketFactory implements SecureProtocolSocketFactory {
private SSLSocketFactory ssf;
public TrustingProtocolSocketFactory() throws IOException {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Trust always
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Trust always
}
}
};
try {
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
ssf = sc.getSocketFactory();
} catch (KeyManagementException e) {
throw new IOException(e);
} catch (NoSuchAlgorithmException e) {
throw new IOException(e);
}
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return ssf.createSocket(host, port);
}
@Override
public Socket createSocket(String address, int port, InetAddress localAddress,
int localPort) throws IOException, UnknownHostException {
return ssf.createSocket(address, port, localAddress, localPort);
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return ssf.createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress,
int localPort, HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
int timeout = params.getConnectionTimeout();
if (timeout == 0) {
return createSocket(host, port, localAddress, localPort);
}
else {
Socket s = ssf.createSocket();
s.bind(new InetSocketAddress(localAddress, localPort));
s.connect(new InetSocketAddress(host, port), timeout);
return s;
}
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,19 +15,21 @@
// 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 java.util.List;
import com.cloud.network.BigSwitchVnsDeviceVO;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.utils.db.GenericDao;
public interface BigSwitchVnsDao extends GenericDao<BigSwitchVnsDeviceVO, Long> {
public interface BigSwitchBcfDao extends GenericDao<BigSwitchBcfDeviceVO, Long> {
/**
* list all the bigswitch Vns devices added in to this physical network
* list all the BigSwitch BCF Controller devices added in to this physical network
* @param physicalNetworkId physical Network Id
* @return list of BigSwitchVnsDeviceVO for this physical network.
* @return list of BigSwitchBcfDeviceVO for this physical network.
*/
List<BigSwitchVnsDeviceVO> listByPhysicalNetwork(long physicalNetworkId);
List<BigSwitchBcfDeviceVO> listByPhysicalNetwork(long physicalNetworkId);
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,6 +15,8 @@
// 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 java.util.List;
@ -22,27 +25,27 @@ import javax.ejb.Local;
import org.springframework.stereotype.Component;
import com.cloud.network.BigSwitchVnsDeviceVO;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
@Component
@Local(value = BigSwitchVnsDao.class)
public class BigSwitchVnsDaoImpl extends GenericDaoBase<BigSwitchVnsDeviceVO, Long> implements BigSwitchVnsDao {
@Local(value = BigSwitchBcfDao.class)
public class BigSwitchBcfDaoImpl extends GenericDaoBase<BigSwitchBcfDeviceVO, Long> implements BigSwitchBcfDao {
protected final SearchBuilder<BigSwitchVnsDeviceVO> physicalNetworkIdSearch;
protected final SearchBuilder<BigSwitchBcfDeviceVO> physicalNetworkIdSearch;
public BigSwitchVnsDaoImpl() {
public BigSwitchBcfDaoImpl() {
physicalNetworkIdSearch = createSearchBuilder();
physicalNetworkIdSearch.and("physicalNetworkId", physicalNetworkIdSearch.entity().getPhysicalNetworkId(), Op.EQ);
physicalNetworkIdSearch.done();
}
@Override
public List<BigSwitchVnsDeviceVO> listByPhysicalNetwork(long physicalNetworkId) {
SearchCriteria<BigSwitchVnsDeviceVO> sc = physicalNetworkIdSearch.create();
public List<BigSwitchBcfDeviceVO> listByPhysicalNetwork(long physicalNetworkId) {
SearchCriteria<BigSwitchBcfDeviceVO> sc = physicalNetworkIdSearch.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
return search(sc, null);
}

View File

@ -0,0 +1,785 @@
//
// 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 java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import org.apache.commons.net.util.SubnetUtils;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.BcfAnswer;
import com.cloud.agent.api.UpdateBcfRouterCommand;
import com.cloud.agent.api.CreateBcfAttachmentCommand;
import com.cloud.agent.api.CreateBcfStaticNatCommand;
import com.cloud.agent.api.DeleteBcfAttachmentCommand;
import com.cloud.agent.api.DeleteBcfStaticNatCommand;
import com.cloud.agent.api.StartupBigSwitchBcfCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.AddBigSwitchBcfDeviceCmd;
import com.cloud.api.commands.DeleteBigSwitchBcfDeviceCmd;
import com.cloud.api.commands.ListBigSwitchBcfDevicesCmd;
import com.cloud.api.commands.BcfConstants;
import com.cloud.api.response.BigSwitchBcfDeviceResponse;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.IpAddressManager;
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.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.bigswitch.AclData;
import com.cloud.network.bigswitch.BigSwitchBcfApi;
import com.cloud.network.bigswitch.BigSwitchBcfUtils;
import com.cloud.network.bigswitch.TopologyData;
import com.cloud.network.dao.BigSwitchBcfDao;
import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkServiceMapDao;
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.BigSwitchBcfResource;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.StaticNat;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.NetworkACLItemCidrsDao;
import com.cloud.network.vpc.NetworkACLItemDao;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceState;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.VMInstanceDao;
/**
* BigSwitchBcfElement is responsible for creating and plugging a nic into a BCF Segment network.
* When a VM is created and needs to be plugged into a BCF Segment network, BigSwitchBcfElement is
* called by NetworkOrchestrator to create a "port" and an "attachment" for each nic, and
* register them with the controller to be plugged into the corresponding network. It also
* removes them when the VM is destroyed.
*/
@Component
@Local(value = {NetworkElement.class, ConnectivityProvider.class, IpDeployer.class,
SourceNatServiceProvider.class, StaticNatServiceProvider.class,
NetworkACLServiceProvider.class, FirewallServiceProvider.class})
public class BigSwitchBcfElement extends AdapterBase implements BigSwitchBcfElementService,
ConnectivityProvider, IpDeployer, SourceNatServiceProvider, StaticNatServiceProvider,
NetworkACLServiceProvider, FirewallServiceProvider, ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(BigSwitchBcfElement.class);
private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@Inject
ResourceManager _resourceMgr;
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@Inject
BigSwitchBcfDao _bigswitchBcfDao;
@Inject
HostDetailsDao _hostDetailsDao;
@Inject
HostDao _hostDao;
@Inject
AgentManager _agentMgr;
@Inject
NetworkDao _networkDao;
@Inject
DomainRouterDao _routerDao;
@Inject
NicDao _nicDao;
@Inject
VMInstanceDao _vmDao;
@Inject
AccountDao _accountDao;
@Inject
VpcDao _vpcDao;
@Inject
NetworkModel _networkModel;
@Inject
ConfigurationManager _configMgr;
@Inject
NetworkServiceMapDao _ntwkSrvcDao;
@Inject
DataCenterDao _zoneDao;
@Inject
IPAddressDao _ipAddressDao;
@Inject
IpAddressManager _ipAddrMgr;
@Inject
VlanDao _vlanDao;
@Inject
FirewallRulesDao _fwRulesDao;
@Inject
FirewallRulesCidrsDao _fwCidrsDao;
@Inject
NetworkACLItemDao _aclItemDao;
@Inject
NetworkACLItemCidrsDao _aclItemCidrsDao;
private BigSwitchBcfUtils _bcfUtils = null;
@Override
public Map<Service, Map<Capability, String>> getCapabilities() {
return capabilities;
}
@Override
public Provider getProvider() {
return Provider.BigSwitchBcf;
}
private boolean canHandle(Network network, Service service) {
s_logger.debug("Checking if BigSwitchBcfElement can handle service " + service.getName() + " on network " + network.getDisplayText());
if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
return false;
}
if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
s_logger.debug("BigSwitchBcfElement is not a provider for network " + network.getDisplayText());
return false;
}
if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, BcfConstants.BigSwitchBcf)) {
s_logger.debug("BigSwitchBcfElement can't provide the " + service.getName() + " service on network " + network.getDisplayText());
return false;
}
return true;
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
_resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
return true;
}
@Override
public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException,
ResourceUnavailableException, InsufficientCapacityException {
updateBcfRouter(network);
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;
}
bcfUtilsInit();
// get arguments for CreateBcfAttachmentCommand
// determine whether this is VPC network or stand-alone network
Vpc vpc = null;
if(network.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(network.getVpcId());
}
String tenantId;
String tenantName;
if (vpc != null) {
tenantId = vpc.getUuid();
tenantName = vpc.getName();
_vpcDao.releaseFromLockTable(vpc.getId());
} else {
// use account in CS as tenant in BSN
// use network id/name as tenant id/name for non-VPC networks
tenantId = network.getUuid();
tenantName = network.getName();
}
String networkId = network.getUuid();
String hostname = dest.getHost().getName();
String nicId = nic.getUuid();
Integer vlan = Integer.valueOf(BroadcastDomainType.getValue(nic.getIsolationUri()));
String ipv4 = nic.getIp4Address();
String mac = nic.getMacAddress();
long zoneId = network.getDataCenterId();
String vmwareVswitchLabel = _networkModel.getDefaultGuestTrafficLabel(zoneId, HypervisorType.VMware);
String[] labelArray = null;
String vswitchName = null;
if(vmwareVswitchLabel!=null){
labelArray=vmwareVswitchLabel.split(",");
vswitchName = labelArray[0];
}
// hypervisor type:
// kvm: ivs port name
// vmware: specific portgroup naming convention
String pgName = "";
if (dest.getHost().getHypervisorType() == HypervisorType.KVM){
pgName = hostname;
} else if (dest.getHost().getHypervisorType() == HypervisorType.VMware){
pgName = hostname + "-" + vswitchName;
}
CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand(tenantId,
tenantName, networkId, pgName, nicId, vlan, ipv4, mac);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
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");
return false;
}
bcfUtilsInit();
String networkId = network.getUuid();
String nicId = nic.getUuid();
String tenantId;
if(network.getVpcId()!=null) {
tenantId = network.getNetworkDomain();
} else {
tenantId = networkId;
}
DeleteBcfAttachmentCommand cmd = new DeleteBcfAttachmentCommand(tenantId, networkId, nicId);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
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 destroy(Network network, ReservationContext context) 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 true;
}
@Override
public boolean verifyServicesCombination(Set<Service> services) {
if (!services.contains(Service.Connectivity)) {
s_logger.warn("Unable to provide services without Connectivity service enabled for this element");
return false;
}
return true;
}
private static Map<Service, Map<Capability, String>> setCapabilities() {
Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
// L2 Support
capabilities.put(Service.Connectivity, null);
// L3 Support
capabilities.put(Service.Gateway, null);
// L3 Support : SourceNat
Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
sourceNatCapabilities.put(Capability.RedundantRouter, "false");
capabilities.put(Service.SourceNat, sourceNatCapabilities);
// L3 support : StaticNat
capabilities.put(Service.StaticNat, null);
//add network ACL capability
Map<Network.Capability, String> networkACLCapabilities = new HashMap<Network.Capability, String>();
networkACLCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp");
capabilities.put(Network.Service.NetworkACL, networkACLCapabilities);
// Set capabilities for Firewall service
Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
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);
return capabilities;
}
@Override
@DB
public BigSwitchBcfDeviceVO addBigSwitchBcfDevice(AddBigSwitchBcfDeviceCmd cmd) {
BigSwitchBcfDeviceVO newBcfDevice;
bcfUtilsInit();
ServerResource resource = new BigSwitchBcfResource();
final String deviceName = BcfConstants.BigSwitchBcf.getName();
NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
final Long physicalNetworkId = cmd.getPhysicalNetworkId();
final String hostname = cmd.getHost();
final String username = cmd.getUsername();
final String password = cmd.getPassword();
final Boolean nat = cmd.getNat();
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 enabled in the physical network: " +
physicalNetworkId + "to add this device");
} else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() + " is in shutdown state in the physical network: " +
physicalNetworkId + "to add this device");
}
ntwkSvcProvider.setFirewallServiceProvided(true);
ntwkSvcProvider.setGatewayServiceProvided(true);
ntwkSvcProvider.setNetworkAclServiceProvided(true);
ntwkSvcProvider.setSourcenatServiceProvided(true);
ntwkSvcProvider.setStaticnatServiceProvided(true);
if (_bigswitchBcfDao.listByPhysicalNetwork(physicalNetworkId).size() > 1) {
throw new CloudRuntimeException("At most two BCF controllers can be configured");
}
DataCenterVO zone = _zoneDao.findById(physicalNetwork.getDataCenterId());
String zoneName;
if(zone!= null){
zoneName = zone.getName();
} else {
zoneName = String.valueOf(zoneId);
}
Boolean natNow = _bcfUtils.isNatEnabled();
if( natNow != null)
if (!nat && natNow){
throw new CloudRuntimeException("NAT is enabled in existing controller. Enable NAT for new controller or remove existing controller first.");
} else if (nat && !natNow){
throw new CloudRuntimeException("NAT is disabled in existing controller. Disable NAT for new controller or remove existing controller first.");
}
Map<String, String> params = new HashMap<String, String>();
params.put("guid", UUID.randomUUID().toString());
params.put("zoneId", zoneName);
params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
params.put("name", "BigSwitch Controller - " + cmd.getHost());
params.put("hostname", cmd.getHost());
params.put("username", username);
params.put("password", password);
params.put("nat", nat.toString());
// FIXME What to do with multiple isolation types
params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase());
Map<String, Object> hostdetails = new HashMap<String, Object>();
hostdetails.putAll(params);
try {
resource.configure(cmd.getHost(), hostdetails);
// store current topology in bcf resource
TopologyData topo = _bcfUtils.getTopology(physicalNetwork.getId());
((BigSwitchBcfResource) resource).setTopology(topo);
final Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, params);
if (host != null) {
newBcfDevice = Transaction.execute(new TransactionCallback<BigSwitchBcfDeviceVO>() {
@Override
public BigSwitchBcfDeviceVO doInTransaction(TransactionStatus status) {
BigSwitchBcfDeviceVO bigswitchBcfDevice =
new BigSwitchBcfDeviceVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(),
deviceName, hostname, username, password, nat, BigSwitchBcfApi.HASH_IGNORE);
_bigswitchBcfDao.persist(bigswitchBcfDevice);
DetailVO detail = new DetailVO(host.getId(), "bigswitchbcfdeviceid", String.valueOf(bigswitchBcfDevice.getId()));
_hostDetailsDao.persist(detail);
return bigswitchBcfDevice;
}
});
} else {
throw new CloudRuntimeException("Failed to add BigSwitch BCF Controller Device due to internal error.");
}
} catch (ConfigurationException e) {
throw new CloudRuntimeException(e.getMessage());
}
// initial topology sync to newly added BCF controller
HostVO bigswitchBcfHost = _hostDao.findById(newBcfDevice.getHostId());
_bcfUtils.syncTopologyToBcfHost(bigswitchBcfHost, nat);
return newBcfDevice;
}
@Override
public BigSwitchBcfDeviceResponse createBigSwitchBcfDeviceResponse(BigSwitchBcfDeviceVO bigswitchBcfDeviceVO) {
HostVO bigswitchBcfHost = _hostDao.findById(bigswitchBcfDeviceVO.getHostId());
_hostDao.loadDetails(bigswitchBcfHost);
BigSwitchBcfDeviceResponse response = new BigSwitchBcfDeviceResponse();
response.setDeviceName(bigswitchBcfDeviceVO.getDeviceName());
PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(bigswitchBcfDeviceVO.getPhysicalNetworkId());
if (pnw != null) {
response.setPhysicalNetworkId(pnw.getUuid());
}
response.setId(bigswitchBcfDeviceVO.getUuid());
response.setProviderName(bigswitchBcfDeviceVO.getProviderName());
response.setHostName(bigswitchBcfHost.getDetail("hostname"));
response.setObjectName("bigswitchbcfdevice");
return response;
}
@Override
public boolean deleteBigSwitchBcfDevice(DeleteBigSwitchBcfDeviceCmd cmd) {
Long bigswitchBcfDeviceId = cmd.getBigSwitchBcfDeviceId();
BigSwitchBcfDeviceVO bigswitchBcfDevice = _bigswitchBcfDao.findById(bigswitchBcfDeviceId);
if (bigswitchBcfDevice == null) {
throw new InvalidParameterValueException("Could not find a BigSwitch Controller with id " + bigswitchBcfDevice);
}
HostVO bigswitchHost = _hostDao.findById(bigswitchBcfDevice.getHostId());
Long hostId = bigswitchHost.getId();
bigswitchHost.setResourceState(ResourceState.Maintenance);
_hostDao.update(hostId, bigswitchHost);
_resourceMgr.deleteHost(hostId, false, false);
_bigswitchBcfDao.remove(bigswitchBcfDeviceId);
return true;
}
@Override
public List<BigSwitchBcfDeviceVO> listBigSwitchBcfDevices(ListBigSwitchBcfDevicesCmd cmd) {
Long physicalNetworkId = cmd.getPhysicalNetworkId();
Long bigswitchBcfDeviceId = cmd.getBigSwitchBcfDeviceId();
List<BigSwitchBcfDeviceVO> responseList = new ArrayList<BigSwitchBcfDeviceVO>();
if (physicalNetworkId == null && bigswitchBcfDeviceId == null) {
throw new InvalidParameterValueException("Either physical network Id or bigswitch device Id must be specified");
}
if (bigswitchBcfDeviceId != null) {
BigSwitchBcfDeviceVO bigswitchBcfDevice = _bigswitchBcfDao.findById(bigswitchBcfDeviceId);
if (bigswitchBcfDevice == null) {
throw new InvalidParameterValueException("Could not find BigSwitch controller with id: " + bigswitchBcfDevice);
}
responseList.add(bigswitchBcfDevice);
} else {
PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
if (physicalNetwork == null) {
throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId);
}
responseList = _bigswitchBcfDao.listByPhysicalNetwork(physicalNetworkId);
}
return responseList;
}
@Override
public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
return null;
}
@Override
public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
if (!(startup[0] instanceof StartupBigSwitchBcfCommand)) {
return null;
}
BigSwitchBcfResource bcfResource = (BigSwitchBcfResource) resource;
bcfUtilsInit();
if(_bcfUtils.getTopology()!=null){
bcfResource.setTopology(_bcfUtils.getTopology());
}
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);
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(AddBigSwitchBcfDeviceCmd.class);
cmdList.add(DeleteBigSwitchBcfDeviceCmd.class);
cmdList.add(ListBigSwitchBcfDevicesCmd.class);
return cmdList;
}
@Override
public IpDeployer getIpDeployer(Network network) {
return this;
}
@Override
public boolean applyStaticNats(Network network,
List<? extends StaticNat> rules)
throws ResourceUnavailableException {
bcfUtilsInit();
_bcfUtils.listACLbyNetwork(network);
Vpc vpc = null;
if(network.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(network.getVpcId());
}
String tenantId;
if (vpc != null) {
tenantId = vpc.getUuid();
_vpcDao.releaseFromLockTable(vpc.getId());
} else {
// use account in CS as tenant in BSN
// use network uuid as tenantId for non-VPC networks
tenantId = network.getUuid();
}
for (StaticNat rule: rules){
String srcIp = _ipAddressDao.findById(rule.getSourceIpAddressId()).getAddress().addr();
String dstIp = rule.getDestIpAddress();
String mac = rule.getSourceMacAddress();
if(!rule.isForRevoke()) {
s_logger.debug("BCF enables static NAT for public IP: " + srcIp + " private IP " + dstIp
+ " mac " + mac);
CreateBcfStaticNatCommand cmd = new CreateBcfStaticNatCommand(
tenantId, network.getUuid(), dstIp, srcIp, mac);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
} else {
s_logger.debug("BCF removes static NAT for public IP: " + srcIp + " private IP " + dstIp
+ " mac " + mac);
DeleteBcfStaticNatCommand cmd = new DeleteBcfStaticNatCommand(tenantId, srcIp);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
}
}
return true;
}
@Override
public boolean applyIps(Network network,
List<? extends PublicIpAddress> ipAddress, Set<Service> services)
throws ResourceUnavailableException {
return false;
}
@Override
public boolean applyNetworkACLs(Network network,
List<? extends NetworkACLItem> rules)
throws ResourceUnavailableException {
SubnetUtils utils;
String cidr = null;
List<String> cidrList;
for(NetworkACLItem r: rules){
if(r.getState()==NetworkACLItem.State.Revoke){
continue;
}
cidrList = r.getSourceCidrList();
if(cidrList != null){
if(cidrList.size()>1 || r.getSourcePortEnd()!=r.getSourcePortStart()){
throw new ResourceUnavailableException("One CIDR and one port only please.",
Network.class, network.getId());
} else {
cidr = cidrList.get(0);
}
}
if (cidr == null || cidr.equalsIgnoreCase("0.0.0.0/0")) {
cidr = "";
} else {
utils = new SubnetUtils(cidr);
if(!utils.getInfo().getNetworkAddress().equals(utils.getInfo().getAddress())){
throw new ResourceUnavailableException("Invalid CIDR in Network ACL rule.",
Network.class, network.getId());
}
}
}
updateBcfRouter(network);
return true;
}
@Override
public boolean applyFWRules(Network network,
List<? extends FirewallRule> rules)
throws ResourceUnavailableException {
SubnetUtils utils;
String cidr = null;
List<String> cidrList;
for(FirewallRule r: rules){
if(r.getState()==FirewallRule.State.Revoke){
continue;
}
cidrList = r.getSourceCidrList();
if(cidrList != null){
if(cidrList.size()>1 || r.getSourcePortEnd()!=r.getSourcePortStart()){
throw new ResourceUnavailableException("One CIDR and one port only please.",
Network.class, network.getId());
} else {
cidr = cidrList.get(0);
}
}
if (cidr == null || cidr.equalsIgnoreCase("0.0.0.0/0")) {
cidr = "";
} else {
utils = new SubnetUtils(cidr);
if(!utils.getInfo().getNetworkAddress().equals(utils.getInfo().getAddress())){
throw new ResourceUnavailableException("Invalid CIDR in Firewall rule.",
Network.class, network.getId());
}
}
}
updateBcfRouter(network);
return true;
}
private void updateBcfRouter(Network network) throws IllegalArgumentException{
bcfUtilsInit();
Vpc vpc = null;
if(network.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(network.getVpcId());
}
String tenantId;
if (vpc != null) {
tenantId = vpc.getUuid();
_vpcDao.releaseFromLockTable(vpc.getId());
} else {
tenantId = network.getUuid();
}
UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand(tenantId);
List<AclData> aclList = _bcfUtils.listACLbyNetwork(network);
for(AclData acl: aclList){
cmd.addAcl(acl);
}
if(vpc != null){
cmd.setPublicIp(_bcfUtils.getPublicIpByVpc(vpc));
} else {
cmd.setPublicIp(_bcfUtils.getPublicIpByNetwork(network));
}
BcfAnswer answer = _bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
if(answer != null && !answer.getResult()){
throw new IllegalArgumentException("Illegal router update arguments");
}
}
private void bcfUtilsInit(){
if (_bcfUtils == null) {
_bcfUtils = new BigSwitchBcfUtils(_networkDao, _nicDao,
_vmDao, _hostDao, _vpcDao, _bigswitchBcfDao,
_agentMgr, _vlanDao, _ipAddressDao, _fwRulesDao,
_fwCidrsDao, _aclItemDao, _aclItemCidrsDao, _networkModel);
}
}
}

View File

@ -1,3 +1,4 @@
//
// 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
@ -14,25 +15,27 @@
// 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.List;
import com.cloud.api.commands.AddBigSwitchVnsDeviceCmd;
import com.cloud.api.commands.DeleteBigSwitchVnsDeviceCmd;
import com.cloud.api.commands.ListBigSwitchVnsDevicesCmd;
import com.cloud.api.response.BigSwitchVnsDeviceResponse;
import com.cloud.network.BigSwitchVnsDeviceVO;
import com.cloud.api.commands.AddBigSwitchBcfDeviceCmd;
import com.cloud.api.commands.DeleteBigSwitchBcfDeviceCmd;
import com.cloud.api.commands.ListBigSwitchBcfDevicesCmd;
import com.cloud.api.response.BigSwitchBcfDeviceResponse;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.utils.component.PluggableService;
public interface BigSwitchVnsElementService extends PluggableService {
public interface BigSwitchBcfElementService extends PluggableService {
public BigSwitchVnsDeviceVO addBigSwitchVnsDevice(AddBigSwitchVnsDeviceCmd cmd);
public BigSwitchBcfDeviceVO addBigSwitchBcfDevice(AddBigSwitchBcfDeviceCmd cmd);
public BigSwitchVnsDeviceResponse createBigSwitchVnsDeviceResponse(BigSwitchVnsDeviceVO bigswitchDeviceVO);
public BigSwitchBcfDeviceResponse createBigSwitchBcfDeviceResponse(BigSwitchBcfDeviceVO bigswitchDeviceVO);
boolean deleteBigSwitchVnsDevice(DeleteBigSwitchVnsDeviceCmd cmd);
public boolean deleteBigSwitchBcfDevice(DeleteBigSwitchBcfDeviceCmd cmd);
List<BigSwitchVnsDeviceVO> listBigSwitchVnsDevices(ListBigSwitchVnsDevicesCmd cmd);
public List<BigSwitchBcfDeviceVO> listBigSwitchBcfDevices(ListBigSwitchBcfDevicesCmd cmd);
}

View File

@ -0,0 +1,423 @@
//
// 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.List;
import javax.ejb.Local;
import javax.inject.Inject;
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.CreateBcfAttachmentCommand;
import com.cloud.agent.api.CreateBcfRouterCommand;
import com.cloud.agent.api.CreateBcfRouterInterfaceCommand;
import com.cloud.agent.api.CreateBcfSegmentCommand;
import com.cloud.agent.api.DeleteBcfSegmentCommand;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.BigSwitchBcfDeviceVO;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkProfile;
import com.cloud.network.NetworkService;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.bigswitch.BigSwitchBcfUtils;
import com.cloud.network.dao.BigSwitchBcfDao;
import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.vpc.NetworkACLItemCidrsDao;
import com.cloud.network.vpc.NetworkACLItemDao;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.VMInstanceDao;
/**
* BigSwitchBcfGuestNetworkGuru is responsible for creating and removing virtual networks.
* Current implementation leverages GuestNetworkGuru to create VLAN based virtual networks
* and map it to a Big Switch Big Cloud Fabric (BCF) Segment. It is called by the NetworkOrchestrator.
*
* When a VM is created and needs to be plugged into a BCF segment network, BigSwitchBcfElement is
* called by NetworkOrchestrator to create a "port" and an "attachment" for each nic, and
* register them with the controller to be plugged into the corresponding network. It also
* removes them when the VM is destroyed.
*/
@Local(value = NetworkGuru.class)
public class BigSwitchBcfGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigrationResponder {
private static final Logger s_logger = Logger.getLogger(BigSwitchBcfGuestNetworkGuru.class);
@Inject
PhysicalNetworkDao _physicalNetworkDao;
@Inject
BigSwitchBcfDao _bigswitchBcfDao;
@Inject
HostDao _hostDao;
@Inject
AgentManager _agentMgr;
@Inject
DomainRouterDao _routerDao;
@Inject
VMInstanceDao _vmDao;
@Inject
AccountDao _accountDao;
@Inject
VpcDao _vpcDao;
@Inject
IPAddressDao _ipAddressDao;
@Inject
HostPodDao _podDao;
@Inject
NetworkService _netService;
@Inject
VlanDao _vlanDao;
@Inject
FirewallRulesDao _fwRulesDao;
@Inject
FirewallRulesCidrsDao _fwCidrsDao;
@Inject
NetworkACLItemDao _aclItemDao;
@Inject
NetworkACLItemCidrsDao _aclItemCidrsDao;
private BigSwitchBcfUtils _bcfUtils = null;
public BigSwitchBcfGuestNetworkGuru() {
super();
_isolationMethods = new IsolationMethod[] {IsolationMethod.BCF_SEGMENT};
}
@Override
protected boolean canHandle(NetworkOffering offering, NetworkType networkType, 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 Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
// Check if the isolation type of the physical network is BCF_SEGMENT, then delegate GuestNetworkGuru to design
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
if (physnet == null || physnet.getIsolationMethods() == null || !physnet.getIsolationMethods().contains("BCF_SEGMENT")) {
s_logger.debug("Refusing to design this network, the physical isolation type is not BCF_SEGMENT");
return null;
}
List<BigSwitchBcfDeviceVO> devices = _bigswitchBcfDao.listByPhysicalNetwork(physnet.getId());
if (devices.isEmpty()) {
s_logger.error("No BigSwitch Controller on physical network " + physnet.getName());
return null;
}
for (BigSwitchBcfDeviceVO d: devices){
s_logger.debug("BigSwitch Controller " + d.getUuid()
+ " found on physical network " + physnet.getId());
}
s_logger.debug("Physical isolation type is BCF_SEGMENT, asking GuestNetworkGuru to design this network");
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
if (networkObject == null) {
return null;
}
// Override the broadcast domain type
networkObject.setBroadcastDomainType(BroadcastDomainType.Vlan);
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;
bcfUtilsInit();
long dcId = dest.getDataCenter().getId();
long 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, false);
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
String vnetId = "";
if (network.getBroadcastUri() == null) {
vnetId = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), context.getReservationId(), UseSystemGuestVlans.valueIn(network.getAccountId()));
if (vnetId == null) {
throw new InsufficientVirtualNetworkCapacityException("Unable to allocate vnet as a " +
"part of network " + network + " implement ", DataCenter.class, dcId);
}
implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnetId));
ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(),
EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnetId + " Network Id: " + network.getId(), 0);
} else {
implemented.setBroadcastUri(network.getBroadcastUri());
}
// Name is either the given name or the uuid
String name = network.getName();
if (name == null || name.isEmpty()) {
name = ((NetworkVO)network).getUuid();
}
if (name.length() > 64) {
name = name.substring(0, 63); // max length 64
}
// update fields in network object
NetworkVO networkObject = (NetworkVO) network;
// determine whether this is VPC network or stand-alone network
Vpc vpc = null;
if(network.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(network.getVpcId());
}
// use uuid of networkVO as network id in BSN
String networkId = networkObject.getUuid();
String tenantId;
String tenantName;
if (vpc != null) {
tenantId = vpc.getUuid();
tenantName = vpc.getName();
_vpcDao.releaseFromLockTable(vpc.getId());
} else {
// use network in CS as tenant in BSN
// for non-VPC networks, use network name and id as tenant name and id
tenantId = networkId;
tenantName = name;
}
// store tenantId in networkObject for NetworkOrchestrator implementNetwork use
networkObject.setNetworkDomain(tenantId);
// store tenant Id in implemented object for future actions (e.g., shutdown)
implemented.setNetworkDomain(tenantId);
String vlanStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
// get public net info - needed to set up source nat gateway
NetworkVO pubNet = _bcfUtils.getPublicNetwork(physicalNetworkId);
// locate subnet info
SearchCriteria<VlanVO> sc = _vlanDao.createSearchCriteria();
sc.setParameters("network_id", pubNet.getId());
VlanVO pubVlanVO = _vlanDao.findOneBy(sc);
String pubVlanStr = pubVlanVO.getVlanTag();
Integer vlan;
if(StringUtils.isNumeric(vlanStr)){
vlan = Integer.valueOf(vlanStr);
} else {
vlan = 0;
}
CreateBcfSegmentCommand cmd1 = new CreateBcfSegmentCommand(tenantId, tenantName, networkId, name, vlan);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd1, networkObject);
if(_bcfUtils.isNatEnabled()){
Integer pvlan;
if(StringUtils.isNumeric(pubVlanStr)){
pvlan = Integer.valueOf(pubVlanStr);
} else {
pvlan = 0;
}
CreateBcfSegmentCommand cmd2 = new CreateBcfSegmentCommand("external", "external", "external", "external", pvlan);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd2, networkObject);
CreateBcfRouterCommand cmd3 = new CreateBcfRouterCommand(tenantId);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd3, network);
CreateBcfRouterInterfaceCommand cmd5 = new CreateBcfRouterInterfaceCommand(tenantId, network.getUuid(), network.getCidr(),
network.getGateway(), network.getName());
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd5, network);
}
return implemented;
}
@Override
public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
// Have GuestNetworkGuru reserve for us
super.reserve(nic, network, vm, dest, context);
}
@Override
public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) {
return super.release(nic, vm, reservationId);
}
@Override
public void shutdown(NetworkProfile profile, NetworkOffering offering) {
NetworkVO networkObject = _networkDao.findById(profile.getId());
if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vlan || networkObject.getBroadcastUri() == null) {
s_logger.warn("BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
return;
}
bcfUtilsInit();
// tenantId stored in network domain field at creation
String tenantId = networkObject.getNetworkDomain();
String networkId = networkObject.getUuid();
DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand(tenantId, networkId);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, networkObject);
super.shutdown(profile, offering);
}
@Override
public boolean trash(Network network, NetworkOffering offering) {
return super.trash(network, offering);
}
@Override
public boolean prepareMigration(NicProfile nic, Network network,
VirtualMachineProfile vm, DeployDestination dest,
ReservationContext context) {
bcfUtilsInit();
// get arguments for CreateBcfAttachmentCommand
// determine whether this is VPC network or stand-alone network
Vpc vpc = null;
if(network.getVpcId()!=null){
vpc = _vpcDao.acquireInLockTable(network.getVpcId());
}
String networkId = network.getUuid();
String tenantId;
String tenantName;
if (vpc != null) {
tenantId = vpc.getUuid();
tenantName = vpc.getName();
boolean released = _vpcDao.releaseFromLockTable(vpc.getId());
s_logger.debug("BCF guru release lock vpc id: " + vpc.getId()
+ " released? " + released);
} else {
// use network id in CS as tenant in BSN
// use network uuid as tenant id for non-VPC networks
tenantId = networkId;
tenantName = network.getName();
}
String hostname = dest.getHost().getName();
long zoneId = network.getDataCenterId();
String vmwareVswitchLabel = _networkModel.getDefaultGuestTrafficLabel(zoneId, HypervisorType.VMware);
String[] labelArray = null;
String vswitchName = null;
if(vmwareVswitchLabel!=null){
labelArray=vmwareVswitchLabel.split(",");
vswitchName = labelArray[0];
}
// hypervisor type:
// kvm: ivs port name
// vmware: specific portgroup naming convention
String pgName = "";
if (dest.getHost().getHypervisorType() == HypervisorType.KVM){
pgName = hostname;
} else if (dest.getHost().getHypervisorType() == HypervisorType.VMware){
pgName = hostname + "-" + vswitchName;
}
String nicId = nic.getUuid();
Integer vlan = Integer.valueOf(BroadcastDomainType.getValue(nic.getIsolationUri()));
String ipv4 = nic.getIp4Address();
String mac = nic.getMacAddress();
CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand(tenantId,
tenantName, networkId, pgName, nicId, vlan, ipv4, mac);
_bcfUtils.sendBcfCommandWithNetworkSyncCheck(cmd, network);
return true;
}
@Override
public void rollbackMigration(NicProfile nic, Network network,
VirtualMachineProfile vm, ReservationContext src,
ReservationContext dst) {
s_logger.debug("BCF guru rollback migration");
}
@Override
public void commitMigration(NicProfile nic, Network network,
VirtualMachineProfile vm, ReservationContext src,
ReservationContext dst) {
s_logger.debug("BCF guru commit migration");
}
private void bcfUtilsInit(){
if (_bcfUtils == null) {
_bcfUtils = new BigSwitchBcfUtils(_networkDao, _nicDao,
_vmDao, _hostDao, _vpcDao, _bigswitchBcfDao,
_agentMgr, _vlanDao, _ipAddressDao, _fwRulesDao,
_fwCidrsDao, _aclItemDao, _aclItemCidrsDao, _networkModel);
}
}
}

View File

@ -0,0 +1,589 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.UpdateBcfRouterCommand;
import com.cloud.agent.api.BcfAnswer;
import com.cloud.agent.api.CacheBcfTopologyCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreateBcfRouterCommand;
import com.cloud.agent.api.CreateBcfRouterInterfaceCommand;
import com.cloud.agent.api.CreateBcfSegmentCommand;
import com.cloud.agent.api.CreateBcfAttachmentCommand;
import com.cloud.agent.api.CreateBcfStaticNatCommand;
import com.cloud.agent.api.DeleteBcfSegmentCommand;
import com.cloud.agent.api.DeleteBcfAttachmentCommand;
import com.cloud.agent.api.DeleteBcfStaticNatCommand;
import com.cloud.agent.api.GetControllerDataAnswer;
import com.cloud.agent.api.GetControllerDataCommand;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.ReadyAnswer;
import com.cloud.agent.api.ReadyCommand;
import com.cloud.agent.api.StartupBigSwitchBcfCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.SyncBcfTopologyCommand;
import com.cloud.agent.api.UpdateBcfAttachmentCommand;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.network.bigswitch.AclData;
import com.cloud.network.bigswitch.BigSwitchBcfApi;
import com.cloud.network.bigswitch.BigSwitchBcfApiException;
import com.cloud.network.bigswitch.Capabilities;
import com.cloud.network.bigswitch.ControlClusterStatus;
import com.cloud.network.bigswitch.ControllerData;
import com.cloud.network.bigswitch.FloatingIpData;
import com.cloud.network.bigswitch.NetworkData;
import com.cloud.network.bigswitch.AttachmentData;
import com.cloud.network.bigswitch.RouterData;
import com.cloud.network.bigswitch.RouterInterfaceData;
import com.cloud.network.bigswitch.TopologyData;
import com.cloud.resource.ServerResource;
import com.cloud.utils.component.ManagerBase;
public class BigSwitchBcfResource extends ManagerBase implements ServerResource {
private static final Logger s_logger = Logger.getLogger(BigSwitchBcfResource.class);
private String _name;
private String _guid;
private String _zoneId;
private int _numRetries;
private BigSwitchBcfApi _bigswitchBcfApi;
private TopologyData _latestTopology = null;
private boolean initTopologySyncDone = false;
protected BigSwitchBcfApi createBigSwitchBcfApi() {
return new BigSwitchBcfApi();
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = (String)params.get("name");
if (_name == null) {
throw new ConfigurationException("Unable to find name");
}
_guid = (String)params.get("guid");
if (_guid == null) {
throw new ConfigurationException("Unable to find the guid");
}
_zoneId = (String)params.get("zoneId");
if (_zoneId == null) {
throw new ConfigurationException("Unable to find zone");
}
_numRetries = 2;
String hostname = (String)params.get("hostname");
if (hostname == null) {
throw new ConfigurationException("Missing host name from params: " + params);
}
String username = (String) params.get("username");
if (username == null) {
throw new ConfigurationException("Missing user name from params: " + params);
}
String password = (String) params.get("password");
if (password == null) {
throw new ConfigurationException("Missing password from params: " + params);
}
Boolean nat = Boolean.parseBoolean((String) params.get("nat"));
if (nat == null) {
throw new ConfigurationException("Missing password from params: " + params);
}
_bigswitchBcfApi = createBigSwitchBcfApi();
_bigswitchBcfApi.setControllerAddress(hostname);
_bigswitchBcfApi.setControllerUsername(username);
_bigswitchBcfApi.setControllerPassword(password);
_bigswitchBcfApi.setControllerNat(nat);
_bigswitchBcfApi.setZoneId(_zoneId);
return true;
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return _name;
}
@Override
public Type getType() {
return Host.Type.L2Networking;
}
@Override
public StartupCommand[] initialize() {
StartupBigSwitchBcfCommand sc = new StartupBigSwitchBcfCommand();
sc.setGuid(_guid);
sc.setName(_name);
sc.setDataCenter(_zoneId);
sc.setPod("");
sc.setPrivateIpAddress("");
sc.setStorageIpAddress("");
sc.setVersion("");
return new StartupCommand[] {sc};
}
@Override
public PingCommand getCurrentStatus(long id) {
if(!initTopologySyncDone && _latestTopology != null){
initTopologySyncDone = true;
if(_bigswitchBcfApi.isNatEnabled()){
try{
executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
} catch(Exception e){
s_logger.error("BigSwitch BCF sync error", e);
}
} else {
try{
executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
} catch (Exception e){
s_logger.error("BigSwitch BCF sync error", e);
}
}
}
try {
ControlClusterStatus ccs = _bigswitchBcfApi.getControlClusterStatus();
if (!ccs.getStatus()) {
s_logger.error("ControlCluster state is not ready: " + ccs.getStatus());
return null;
}
if (ccs.isTopologySyncRequested()) {
if(_latestTopology != null) {
if(_bigswitchBcfApi.isNatEnabled()){
executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
} else {
executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
}
} else {
s_logger.debug("topology sync needed but no topology history");
}
}
} catch (BigSwitchBcfApiException e) {
s_logger.error("getControlClusterStatus failed", e);
return null;
}
try {
Capabilities cap = _bigswitchBcfApi.getCapabilities();
// TODO: update controller status display, enable/disable service accordingly
if (cap.isTopologySyncRequested()) {
if(_latestTopology != null) {
if(_bigswitchBcfApi.isNatEnabled()){
executeRequest(new SyncBcfTopologyCommand(true, true), _numRetries);
} else {
executeRequest(new SyncBcfTopologyCommand(true, false), _numRetries);
}
}
}
} catch (BigSwitchBcfApiException e) {
s_logger.error("getCapabilities failed", e);
}
return new PingCommand(Host.Type.L2Networking, id);
}
@Override
public Answer executeRequest(Command cmd) {
return executeRequest(cmd, _numRetries);
}
public Answer executeRequest(Command cmd, int numRetries) {
if (cmd instanceof ReadyCommand) {
return executeRequest((ReadyCommand)cmd);
} else if (cmd instanceof MaintainCommand) {
return executeRequest((MaintainCommand)cmd);
} else if (cmd instanceof CreateBcfSegmentCommand) {
_latestTopology = ((CreateBcfSegmentCommand) cmd).getTopology();
return executeRequest((CreateBcfSegmentCommand)cmd, numRetries);
} else if (cmd instanceof DeleteBcfSegmentCommand) {
_latestTopology = ((DeleteBcfSegmentCommand) cmd).getTopology();
return executeRequest((DeleteBcfSegmentCommand)cmd, numRetries);
} else if (cmd instanceof CreateBcfAttachmentCommand) {
_latestTopology = ((CreateBcfAttachmentCommand) cmd).getTopology();
return executeRequest((CreateBcfAttachmentCommand)cmd, numRetries);
} else if (cmd instanceof DeleteBcfAttachmentCommand) {
_latestTopology = ((DeleteBcfAttachmentCommand) cmd).getTopology();
return executeRequest((DeleteBcfAttachmentCommand)cmd, numRetries);
} else if (cmd instanceof UpdateBcfAttachmentCommand) {
_latestTopology = ((UpdateBcfAttachmentCommand) cmd).getTopology();
return executeRequest((UpdateBcfAttachmentCommand)cmd, numRetries);
} else if (cmd instanceof CreateBcfRouterCommand) {
_latestTopology = ((CreateBcfRouterCommand) cmd).getTopology();
return executeRequest((CreateBcfRouterCommand)cmd, numRetries);
} else if (cmd instanceof CreateBcfRouterInterfaceCommand) {
_latestTopology = ((CreateBcfRouterInterfaceCommand) cmd).getTopology();
return executeRequest((CreateBcfRouterInterfaceCommand)cmd, numRetries);
} else if (cmd instanceof CreateBcfStaticNatCommand) {
_latestTopology = ((CreateBcfStaticNatCommand) cmd).getTopology();
return executeRequest((CreateBcfStaticNatCommand)cmd, numRetries);
} else if (cmd instanceof DeleteBcfStaticNatCommand) {
_latestTopology = ((DeleteBcfStaticNatCommand) cmd).getTopology();
return executeRequest((DeleteBcfStaticNatCommand)cmd, numRetries);
} else if (cmd instanceof UpdateBcfRouterCommand) {
_latestTopology = ((UpdateBcfRouterCommand) cmd).getTopology();
return executeRequest((UpdateBcfRouterCommand)cmd, numRetries);
} else if (cmd instanceof SyncBcfTopologyCommand) {
return executeRequest((SyncBcfTopologyCommand)cmd, numRetries);
} else if (cmd instanceof CacheBcfTopologyCommand) {
return executeRequest((CacheBcfTopologyCommand)cmd, numRetries);
} else if (cmd instanceof GetControllerDataCommand) {
return executeRequest((GetControllerDataCommand)cmd, numRetries);
}
s_logger.debug("Received unsupported command " + cmd.toString());
return Answer.createUnsupportedCommandAnswer(cmd);
}
@Override
public void disconnected() {
}
@Override
public IAgentControl getAgentControl() {
return null;
}
@Override
public void setAgentControl(IAgentControl agentControl) {
}
public void setTopology(TopologyData topology){
_latestTopology = topology;
}
public TopologyData getTopology(){
return _latestTopology;
}
private Answer executeRequest(CreateBcfSegmentCommand cmd, int numRetries) {
NetworkData network = new NetworkData();
network.getNetwork().setTenantId(cmd.getTenantId());
network.getNetwork().setTenantName(cmd.getTenantName());
network.getNetwork().setId(cmd.getNetworkId());
network.getNetwork().setName(truncate("segment-cloudstack-" + cmd.getNetworkName(), 64));
network.getNetwork().setVlan(cmd.getVlan());
try {
String hash =_bigswitchBcfApi.createNetwork(network);
return new BcfAnswer(cmd, true, "Segment " + network.getNetwork().getId() + " created", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "Segment " + network.getNetwork().getId() + " created; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(DeleteBcfSegmentCommand cmd, int numRetries) {
try {
String hash = _bigswitchBcfApi.deleteNetwork(cmd.get_tenantUuid(), cmd.getNetworkUuid());
return new BcfAnswer(cmd, true, "Segment " + cmd.getNetworkUuid() + " deleted", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "Segment " + cmd.getNetworkUuid() + " deleted; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(CreateBcfAttachmentCommand cmd, int numRetries) {
AttachmentData attachment = new AttachmentData();
attachment.getAttachment().setId(cmd.getNicId());
attachment.getAttachment().setHostId(cmd.getPortId());
attachment.getAttachment().setTenantName(cmd.getTenantName());
attachment.getAttachment().setVlan(cmd.getVlan());
attachment.getAttachment().addIpv4(cmd.getIpv4());
attachment.getAttachment().setMac(cmd.getMac());
try {
String hash = _bigswitchBcfApi.createAttachment(cmd.getTenantId(), cmd.getNetworkId(), attachment);
return new BcfAnswer(cmd, true, "network attachment " + cmd.getPortId() + " created", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "network attachment " + cmd.getPortId() + " created; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(DeleteBcfAttachmentCommand cmd, int numRetries) {
String nicName = cmd.getAttachmentId();
try {
String hash = _bigswitchBcfApi.deleteAttachment(cmd.getTenantId(), cmd.getNetworkId(), nicName);
return new BcfAnswer(cmd, true, "network attachment " + nicName + " deleted", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "network attachment " + nicName + " deleted; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(UpdateBcfAttachmentCommand cmd, int numRetries) {
AttachmentData attachment = new AttachmentData();
attachment.getAttachment().setId(cmd.getAttachmentId());
attachment.getAttachment().setTenantName(cmd.getTenantId());
try {
String hash = _bigswitchBcfApi.modifyAttachment(cmd.getTenantId(), cmd.getNetworkId(), attachment);
return new BcfAnswer(cmd, true, "Network attachment " + cmd.getAttachmentId() + " updated", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "Network attachment " + cmd.getAttachmentId() + " updated; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(CreateBcfStaticNatCommand cmd, int numRetries) {
FloatingIpData fip = new FloatingIpData();
fip.setTenantId(cmd.get_tenantId());
fip.setNetworkId(cmd.get_networkId());
fip.setFixedIp(cmd.get_privateIp());
fip.setFloatingIpAndId(cmd.get_publicIp());
fip.setMac(cmd.get_mac());
try {
String hash = _bigswitchBcfApi.createFloatingIp(cmd.get_tenantId(), fip);
return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + ":" +
cmd.get_privateIp() + " created", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + ":" +
cmd.get_privateIp() + " created; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(DeleteBcfStaticNatCommand cmd, int numRetries) {
try {
String hash = _bigswitchBcfApi.deleteFloatingIp(cmd.get_tenantId(), cmd.get_floatingIpId());
return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + " deleted", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "floating ip " + cmd.get_publicIp() + " deleted; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(CreateBcfRouterCommand cmd, int numRetries) {
RouterData router = new RouterData(cmd.get_tenantId());
try {
String hash;
hash = _bigswitchBcfApi.createRouter(cmd.get_tenantId(), router);
return new BcfAnswer(cmd, true, "router " + cmd.get_tenantId() +
" created.", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, " created; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(CreateBcfRouterInterfaceCommand cmd, int numRetries) {
RouterInterfaceData routerInterface = new RouterInterfaceData(cmd.get_tenantId(),
cmd.get_gateway(), cmd.get_cidr(), cmd.get_networkId(), cmd.get_networkName());
try {
String hash;
hash = _bigswitchBcfApi.createRouterInterface(cmd.get_tenantId(),
cmd.get_tenantId(), routerInterface);
return new BcfAnswer(cmd, true, "router " + cmd.get_tenantId() +
" created.", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, " created; topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
}
}
private Answer executeRequest(UpdateBcfRouterCommand cmd, int numRetries){
RouterData routerData = new RouterData(cmd.getTenantId());
List<AclData> acls = new ArrayList<AclData>();
acls.addAll(cmd.getAcls());
routerData.getRouter().getAcls().addAll(acls);
routerData.getRouter().addExternalGateway(cmd.getPublicIp());
try {
String hash = _bigswitchBcfApi.modifyRouter(cmd.getTenantId(), routerData);
return new BcfAnswer(cmd, true, "tenant " + cmd.getTenantId() + " router updated", hash);
} catch (BigSwitchBcfApiException e) {
if (e.is_topologySyncRequested()) {
cmd.set_topologySyncRequested(true);
return new BcfAnswer(cmd, true, "tenant " + cmd.getTenantId() + " router updated but topology sync required.");
} else {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
}
} catch (IllegalArgumentException e1){
return new BcfAnswer(cmd, false, "Illegal argument in BCF router update");
}
}
private Answer executeRequest(SyncBcfTopologyCommand cmd, int numRetries) {
try {
TopologyData topo = _latestTopology;
if (!cmd.isNetworkIncluded()) {
topo.clearNetworks();
}
if(!cmd.isRouterIncluded()) {
topo.clearRouters();
}
String hash = _bigswitchBcfApi.syncTopology(topo);
if(!initTopologySyncDone){
initTopologySyncDone=true;
}
return new BcfAnswer(cmd, true, "BCF topology synced", hash);
} catch (BigSwitchBcfApiException e) {
if (numRetries > 0) {
return retry(cmd, --numRetries);
} else {
return new BcfAnswer(cmd, e);
}
} catch (IllegalArgumentException e1){
return new BcfAnswer(cmd, false, "Illegal argument in BCF topology sync");
}
}
private Answer executeRequest(CacheBcfTopologyCommand cmd, int numRetries) {
_latestTopology = cmd.getTopology();
return new Answer(cmd, true, "BCF topology cached");
}
private Answer executeRequest(GetControllerDataCommand cmd, int numRetries) {
ControllerData controller = _bigswitchBcfApi.getControllerData();
return new GetControllerDataAnswer(cmd,
controller.getIpAddress(),
controller.isMaster());
}
private Answer executeRequest(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer executeRequest(MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
private Answer retry(Command cmd, int numRetries) {
s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetries);
return executeRequest(cmd, numRetries);
}
private String truncate(String string, int length) {
if (string.length() <= length) {
return string;
} else {
return string.substring(0, length);
}
}
}

View File

@ -0,0 +1,433 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.bigswitch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.http.HttpStatus;
import org.junit.Before;
import org.junit.Test;
import com.google.gson.reflect.TypeToken;
public class BigSwitchApiTest {
BigSwitchBcfApi _api;
HttpClient _client = mock(HttpClient.class);
HttpMethod _method;
@Before
public void setUp() {
HttpClientParams hmp = mock(HttpClientParams.class);
when(_client.getParams()).thenReturn(hmp);
_api = new BigSwitchBcfApi(){
@Override
protected HttpClient createHttpClient() {
return _client;
}
@Override
protected HttpMethod createMethod(String type, String uri, int port) {
return _method;
}
};
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithoutHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress(null);
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithEmptyHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress("");
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithoutUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername(null);
_api.setControllerPassword("mypassword");
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithEmptyUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("");
_api.setControllerPassword("mypassword");
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithoutPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword(null);
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectWithEmptyPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword("");
_api.executeUpdateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithoutHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress(null);
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithEmptyHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress("");
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithoutUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername(null);
_api.setControllerPassword("mypassword");
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithEmptyUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("");
_api.setControllerPassword("mypassword");
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithoutPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword(null);
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectWithEmptyPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword("");
_api.executeCreateObject(new String(), "/", Collections.<String, String> emptyMap());
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithoutHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress(null);
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeDeleteObject("/");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithEmptyHostname() throws BigSwitchBcfApiException {
_api.setControllerAddress("");
_api.setControllerUsername("myname");
_api.setControllerPassword("mypassword");
_api.executeDeleteObject("/");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithoutUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername(null);
_api.setControllerPassword("mypassword");
_api.executeDeleteObject("/");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithEmptyUsername() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("");
_api.setControllerPassword("mypassword");
_api.executeDeleteObject("/");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithoutPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword(null);
_api.executeDeleteObject("/");
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectWithEmptyPassword() throws BigSwitchBcfApiException {
_api.setControllerAddress("10.10.0.10");
_api.setControllerUsername("myname");
_api.setControllerPassword("");
_api.executeDeleteObject("/");
}
@Test
public void executeMethodTestOK() throws BigSwitchBcfApiException, HttpException, IOException {
GetMethod gm = mock(GetMethod.class);
when(gm.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeMethod(gm);
verify(gm, times(1)).getStatusCode();
}
@Test(expected = BigSwitchBcfApiException.class)
public void executeMethodTestUnauthorized() throws BigSwitchBcfApiException, IOException {
GetMethod gm = mock(GetMethod.class);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
when(gm.getStatusCode()).thenReturn(HttpStatus.SC_UNAUTHORIZED);
_api.executeMethod(gm);
}
@Test
public void testExecuteCreateObjectOK() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getResponseHeader("X-BSN-BVS-HASH-MATCH")).thenReturn(new Header("X-BSN-BVS-HASH-MATCH", UUID.randomUUID().toString()));
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
String hash = _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);assertNotEquals(hash, "");
assertNotEquals(hash, BigSwitchBcfApi.HASH_CONFLICT);
assertNotEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectConflict() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
_api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
}
@Test
public void testExecuteCreateObjectSlave() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
String hash = _api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
assertEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
assertEquals(_api.getControllerData().isMaster(), false);
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectFailure() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteCreateObjectException() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
_method = mock(PostMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
try {
_api.executeCreateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test
public void testExecuteUpdateObjectOK() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getResponseHeader("X-BSN-BVS-HASH-MATCH")).thenReturn(new Header("X-BSN-BVS-HASH-MATCH", UUID.randomUUID().toString()));
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
String hash = _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
assertNotEquals(hash, "");
assertNotEquals(hash, BigSwitchBcfApi.HASH_CONFLICT);
assertNotEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectConflict() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
}
@Test
public void testExecuteUpdateObjectSlave() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
String hash = _api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
assertEquals(hash, BigSwitchBcfApi.HASH_IGNORE);
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectFailure() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteUpdateObjectException() throws BigSwitchBcfApiException, IOException {
NetworkData network = new NetworkData();
_method = mock(PutMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new IOException());
try {
_api.executeUpdateObject(network, "/", Collections.<String, String> emptyMap());
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test
public void testExecuteDeleteObject() throws BigSwitchBcfApiException, IOException {
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
_api.executeDeleteObject("/");
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectFailure() throws BigSwitchBcfApiException, IOException {
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_INTERNAL_SERVER_ERROR);
Header header = mock(Header.class);
when(header.getValue()).thenReturn("text/html");
when(_method.getResponseHeader("Content-type")).thenReturn(header);
when(_method.getResponseBodyAsString()).thenReturn("Off to timbuktu, won't be back later.");
when(_method.isRequestSent()).thenReturn(true);
try {
_api.executeDeleteObject("/");
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test(expected = BigSwitchBcfApiException.class)
public void testExecuteDeleteObjectException() throws BigSwitchBcfApiException, IOException {
_method = mock(DeleteMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(_client.executeMethod((HttpMethod)any())).thenThrow(new HttpException());
try {
_api.executeDeleteObject("/");
} finally {
verify(_method, times(1)).releaseConnection();
}
}
@Test
public void testExecuteRetrieveControllerMasterStatus() throws BigSwitchBcfApiException, IOException {
_method = mock(GetMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_OK);
when(((HttpMethodBase)_method).getResponseBodyAsString(2048)).thenReturn("{'healthy': true, 'topologySyncRequested': false}");
_api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), "/", null);
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
assertEquals(_api.getControllerData().isMaster(), true);
}
@Test
public void testExecuteRetrieveControllerMasterStatusWithTopoConflict() throws BigSwitchBcfApiException, IOException {
_method = mock(GetMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_CONFLICT);
when(((HttpMethodBase)_method).getResponseBodyAsString(2048)).thenReturn("{'healthy': true, 'topologySyncRequested': true}");
_api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), "/", null);
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
assertEquals(_api.getControllerData().isMaster(), true);
}
@Test
public void testExecuteRetrieveControllerSlaveStatus() throws BigSwitchBcfApiException, IOException {
_method = mock(GetMethod.class);
when(_method.getStatusCode()).thenReturn(HttpStatus.SC_SEE_OTHER);
when(((HttpMethodBase)_method).getResponseBodyAsString(1024)).thenReturn("{'healthy': true, 'topologySyncRequested': false}");
_api.executeRetrieveObject(new TypeToken<ControlClusterStatus>() {
}.getType(), "/", null);
verify(_method, times(1)).releaseConnection();
verify(_client, times(1)).executeMethod(_method);
assertEquals(_api.getControllerData().isMaster(), false);
}
}

View File

@ -0,0 +1,431 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.network.resource;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.naming.ConfigurationException;
import org.junit.Before;
import org.junit.Test;
import com.cloud.agent.api.BcfAnswer;
import com.cloud.agent.api.CreateBcfRouterCommand;
import com.cloud.agent.api.CreateBcfSegmentCommand;
import com.cloud.agent.api.CreateBcfAttachmentCommand;
import com.cloud.agent.api.CreateBcfStaticNatCommand;
import com.cloud.agent.api.DeleteBcfSegmentCommand;
import com.cloud.agent.api.DeleteBcfAttachmentCommand;
import com.cloud.agent.api.DeleteBcfStaticNatCommand;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.SyncBcfTopologyCommand;
import com.cloud.agent.api.UpdateBcfAttachmentCommand;
import com.cloud.agent.api.UpdateBcfRouterCommand;
import com.cloud.host.Host;
import com.cloud.network.bigswitch.BigSwitchBcfApi;
import com.cloud.network.bigswitch.BigSwitchBcfApiException;
import com.cloud.network.bigswitch.Capabilities;
import com.cloud.network.bigswitch.ControlClusterStatus;
import com.cloud.network.bigswitch.FloatingIpData;
import com.cloud.network.bigswitch.NetworkData;
import com.cloud.network.bigswitch.AttachmentData;
import com.cloud.network.bigswitch.RouterData;
import com.cloud.network.bigswitch.TopologyData;
public class BigSwitchBcfResourceTest {
BigSwitchBcfApi _bigswitchBcfApi = mock(BigSwitchBcfApi.class);
BigSwitchBcfResource _resource;
Map<String, Object> _parameters;
String bcfAddress = "127.0.0.1";
String bcfUserName = "myname";
String bcfPassword = "mypassword";
@Before
public void setUp() throws ConfigurationException {
_resource = new BigSwitchBcfResource() {
@Override
protected BigSwitchBcfApi createBigSwitchBcfApi() {
return _bigswitchBcfApi;
}
};
_parameters = new HashMap<String, Object>();
_parameters.put("name", "bigswitchbcftestdevice");
_parameters.put("hostname", bcfAddress);
_parameters.put("guid", "aaaaa-bbbbb-ccccc");
_parameters.put("zoneId", "blublub");
_parameters.put("username", bcfUserName);
_parameters.put("password", bcfPassword);
}
@Test(expected = ConfigurationException.class)
public void resourceConfigureFailure() throws ConfigurationException {
_resource.configure("BigSwitchBcfResource", Collections.<String, Object> emptyMap());
}
@Test
public void resourceConfigure() throws ConfigurationException {
_resource.configure("BigSwitchBcfResource", _parameters);
verify(_bigswitchBcfApi).setControllerAddress(bcfAddress);
verify(_bigswitchBcfApi).setControllerUsername(bcfUserName);
verify(_bigswitchBcfApi).setControllerPassword(bcfPassword);
assertTrue("bigswitchbcftestdevice".equals(_resource.getName()));
/* Pretty lame test, but here to assure this plugin fails
* if the type name ever changes from L2Networking
*/
assertTrue(_resource.getType() == Host.Type.L2Networking);
}
@Test
public void testInitialization() throws ConfigurationException {
_resource.configure("BigSwitchBcfResource", _parameters);
StartupCommand[] sc = _resource.initialize();
assertTrue(sc.length == 1);
assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid()));
assertTrue("bigswitchbcftestdevice".equals(sc[0].getName()));
assertTrue("blublub".equals(sc[0].getDataCenter()));
}
@Test
public void testPingCommandStatusOk() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(true);
when(_bigswitchBcfApi.getControlClusterStatus()).thenReturn(ccs);
Capabilities cap = mock(Capabilities.class);
when(_bigswitchBcfApi.getCapabilities()).thenReturn(cap);
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping != null);
assertTrue(ping.getHostId() == 42);
assertTrue(ping.getHostType() == Host.Type.L2Networking);
}
@Test
public void testPingCommandStatusFail() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(false);
when(_bigswitchBcfApi.getControlClusterStatus()).thenReturn(ccs);
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping == null);
}
@Test
public void testPingCommandStatusApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
ControlClusterStatus ccs = mock(ControlClusterStatus.class);
when(ccs.getStatus()).thenReturn(false);
when(_bigswitchBcfApi.getControlClusterStatus()).thenThrow(new BigSwitchBcfApiException());
PingCommand ping = _resource.getCurrentStatus(42);
assertTrue(ping == null);
}
@Test
public void testCreateNetworkRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
NetworkData networkdata = mock(NetworkData.class);
NetworkData.Network network = mock(NetworkData.Network.class);
when(networkdata.getNetwork()).thenReturn(network);
when(network.getId()).thenReturn("cccc");
when(_bigswitchBcfApi.createNetwork((NetworkData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
CreateBcfSegmentCommand cmd = new CreateBcfSegmentCommand("tenantid", "tenantname",
(String)_parameters.get("guid"), "networkName", 0);
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testCreateNetworkApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
NetworkData networkdata = mock(NetworkData.class);
NetworkData.Network network = mock(NetworkData.Network.class);
when(networkdata.getNetwork()).thenReturn(network);
when(network.getId()).thenReturn("cccc");
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createNetwork((NetworkData)any());
CreateBcfSegmentCommand cmd = new CreateBcfSegmentCommand("tenantid", "tenantname",
(String)_parameters.get("guid"), "networkName", 0);
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).createNetwork((NetworkData)any());
}
@Test
public void testDeleteNetworkRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.deleteNetwork((String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand("tenantid", "networkid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testDeleteNetworkApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteNetwork((String)any(), (String)any());
DeleteBcfSegmentCommand cmd = new DeleteBcfSegmentCommand("tenantid", "networkid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).deleteNetwork((String)any(), (String)any());
}
@Test
public void testCreateAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
AttachmentData attachmentData = mock(AttachmentData.class);
AttachmentData.Attachment attachment = mock(AttachmentData.Attachment.class);
when(attachmentData.getAttachment()).thenReturn(attachment);
when(attachment.getId()).thenReturn("eeee");
when(_bigswitchBcfApi.createAttachment((String)any(), (String)any(), (AttachmentData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand("tenantid", "tenantname",
"networkid", "portid", "nicId", 100, "1.2.3.4", "aa:bb:cc:dd:ee:ff");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testCreateAttachmentApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
AttachmentData attachmentData = mock(AttachmentData.class);
AttachmentData.Attachment attachment = mock(AttachmentData.Attachment.class);
when(attachmentData.getAttachment()).thenReturn(attachment);
when(attachment.getId()).thenReturn("eeee");
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createAttachment((String)any(), (String)any(), (AttachmentData)any());
CreateBcfAttachmentCommand cmd = new CreateBcfAttachmentCommand("tenantid", "tenantname",
"networkid", "portid", "nicId", 100, "1.2.3.4", "aa:bb:cc:dd:ee:ff");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).createAttachment((String)any(), (String)any(), (AttachmentData)any());
}
@Test
public void testDeleteAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.deleteAttachment((String)any(), (String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new DeleteBcfAttachmentCommand("networkId", "portid", "tenantid"));
assertTrue(ans.getResult());
}
@Test
public void testDeleteAttachmentException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteAttachment((String)any(), (String)any(), (String)any());
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new DeleteBcfAttachmentCommand("networkId", "portid", "tenantid"));
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).deleteAttachment((String)any(), (String)any(), (String)any());
}
@Test
public void testUpdateAttachmentRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.modifyAttachment((String)any(), (String)any(), (AttachmentData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new UpdateBcfAttachmentCommand("networkId", "portId", "tenantId", "portname"));
assertTrue(ans.getResult());
}
@Test
public void testUpdateAttachmentException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyAttachment((String)any(), (String)any(), (AttachmentData)any());
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new UpdateBcfAttachmentCommand("networkId", "portId", "tenantId", "portname"));
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).modifyAttachment((String)any(), (String)any(), (AttachmentData)any());
}
@Test
public void testCreateStaticNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.createFloatingIp((String)any(), (FloatingIpData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
CreateBcfStaticNatCommand cmd = new CreateBcfStaticNatCommand("tenantid",
"networkid", "192.168.0.10", "10.4.4.100", "90:b1:1c:49:d8:56");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testCreateStaticNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createFloatingIp((String)any(), (FloatingIpData)any());
CreateBcfStaticNatCommand cmd = new CreateBcfStaticNatCommand("tenantid",
"networkid", "192.168.0.10", "10.4.4.100", "90:b1:1c:49:d8:56");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).createFloatingIp((String)any(), (FloatingIpData)any());
}
@Test
public void testDeleteStaticNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.deleteFloatingIp((String)any(), (String)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
DeleteBcfStaticNatCommand cmd = new DeleteBcfStaticNatCommand("tenantid",
"10.4.4.100");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testDeleteStaticNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).deleteFloatingIp((String)any(), (String)any());
DeleteBcfStaticNatCommand cmd = new DeleteBcfStaticNatCommand("tenantid",
"10.4.4.100");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).deleteFloatingIp((String)any(), (String)any());
}
@Test
public void testCreateRouterRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.createRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
CreateBcfRouterCommand cmd = new CreateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testCreateRouterApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).createRouter((String)any(), (RouterData)any());
CreateBcfRouterCommand cmd = new CreateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).createRouter((String)any(), (RouterData)any());
}
@Test
public void testCreateSourceNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.modifyRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testCreateSourceNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyRouter((String)any(), (RouterData)any());
UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).modifyRouter((String)any(), (RouterData)any());
}
@Test
public void testDeleteSourceNatRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
when(_bigswitchBcfApi.modifyRouter((String)any(), (RouterData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertTrue(ans.getResult());
}
@Test
public void testDeleteSourceNatApiException() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
doThrow(new BigSwitchBcfApiException()).when(_bigswitchBcfApi).modifyRouter((String)any(), (RouterData)any());
UpdateBcfRouterCommand cmd = new UpdateBcfRouterCommand("tenantid");
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(cmd);
assertFalse(ans.getResult());
verify(_bigswitchBcfApi, times(3)).modifyRouter((String)any(), (RouterData)any());
}
@Test
public void testSyncTopologyRetryOnce() throws ConfigurationException, BigSwitchBcfApiException {
_resource.configure("BigSwitchBcfResource", _parameters);
_resource.setTopology(new TopologyData());
when(_bigswitchBcfApi.syncTopology((TopologyData)any())).thenThrow(new BigSwitchBcfApiException())
.thenReturn(UUID.randomUUID().toString());
BcfAnswer ans = (BcfAnswer)_resource.executeRequest(new SyncBcfTopologyCommand(true, false));
assertTrue(ans.getResult());
}
}

View File

@ -65,7 +65,7 @@
<module>network-elements/palo-alto</module>
<module>network-elements/netscaler</module>
<module>network-elements/nicira-nvp</module>
<module>network-elements/bigswitch-vns</module>
<module>network-elements/bigswitch</module>
<module>network-elements/brocade-vcs</module>
<module>network-elements/midonet</module>
<module>network-elements/stratosphere-ssp</module>

20
scripts/util/qemu-ivs-ifup Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
/sbin/ifconfig $1 0.0.0.0 up
/usr/sbin/ivs-ctl add-port $1

View File

@ -2401,7 +2401,7 @@ public class ApiResponseHelper implements ResponseGenerator {
for (Network.Provider serviceProvider : serviceProviders) {
// return only Virtual Router/JuniperSRX/CiscoVnmc as a provider for the firewall
if (service == Service.Firewall
&& !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp)) {
&& !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX || serviceProvider == Provider.CiscoVnmc || serviceProvider == Provider.PaloAlto || serviceProvider == Provider.NuageVsp || serviceProvider == Provider.BigSwitchBcf)) {
continue;
}

View File

@ -1406,7 +1406,14 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
throw new InvalidParameterValueException("Vm ip is not set as dnat ip for this public ip");
}
StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, forRevoke);
String srcMac = null;
try {
srcMac = _networkModel.getNextAvailableMacAddressInNetwork(networkId);
} catch (InsufficientAddressCapacityException e) {
throw new CloudRuntimeException("Insufficient MAC address for static NAT instantiation.");
}
StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIp.getId(), dstIp, srcMac, forRevoke);
staticNats.add(staticNat);
return staticNats;
}

View File

@ -22,6 +22,7 @@ public class StaticNatImpl implements StaticNat {
long networkId;
long sourceIpAddressId;
String destIpAddress;
String sourceMacAddress;
boolean forRevoke;
public StaticNatImpl(long accountId, long domainId, long networkId, long sourceIpAddressId, String destIpAddress, boolean forRevoke) {
@ -31,6 +32,18 @@ public class StaticNatImpl implements StaticNat {
this.networkId = networkId;
this.sourceIpAddressId = sourceIpAddressId;
this.destIpAddress = destIpAddress;
this.sourceMacAddress = null;
this.forRevoke = forRevoke;
}
public StaticNatImpl(long accountId, long domainId, long networkId, long sourceIpAddressId, String destIpAddress, String sourceMacAddress, boolean forRevoke) {
super();
this.accountId = accountId;
this.domainId = domainId;
this.networkId = networkId;
this.sourceIpAddressId = sourceIpAddressId;
this.destIpAddress = destIpAddress;
this.sourceMacAddress = sourceMacAddress;
this.forRevoke = forRevoke;
}
@ -59,6 +72,11 @@ public class StaticNatImpl implements StaticNat {
return destIpAddress;
}
@Override
public String getSourceMacAddress() {
return sourceMacAddress;
}
@Override
public boolean isForRevoke() {
return forRevoke;

View File

@ -224,7 +224,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter,
Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter,
Provider.Ovs, Provider.NuageVsp);
Provider.Ovs, Provider.NuageVsp, Provider.BigSwitchBcf);
int _cleanupInterval;
int _maxNetworks;
@ -2431,4 +2431,4 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final StaticRoute route = _staticRouteDao.findById(routeId);
return applyStaticRoutesForVpc(route.getVpcId());
}
}
}

View File

@ -150,6 +150,7 @@ DROP TABLE IF EXISTS `cloud`.`nicira_nvp_nic_map`;
DROP TABLE IF EXISTS `cloud`.`s3`;
DROP TABLE IF EXISTS `cloud`.`template_s3_ref`;
DROP TABLE IF EXISTS `cloud`.`nicira_nvp_router_map`;
DROP TABLE IF EXISTS `cloud`.`external_bigswitch_bcf_devices`;
DROP TABLE IF EXISTS `cloud`.`external_bigswitch_vns_devices`;
DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroup_policy_map`;
DROP TABLE IF EXISTS `cloud`.`autoscale_vmgroup_vm_map`;

View File

@ -284,6 +284,24 @@ CREATE TABLE `cloud`.`brocade_network_vlan_map` (
CONSTRAINT `fk_brocade_network_vlan_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `cloud`.`external_bigswitch_vns_devices`;
CREATE TABLE `cloud`.`external_bigswitch_bcf_devices` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uuid` varchar(255) UNIQUE,
`physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which bigswitch bcf device is added',
`provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this bigswitch bcf device',
`device_name` varchar(255) NOT NULL COMMENT 'name of the bigswitch bcf device',
`host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external bigswitch bcf device',
`hostname` varchar(255) NOT NULL COMMENT 'host name or IP address for the bigswitch bcf device',
`username` varchar(255) NOT NULL COMMENT 'username for the bigswitch bcf device',
`password` varchar(255) NOT NULL COMMENT 'password for the bigswitch bcf device',
`nat` boolean NOT NULL COMMENT 'NAT support for the bigswitch bcf device',
`hash` varchar(255) NOT NULL COMMENT 'topology hash for the bigswitch bcf networks',
PRIMARY KEY (`id`),
CONSTRAINT `fk_external_bigswitch_bcf_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_external_bigswitch_bcf_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* As part of the separation of Xen and XenServer, update the column for the network labels */
ALTER TABLE `cloud`.`physical_network_traffic_types` CHANGE `xen_network_label` `xenserver_network_label` varchar(255) COMMENT 'The network name label of the physical device dedicated to this traffic on a XenServer host';

View File

@ -0,0 +1,776 @@
# 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 BigSwitchBcf 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,
ServiceOffering,
NetworkOffering,
VpcOffering,
Network,
PublicIPAddress,
FireWallRule,
NATRule,
Configurations)
from marvin.lib.common import (get_domain,
get_zone,
get_template)
from marvin.sshClient import SshClient
from marvin.codes import PASS
import subprocess
import time
class Services:
"""Test BigSwitchBcf 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": 'KVM',
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"net1_net2_aclrule": {
"protocol": "ICMP",
"cidrlist": '0.0.0.0/0',
},
"big_switch_bcf_device": {
"hostname": '10.212.1.104',
"username": 'admin',
"password": 'bsn',
"retrycount": '4',
"retryinterval": '60'
},
#services supported by Big Switch BCF for isolated networks.
"network_offering": {
"name": 'BCF network offering (marvin)',
"displaytext": 'BCF (marvin)',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,PortForwarding,Firewall',
"traffictype": 'GUEST',
"availability": 'Optional',
"serviceProviderList": {
"PortForwarding": 'VirtualRouter',
"Dhcp" : 'VirtualRouter',
"Connectivity" : 'BigSwitchBcf',
"StaticNat" : 'VirtualRouter',
"SourceNat" : 'VirtualRouter',
"Firewall" : 'VirtualRouter'
},
},
"vpc_network_offering": {
"name": 'BCF VPC network offering (marvin)',
"displaytext": 'BCF VPC (marvin)',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,PortForwarding,StaticNat,NetworkACL',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Dhcp": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter',
"Connectivity" : 'BigSwitchBcf'
},
},
"vpc_offering": {
"name": 'BCF VPC',
"displaytext": 'BCF VPC',
"supportedservices": 'Dhcp,SourceNat,PortForwarding,StaticNat,NetworkACL,Connectivity',
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/16'
},
"network": {
"name": "BCF network",
"displaytext": "BCF network",
},
"ostype": 'CentOS 5.3 (64-bit)',
"sleep": 60,
"timeout": 10
}
class TestBigSwitchBcf(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls._cleanup = []
cls.testClient = super(TestBigSwitchBcf, 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"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
# Get test parameters
cls.bigswitch_services = cls.services["big_switch_bcf_device"]
try:
# Get physical network
resp = listPhysicalNetworks.listPhysicalNetworksCmd()
resp.zoneid = cls.zone.id
physical_networks = cls.api_client.listPhysicalNetworks(resp)
if isinstance(physical_networks, list):
cls.debug("phy net %s" % physical_networks)
physical_network = physical_networks[1]
# Get bigswitch network service provider
resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd()
resp.name = 'BigSwitchBcf'
resp.physicalnetworkid = physical_network.id
nw_service_providers = cls.api_client.listNetworkServiceProviders(resp)
if isinstance(nw_service_providers, list):
bigswitch_provider = nw_service_providers[0]
cls.debug("net serv prov %s" % nw_service_providers)
else:
# Create bigswitch provider if not already existent
resp_add_nsp = addNetworkServiceProvider.addNetworkServiceProviderCmd()
resp_add_nsp.name = 'BigSwitchBcf'
resp_add_nsp.physicalnetworkid = physical_network.id
bigswitch_provider = cls.api_client.addNetworkServiceProvider(resp_add_nsp)
# add BCF controller
resp_add_device = addBigSwitchBcfDevice.addBigSwitchBcfDeviceCmd()
resp_add_device.physicalnetworkid = physical_network.id
resp_add_device.username = cls.bigswitch_services["username"]
resp_add_device.password = cls.bigswitch_services["password"]
resp_add_device.hostname = cls.bigswitch_services["hostname"]
resp_add_device.retrycount = cls.bigswitch_services["retrycount"]
resp_add_device.retryinterval = cls.bigswitch_services["retryinterval"]
cls.bigswitch = cls.api_client.addBigSwitchBcfDevice(resp_add_device)
if bigswitch_provider.state != 'Enabled':
cmd = updateNetworkServiceProvider.updateNetworkServiceProviderCmd()
cmd.id = bigswitch_provider.id
cmd.state = 'Enabled'
cls.api_client.updateNetworkServiceProvider(cmd)
# Create non-VPC network offering
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')
# Create VPC network offering
cls.vpc_network_offering = NetworkOffering.create(
cls.api_client,
cls.services["vpc_network_offering"],
conservemode=False
)
cls._cleanup.append(cls.vpc_network_offering)
cls.vpc_network_offering.update(cls.api_client, state='Enabled')
# Create VPC offering
cls.vpc_offering = VpcOffering.create(
cls.api_client,
cls.services["vpc_offering"]
)
cls._cleanup.append(cls.vpc_offering)
cls.vpc_offering.update(cls.api_client, state='Enabled')
# Create compute service offering
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_bcf(self):
"""Test basic workflow with BigSwitch BCF plugin
1. Create a non-VPC guest network
2. Create two VMs on the network
3. Add firewall rule to make virtual router pingable
4. Test ping to virtual router public IP
5. Add static NAT to vm_1, with firewall rule to allow ssh
6. Ssh to vm_1, ping vm_2 private address, ping google.com
"""
self.debug("STEP 1: 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("STEP 2: Deploying VMs in account: %s" % self.account.name)
vm_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=vm_1.id
)
self.debug(
"Verify listVirtualMachines response for virtual machine: %s" \
% vm_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"
)
vm_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=vm_2.id
)
self.debug(
"Verify listVirtualMachines response for virtual machine: %s" \
% vm_2.id
)
self.assertEqual(
isinstance(list_vm_response, list),
True,
"Check list response returns a valid list"
)
vm_response = list_vm_response[0]
self.assertEqual(
vm_response.state,
"Running",
"VM state should be running after deployment"
)
self.debug("STEP 3: Add FW rule to allow source nat ping")
src_nat_list = PublicIPAddress.list(
self.apiclient,
associatednetworkid=self.network.id,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
)
self.assertEqual(
isinstance(src_nat_list, list),
True,
"List Public IP should return a valid source NAT"
)
self.assertNotEqual(
len(src_nat_list),
0,
"Length of response from listPublicIp should not be 0"
)
src_nat = src_nat_list[0]
#Create Firewall rules on source NAT
fw_rule_icmp = FireWallRule.create(
self.apiclient,
ipaddressid=src_nat.id,
protocol='ICMP',
cidrlist=["0.0.0.0/0",]
)
self.debug("Created firewall rule: %s" % fw_rule_icmp.id)
self.debug("STEP 4: Trying to ping source NAT %s" % src_nat.ipaddress)
# User should be able to ping router via source nat ip
try:
self.debug("Trying to ping source NAT %s" % src_nat.ipaddress)
result = subprocess.call(
['ping', '-c 1', src_nat.ipaddress])
self.debug("Ping result: %s" % result)
# if ping successful, then result should be 0
self.assertEqual(
result,
0,
"Check if ping is successful or not"
)
except Exception as e:
self.fail("Ping failed for source NAT %s (%s)"
% (src_nat.ipaddress, e))
self.debug("STEP 5: Add static NAT to vm_1 with FW rule to allow SSH")
floating_ip_1 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=self.network.id,
)
self.debug("Associated %s with network %s" % (
floating_ip_1.ipaddress,
self.network.id
)
)
NATRule.create(
self.apiclient,
vm_1,
self.services["natrule"],
ipaddressid=floating_ip_1.ipaddress.id,
openfirewall=False,
networkid=self.network.id
)
# Should be able to SSH vm_1 via static nat, then ping vm_2 & Internet
try:
self.debug("STEP 6: SSH into vm_1: %s" % floating_ip_1)
ssh = vm_1.get_ssh_client(
ipaddress=floating_ip_1.ipaddress.ipaddress
)
self.debug("Ping vm_2 at %s" % vm_2.ipaddress)
# Ping vm_2
res_1 = ssh.execute("ping -c 1 %s" % vm_2.ipaddress)
self.debug("Ping to google.com from VM")
# Ping Internet
res_2 = ssh.execute("ping -c 1 www.google.com")
# res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212):
# icmp_req=1 ttl=57 time=25.9 ms
# --- www.l.google.com ping statistics ---
# 1 packets transmitted, 1 received, 0% packet loss, time 0ms
# rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms
except Exception as e:
self.fail("SSH Access failed: %s" % e)
self.debug("ping result1: %s" % res_1);
self.debug("ping result2: %s" % res_2);
result1 = str(res_1)
self.assertEqual(
result1.count("1 received"),
1,
"Ping vm_2 from vm_1 should be successful"
)
result2 = str(res_2)
self.assertEqual(
result2.count("1 received"),
1,
"Ping Internet from vm_1 should be successful"
)
# Deleting two test VMs
VirtualMachine.delete(vm_1, self.apiclient, expunge=True)
VirtualMachine.delete(vm_2, self.apiclient, expunge=True)
# Delete Network
Network.delete(self.network, self.apiclient)
return
@attr(tags = ["advancedns"])
def test_vpc_network_bcf(self):
"""Test VPC workflow with BigSwitch BCF plugin
1. Create a VPC with three networks
2. Create one VM on each of the three networks
3. Add firewall rule to make virtual router pingable
4. Test ping to virtual router public IP
5. Add static NAT to vm_1, with firewall rule to allow ssh
6. Add NAT rule to allow ping between net1 and net2
7. Ssh to vm_1, ping vm_2 private address, should succeed
8. continue ... ping vm_3 private address, should fail
9. continue ... ping Internet, should succeed
"""
self.debug("STEP 1: Creating VPC with VPC offering: %s" %
self.vpc_offering.id)
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
accountid=self.account.name,
domainid=self.account.domainid,
vpcofferingid=self.vpc_offering.id,
zoneid=self.zone.id
)
self.debug("Created VPC with ID: %s" % self.vpc.id)
# Creating network using the vpc network offering created
self.debug("Creating networks with vpc network offering: %s" %
self.vpc_network_offering.id)
net1 = Network.create(
self.apiclient,
self.services["vpc_network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.vpc_network_offering.id,
zoneid=self.zone.id,
gateway="10.0.100.1",
vpcid=vpc.id
)
self.debug("Created network with ID: %s" % net1.id)
net2 = Network.create(
self.apiclient,
self.services["vpc_network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.vpc_network_offering.id,
zoneid=self.zone.id,
gateway="10.0.101.1",
vpcid=vpc.id
)
self.debug("Created network with ID: %s" % net2.id)
net3 = Network.create(
self.apiclient,
self.services["vpc_network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.vpc_network_offering.id,
zoneid=self.zone.id,
gateway="10.0.102.0",
vpcid=vpc.id
)
self.debug("Created network with ID: %s" % net3.id)
self.debug("STEP 2: Deploying VMs in networks")
vm_1 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[ str(net1.id), ]
)
self.debug("Deployed VM in network: %s" % net1.id)
list_vm_response = VirtualMachine.list(
self.apiclient,
id=vm_1.id
)
self.debug(
"Verify listVirtualMachines response for virtual machine: %s" \
% vm_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"
)
vm_2 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[ str(net2.id), ]
)
self.debug("Deployed VM in network: %s" % net2.id)
list_vm_response = VirtualMachine.list(
self.apiclient,
id=vm_2.id
)
self.debug(
"Verify listVirtualMachines response for virtual machine: %s" \
% vm_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"
)
vm_3 = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[ str(net3.id), ]
)
self.debug("Deployed VM in network: %s" % net3.id)
list_vm_response = VirtualMachine.list(
self.apiclient,
id=vm_3.id
)
self.debug(
"Verify listVirtualMachines response for virtual machine: %s" \
% vm_3.id
)
self.assertEqual(
isinstance(list_vm_response, list),
True,
"Check list response returns a valid list"
)
vm_response = list_vm_response[0]
self.assertEqual(
vm_response.state,
"Running",
"VM state should be running after deployment"
)
self.debug("STEP 3: Add FW rule to allow source nat ping")
src_nat_list = PublicIPAddress.list(
self.apiclient,
account=self.account.name,
domainid=self.account.domainid,
listall=True,
issourcenat=True,
vpcid=vpc.id
)
self.assertEqual(
isinstance(src_nat_list, list),
True,
"List Public IP should return a valid source NAT"
)
self.assertNotEqual(
len(src_nat_list),
0,
"Length of response from listPublicIp should not be 0"
)
src_nat = src_nat_list[0]
#Create Firewall rules on source NAT
fw_rule_icmp = FireWallRule.create(
self.apiclient,
ipaddressid=src_nat.id,
protocol='ICMP',
cidrlist=["0.0.0.0/0",]
)
self.debug("Created firewall rule: %s" % fw_rule_icmp.id)
self.debug("STEP 4: Trying to ping source NAT %s" % src_nat.ipaddress)
# User should be able to ping router via source nat ip
try:
self.debug("Trying to ping source NAT %s" % src_nat.ipaddress)
result = subprocess.call(
['ping', '-c 1', src_nat.ipaddress])
self.debug("Ping result: %s" % result)
# if ping successful, then result should be 0
self.assertEqual(
result,
0,
"Check if ping is successful or not"
)
except Exception as e:
self.fail("Ping failed for source NAT %s (%s)"
% (src_nat.ipaddress, e))
self.debug("STEP 5: Add static NAT to vm_1 with FW rule to allow SSH")
floating_ip_1 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=net1.id,
vpcid=vpc.id
)
self.debug("Associated %s with network %s" % (
floating_ip_1.ipaddress,
net1.id
)
)
NATRule.create(
self.apiclient,
vm_1,
self.services["natrule"],
ipaddressid=floating_ip_1.ipaddress.id,
openfirewall=False,
networkid=net1.id,
vpcid=vpc.id
)
# Should be able to SSH vm_1 via static nat, then ping vm_2 & Internet
try:
self.debug("STEP 6: SSH into vm_1: %s" % floating_ip_1)
ssh = vm_1.get_ssh_client(
ipaddress=floating_ip_1.ipaddress.ipaddress
)
# self.debug("Ping vm_2 at %s" % vm_2.ipaddress)
# Ping to outsite world
# res_1 = ssh.execute("ping -c 1 %s" % vm_2.ipaddress)
# self.debug("Ping to google.com from VM")
# Ping to outsite world
# res_2 = ssh.execute("ping -c 1 www.google.com")
# res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212):
# icmp_req=1 ttl=57 time=25.9 ms
# --- www.l.google.com ping statistics ---
# 1 packets transmitted, 1 received, 0% packet loss, time 0ms
# rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms
except Exception as e:
self.fail("SSH Access failed: %s" % e)
# self.debug("ping result1: %s" % res_1);
# self.debug("ping result2: %s" % res_2);
# result1 = str(res_1)
# self.assertEqual(
# result1.count("1 received"),
# 1,
# "Ping vm_2 from vm_1 should be successful"
# )
# result2 = str(res_2)
# self.assertEqual(
# result2.count("1 received"),
# 1,
# "Ping Internet from vm_1 should be successful"
# )
# Deleting two test VMs
VirtualMachine.delete(vm_1, self.apiclient, expunge=True)
VirtualMachine.delete(vm_2, self.apiclient, expunge=True)
# Delete Network
Network.delete(self.network, self.apiclient)
return

View File

@ -138,7 +138,7 @@ known_categories = {
'Tags': 'Resource tags',
'NiciraNvpDevice': 'Nicira NVP',
'BrocadeVcsDevice': 'Brocade VCS',
'BigSwitchVnsDevice': 'BigSwitch VNS',
'BigSwitchBcfDevice': 'BigSwitch BCF',
'NuageVsp': 'Nuage VSP',
'AutoScale': 'AutoScale',
'Counter': 'AutoScale',

View File

@ -425,13 +425,13 @@
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
/instance/org.eclipse.jdt.ui/cleanup.use_this_for_non_static_field_access=true
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
/instance/org.eclipse.wst.sse.core/task-tag-projects-already-scanned=cloud-agent,cloud-api,cloud-apidoc,cloud-awsapi,cloud-cli,cloud-client-ui,cloud-console-proxy,cloud-core,cloud-devcloud,cloud-devcloud-kvm,cloud-developer,cloud-engine,cloud-engine-api,cloud-engine-components-api,cloud-engine-compute,cloud-engine-network,cloud-engine-orchestration,cloud-engine-schema,cloud-engine-service,cloud-engine-storage,cloud-engine-storage-backup,cloud-engine-storage-image,cloud-engine-storage-imagemotion,cloud-engine-storage-integration-test,cloud-engine-storage-snapshot,cloud-engine-storage-volume,cloud-framework-events,cloud-framework-ipc,cloud-framework-rest,cloud-marvin,cloud-mom-rabbitmq,cloud-patches,cloud-plugin-acl-static-role-based,cloud-plugin-api-discovery,cloud-plugin-api-limit-account-based,cloud-plugin-console-proxy,cloud-plugin-example-dns-notifier,cloud-plugin-host-allocator-random,cloud-plugin-hypervisor-baremetal,cloud-plugin-hypervisor-kvm,cloud-plugin-hypervisor-ovm,cloud-plugin-hypervisor-simulator,cloud-plugin-hypervisor-ucs,cloud-plugin-hypervisor-vmware,cloud-plugin-hypervisor-xen,cloud-plugin-netapp,cloud-plugin-network-elb,cloud-plugin-network-f5,cloud-plugin-network-netscaler,cloud-plugin-network-nvp,cloud-plugin-network-ovs,cloud-plugin-network-srx,cloud-plugin-network-vns,cloud-plugin-planner-user-concentrated-pod,cloud-plugin-planner-user-dispersing,cloud-plugin-snmp-alerts,cloud-plugin-storage-allocator-random,cloud-plugin-storage-image-s3,cloud-plugin-storage-volume-default,cloud-plugin-storage-volume-solidfire,cloud-plugin-syslog-alerts,cloud-plugin-user-authenticator-ldap,cloud-plugin-user-authenticator-md5,cloud-plugin-user-authenticator-plaintext,cloud-plugin-user-authenticator-saml2,cloud-plugin-user-authenticator-sha256salted,cloud-server,cloud-testclient,cloud-tools,cloud-usage,cloud-utils,cloud-vmware-base,cloudstack,cloudstack-framework,cloudstack-plugins,xapi,cloud-framework-jobs,cloud-plugin-host-anti-affinity,cloud-plugin-network-cisco-vnmc,cloud-plugin-network-midonet,cloud-secondary-storage,cloudstack-services,cloud-plugin-network-internallb,cloud-plugin-planner-implicit-dedication,cloudstack-service-console-proxy
/instance/org.eclipse.jdt.debug.ui/org.eclipse.debug.ui.ExpressionView.org.eclipse.jdt.debug.ui.show_null_entries=true
/instance/org.eclipse.jdt.ui/sp_cleanup.correct_indentation=false
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_source_code=true
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
/instance/org.eclipse.wst.sse.core/task-tag-projects-already-scanned=cloud-agent,cloud-api,cloud-apidoc,cloud-awsapi,cloud-cli,cloud-client-ui,cloud-console-proxy,cloud-core,cloud-devcloud,cloud-devcloud-kvm,cloud-developer,cloud-engine,cloud-engine-api,cloud-engine-components-api,cloud-engine-compute,cloud-engine-network,cloud-engine-orchestration,cloud-engine-schema,cloud-engine-service,cloud-engine-storage,cloud-engine-storage-backup,cloud-engine-storage-image,cloud-engine-storage-imagemotion,cloud-engine-storage-integration-test,cloud-engine-storage-snapshot,cloud-engine-storage-volume,cloud-framework-events,cloud-framework-ipc,cloud-framework-rest,cloud-marvin,cloud-mom-rabbitmq,cloud-patches,cloud-plugin-acl-static-role-based,cloud-plugin-api-discovery,cloud-plugin-api-limit-account-based,cloud-plugin-console-proxy,cloud-plugin-example-dns-notifier,cloud-plugin-host-allocator-random,cloud-plugin-hypervisor-baremetal,cloud-plugin-hypervisor-kvm,cloud-plugin-hypervisor-ovm,cloud-plugin-hypervisor-simulator,cloud-plugin-hypervisor-ucs,cloud-plugin-hypervisor-vmware,cloud-plugin-hypervisor-xen,cloud-plugin-netapp,cloud-plugin-network-elb,cloud-plugin-network-f5,cloud-plugin-network-netscaler,cloud-plugin-network-nvp,cloud-plugin-network-ovs,cloud-plugin-network-srx,cloud-plugin-network-bigswitch,cloud-plugin-planner-user-concentrated-pod,cloud-plugin-planner-user-dispersing,cloud-plugin-snmp-alerts,cloud-plugin-storage-allocator-random,cloud-plugin-storage-image-s3,cloud-plugin-storage-volume-default,cloud-plugin-storage-volume-solidfire,cloud-plugin-syslog-alerts,cloud-plugin-user-authenticator-ldap,cloud-plugin-user-authenticator-md5,cloud-plugin-user-authenticator-plaintext,cloud-plugin-user-authenticator-saml2,cloud-plugin-user-authenticator-sha256salted,cloud-server,cloud-testclient,cloud-tools,cloud-usage,cloud-utils,cloud-vmware-base,cloudstack,cloudstack-framework,cloudstack-plugins,xapi,cloud-framework-jobs,cloud-plugin-host-anti-affinity,cloud-plugin-network-cisco-vnmc,cloud-plugin-network-midonet,cloud-secondary-storage,cloudstack-services,cloud-plugin-network-internallb,cloud-plugin-planner-implicit-dedication,cloudstack-service-console-proxy
/instance/org.eclipse.jdt.debug.ui/org.eclipse.debug.ui.ExpressionView.org.eclipse.jdt.debug.ui.show_null_entries=true
/instance/org.eclipse.jdt.ui/sp_cleanup.correct_indentation=false
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_source_code=true
/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
/instance/org.eclipse.jdt.ui/cleanup.never_use_parentheses_in_expressions=true
@org.eclipse.debug.core=3.7.100.v20120521-2012

View File

@ -328,7 +328,7 @@ dictionary = {
'label.add.account.to.project': '<fmt:message key="label.add.account.to.project" />',
'label.add.ACL': '<fmt:message key="label.add.ACL" />',
'label.add.affinity.group': '<fmt:message key="label.add.affinity.group" />',
'label.add.BigSwitchVns.device': '<fmt:message key="label.add.BigSwitchVns.device" />',
'label.add.BigSwitchBcf.device': '<fmt:message key="label.add.BigSwitchBcf.device" />',
'label.add.by.cidr': '<fmt:message key="label.add.by.cidr" />',
'label.add.by': '<fmt:message key="label.add.by" />',
'label.add.by.group': '<fmt:message key="label.add.by.group" />',
@ -521,7 +521,7 @@ dictionary = {
'label.default.use': '<fmt:message key="label.default.use" />',
'label.default.view': '<fmt:message key="label.default.view" />',
'label.delete.affinity.group': '<fmt:message key="label.delete.affinity.group" />',
'label.delete.BigSwitchVns': '<fmt:message key="label.delete.BigSwitchVns" />',
'label.delete.BigSwitchBcf': '<fmt:message key="label.delete.BigSwitchBcf" />',
'label.delete.F5': '<fmt:message key="label.delete.F5" />',
'label.delete': '<fmt:message key="label.delete" />',
'label.delete.gateway': '<fmt:message key="label.delete.gateway" />',

View File

@ -452,6 +452,7 @@ under the License.
'message.configuring.public.traffic': '<fmt:message key="message.configuring.public.traffic" />',
'message.configuring.storage.traffic': '<fmt:message key="message.configuring.storage.traffic" />',
'message.confirm.action.force.reconnect': '<fmt:message key="message.confirm.action.force.reconnect" />',
'message.confirm.delete.BigSwitchBcf': '<fmt:message key="message.confirm.delete.BigSwitchBcf" />',
'message.confirm.delete.F5': '<fmt:message key="message.confirm.delete.F5" />',
'message.confirm.delete.BrocadeVcs': '<fmt:message key="message.confirm.delete.BrocadeVcs" />',
'message.confirm.delete.NetScaler': '<fmt:message key="message.confirm.delete.NetScaler" />',
@ -758,8 +759,9 @@ under the License.
'label.nicira.nvp.details': '<fmt:message key="label.nicira.nvp.details" />',
'label.added.brocade.vcs.switch': '<fmt:message key="label.added.brocade.vcs.switch" />',
'label.brocade.vcs.details': '<fmt:message key="label.brocade.vcs.details" />',
'label.added.new.bigswitch.vns.controller': '<fmt:message key="label.added.new.bigswitch.vns.controller" />',
'label.bigswitch.vns.details': '<fmt:message key="label.bigswitch.vns.details" />',
'label.added.new.bigswitch.bcf.controller': '<fmt:message key="label.added.new.bigswitch.bcf.controller" />',
'label.bigswitch.bcf.details': '<fmt:message key="label.bigswitch.bcf.details" />',
'label.bigswitch.bcf.nat': '<fmt:message key="label.bigswitch.bcf.nat" />',
'label.dedicate': '<fmt:message key="label.dedicate" />',
'label.dedicate.pod': '<fmt:message key="label.dedicate.pod" />',
'label.pod.dedicated': '<fmt:message key="label.pod.dedicated" />',

View File

@ -2286,7 +2286,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' || $(this).val() == 'NuageVsp' || $(this).val() == 'NuageVspVpc') {
if ($(this).val() == 'InternalLbVm' || $(this).val() == 'VpcVirtualRouter' || $(this).val() == 'Netscaler' || $(this).val() == 'NuageVsp' || $(this).val() == 'NuageVspVpc' || $(this).val() == 'BigSwitchBcf') {
$(this).attr('disabled', false);
} else {
$(this).attr('disabled', true);
@ -3578,25 +3578,29 @@
});
networkServiceObjs.push({
name: 'Gateway',
provider: [{name: 'VpcVirtualRouter'}]
provider: [{name: 'VpcVirtualRouter'},
{name: 'BigSwitchBcf'}]
});
networkServiceObjs.push({
name: 'StaticNat',
provider: [
{name: 'VpcVirtualRouter'},
{name: 'NuageVsp'}]
{name: 'NuageVsp'},
{name: 'BigSwitchBcf'}]
});
networkServiceObjs.push({
name: 'SourceNat',
provider: [
{name: 'VpcVirtualRouter'},
{name: 'NuageVsp'}]
{name: 'NuageVsp'},
{name: 'BigSwitchBcf'}]
});
networkServiceObjs.push({
name: 'NetworkACL',
provider: [
{name: 'VpcVirtualRouter'},
{name: 'NuageVsp'}]
{name: 'NuageVsp'},
{name: 'BigSwitchBcf'}]
});
networkServiceObjs.push({
name: 'PortForwarding',
@ -3608,12 +3612,14 @@
});
networkServiceObjs.push({
name: 'Vpn',
provider: [{name: 'VpcVirtualRouter'}]
provider: [{name: 'VpcVirtualRouter'},
{name: 'BigSwitchBcf'}]
});
networkServiceObjs.push({
name: 'Connectivity',
provider: [
{name: 'BigSwitchBcf'},
{name: 'NiciraNvp'},
{name: 'Ovs'},
{name: 'JuniperContrailVpcRouter'},

View File

@ -6024,14 +6024,14 @@
}
}
},
// BigSwitch Vns provider detail view
bigswitchVns: {
// BigSwitch BCF provider detail view
bigswitchBcf: {
type: 'detailView',
id: 'bigswitchVnsProvider',
label: 'label.bigswitchVns',
id: 'bigswitchBcfProvider',
label: 'label.bigswitchBcf',
viewAll: {
label: 'label.devices',
path: '_zone.bigswitchVnsDevices'
path: '_zone.bigswitchBcfDevices'
},
tabs: {
details: {
@ -6047,31 +6047,43 @@
}
}],
dataProvider: function (args) {
refreshNspData("BigSwitchVns");
refreshNspData("BigSwitchBcf");
var providerObj;
$(nspHardcodingArray).each(function () {
if (this.id == "bigswitchVns") {
if (this.id == "bigswitchBcf") {
providerObj = this;
return false;
}
});
args.response.success({
data: providerObj,
actionFilter: networkProviderActionFilter('bigswitchVns')
actionFilter: networkProviderActionFilter('bigswitchBcf')
});
}
}
},
actions: {
add: {
label: 'label.add.BigSwitchVns.device',
label: 'label.add.BigSwitchBcf.device',
createForm: {
title: 'label.add.BigSwitchVns.device',
title: 'label.add.BigSwitchBcf.device',
preFilter: function (args) {
},
fields: {
host: {
label: 'label.ip.address'
label: 'label.host.name'
},
username: {
label: 'label.username'
},
password: {
label: 'label.password',
isPassword: true
},
nat: {
label: 'label.bigswitch.bcf.nat',
isBoolean: true,
isChecked: false
},
numretries: {
label: 'label.numretries',
@ -6080,14 +6092,14 @@
}
},
action: function (args) {
if (nspMap[ "bigswitchVns"] == null) {
if (nspMap[ "bigswitchBcf"] == null) {
$.ajax({
url: createURL("addNetworkServiceProvider&name=BigSwitchVns&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
url: createURL("addNetworkServiceProvider&name=BigSwitchBcf&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
dataType: "json",
async: true,
success: function (json) {
var jobId = json.addnetworkserviceproviderresponse.jobid;
var addBigSwitchVnsProviderIntervalID = setInterval(function () {
var addBigSwitchBcfProviderIntervalID = setInterval(function () {
$.ajax({
url: createURL("queryAsyncJobResult&jobId=" + jobId),
dataType: "json",
@ -6096,18 +6108,18 @@
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
clearInterval(addBigSwitchVnsProviderIntervalID);
clearInterval(addBigSwitchBcfProviderIntervalID);
if (result.jobstatus == 1) {
nspMap[ "bigswitchVns"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider;
addBigSwitchVnsDevice(args, selectedPhysicalNetworkObj, "addBigSwitchVnsDevice", "addbigswitchvnsdeviceresponse", "bigswitchvnsdevice")
nspMap[ "bigswitchBcf"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider;
addBigSwitchBcfDevice(args, selectedPhysicalNetworkObj, "addBigSwitchBcfDevice", "addbigswitchbcfdeviceresponse", "bigswitchbcfdevice")
} else if (result.jobstatus == 2) {
alert("addNetworkServiceProvider&name=BigSwitchVns failed. Error: " + _s(result.jobresult.errortext));
alert("addNetworkServiceProvider&name=BigSwitchBcf failed. Error: " + _s(result.jobresult.errortext));
}
}
},
error: function (XMLHttpResponse) {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
alert("addNetworkServiceProvider&name=BigSwitchVns failed. Error: " + errorMsg);
alert("addNetworkServiceProvider&name=BigSwitchBcf failed. Error: " + errorMsg);
}
});
},
@ -6115,12 +6127,12 @@
}
});
} else {
addBigSwitchVnsDevice(args, selectedPhysicalNetworkObj, "addBigSwitchVnsDevice", "addbigswitchvnsdeviceresponse", "bigswitchvnsdevice")
addBigSwitchBcfDevice(args, selectedPhysicalNetworkObj, "addBigSwitchBcfDevice", "addbigswitchbcfdeviceresponse", "bigswitchbcfdevice")
}
},
messages: {
notification: function (args) {
return 'label.add.BigSwitchVns.device';
return 'label.add.BigSwitchBcf.device';
}
},
notification: {
@ -6131,7 +6143,7 @@
label: 'label.enable.provider',
action: function (args) {
$.ajax({
url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "bigswitchVns"].id + "&state=Enabled"),
url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "bigswitchBcf"].id + "&state=Enabled"),
dataType: "json",
success: function (json) {
var jid = json.updatenetworkserviceproviderresponse.jobid;
@ -6162,7 +6174,7 @@
label: 'label.disable.provider',
action: function (args) {
$.ajax({
url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "bigswitchVns"].id + "&state=Disabled"),
url: createURL("updateNetworkServiceProvider&id=" + nspMap[ "bigswitchBcf"].id + "&state=Disabled"),
dataType: "json",
success: function (json) {
var jid = json.updatenetworkserviceproviderresponse.jobid;
@ -6193,7 +6205,7 @@
label: 'label.shutdown.provider',
action: function (args) {
$.ajax({
url: createURL("deleteNetworkServiceProvider&id=" + nspMap[ "bigswitchVns"].id),
url: createURL("deleteNetworkServiceProvider&id=" + nspMap[ "bigswitchBcf"].id),
dataType: "json",
success: function (json) {
var jid = json.deletenetworkserviceproviderresponse.jobid;
@ -12709,11 +12721,11 @@
}
}
},
bigswitchVnsDevices: {
id: 'bigswitchVnsDevices',
bigswitchBcfDevices: {
id: 'bigswitchBcfDevices',
title: 'label.devices',
listView: {
id: 'bigswitchVnsDevices',
id: 'bigswitchBcfDevices',
fields: {
hostname: {
label: 'label.bigswitch.controller.address'
@ -12721,14 +12733,35 @@
},
actions: {
add: {
label: 'label.add.BigSwitchVns.device',
label: 'label.add.BigSwitchBcf.device',
createForm: {
title: 'label.add.BigSwitchVns.device',
title: 'label.add.BigSwitchBcf.device',
preFilter: function (args) {
},
fields: {
host: {
label: 'label.ip.address'
label: 'label.ip.address',
validation: {
required: true
}
},
username: {
label: 'label.username',
validation: {
required: true
}
},
password: {
label: 'label.password',
isPassword: true,
validation: {
required: true
}
},
nat: {
label: 'label.bigswitch.bcf.nat',
isBoolean: true,
isChecked: false
},
numretries: {
label: 'label.numretries',
@ -12737,14 +12770,14 @@
}
},
action: function (args) {
if (nspMap[ "bigswitchVns"] == null) {
if (nspMap[ "bigswitchBcf"] == null) {
$.ajax({
url: createURL("addNetworkServiceProvider&name=BigSwitchVns&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
url: createURL("addNetworkServiceProvider&name=BigSwitchBcf&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
dataType: "json",
async: true,
success: function (json) {
var jobId = json.addnetworkserviceproviderresponse.jobid;
var addBigSwitchVnsProviderIntervalID = setInterval(function () {
var addBigSwitchBcfProviderIntervalID = setInterval(function () {
$.ajax({
url: createURL("queryAsyncJobResult&jobId=" + jobId),
dataType: "json",
@ -12753,18 +12786,18 @@
if (result.jobstatus == 0) {
return;
} else {
clearInterval(addBigSwitchVnsProviderIntervalID);
clearInterval(addBigSwitchBcfProviderIntervalID);
if (result.jobstatus == 1) {
nspMap[ "bigswitchVns"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider;
addBigSwitchVnsDevice(args, selectedPhysicalNetworkObj, "addBigSwitchVnsDevice", "addbigswitchvnsdeviceresponse", "bigswitchvnsdevice")
nspMap[ "bigswitchBcf"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider;
addBigSwitchBcfDevice(args, selectedPhysicalNetworkObj, "addBigSwitchBcfDevice", "addbigswitchbcfdeviceresponse", "bigswitchbcfdevice")
} else if (result.jobstatus == 2) {
alert("addNetworkServiceProvider&name=BigSwitchVns failed. Error: " + _s(result.jobresult.errortext));
alert("addNetworkServiceProvider&name=BigSwitchBcf failed. Error: " + _s(result.jobresult.errortext));
}
}
},
error: function (XMLHttpResponse) {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
alert("addNetworkServiceProvider&name=BigSwitchVns failed. Error: " + errorMsg);
alert("addNetworkServiceProvider&name=BigSwitchBcf failed. Error: " + errorMsg);
}
});
},
@ -12772,13 +12805,13 @@
}
});
} else {
addBigSwitchVnsDevice(args, selectedPhysicalNetworkObj, "addBigSwitchVnsDevice", "addbigswitchvnsdeviceresponse", "bigswitchvnsdevice")
addBigSwitchBcfDevice(args, selectedPhysicalNetworkObj, "addBigSwitchBcfDevice", "addbigswitchbcfdeviceresponse", "bigswitchbcfdevice")
}
},
messages: {
notification: function (args) {
return 'label.added.new.bigswitch.vns.controller';
return 'label.added.new.bigswitch.bcf.controller';
}
},
notification: {
@ -12788,7 +12821,7 @@
},
dataProvider: function (args) {
$.ajax({
url: createURL("listBigSwitchVnsDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
url: createURL("listBigSwitchBcfDevices&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
data: {
page: args.page,
pageSize: pageSize
@ -12796,7 +12829,7 @@
dataType: "json",
async: false,
success: function (json) {
var items = json.listbigswitchvnsdeviceresponse.bigswitchvnsdevice;
var items = json.listbigswitchbcfdeviceresponse.bigswitchbcfdevice;
args.response.success({
data: items
});
@ -12804,25 +12837,25 @@
});
},
detailView: {
name: 'label.bigswitch.vns.details',
name: 'label.bigswitch.bcf.details',
actions: {
'remove': {
label: 'label.delete.BigSwitchVns',
label: 'label.delete.BigSwitchBcf',
messages: {
confirm: function (args) {
return 'message.confirm.delete.BigSwitchVns';
return 'message.confirm.delete.BigSwitchBcf';
},
notification: function (args) {
return 'label.delete.BigSwitchVns';
return 'label.delete.BigSwitchBcf';
}
},
action: function (args) {
$.ajax({
url: createURL("deleteBigSwitchVnsDevice&vnsdeviceid=" + args.context.bigswitchvnsDevices[0].vnsdeviceid),
url: createURL("deleteBigSwitchBcfDevice&bcfdeviceid=" + args.context.bigswitchBcfDevices[0].bcfdeviceid),
dataType: "json",
async: true,
success: function (json) {
var jid = json.deletebigswitchvnsdeviceresponse.jobid;
var jid = json.deletebigswitchbcfdeviceresponse.jobid;
args.response.success({
_custom: {
jobId: jid
@ -12840,20 +12873,20 @@
details: {
title: 'label.details',
fields:[ {
vnsdeviceid: {
bcfdeviceid: {
label: 'label.id'
},
hostname: {
label: 'label.ip.address'
label: 'label.host.name'
}
}],
dataProvider: function (args) {
$.ajax({
url: createURL("listBigSwitchVnsDevices&vnsdeviceid=" + args.context.bigswitchVnsDevices[0].vnsdeviceid),
url: createURL("listBigSwitchBcfDevices&bcfdeviceid=" + args.context.bigswitchBcfDevices[0].bcfdeviceid),
dataType: "json",
async: true,
success: function (json) {
var item = json.listbigswitchvnsdeviceresponse.bigswitchvnsdevice[0];
var item = json.listbigswitchbcfdeviceresponse.bigswitchbcfdevice[0];
args.response.success({
data: item
});
@ -20159,11 +20192,14 @@
});
}
function addBigSwitchVnsDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
function addBigSwitchBcfDevice(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) {
var array1 =[];
array1.push("&physicalnetworkid=" + physicalNetworkObj.id);
array1.push("&hostname=" + todb(args.data.host));
array1.push("&username=" + args.data.username);
array1.push("&password=" + args.data.password);
array1.push("&nat=" + (args.data.nat == 'on' ? "true": "false"));
$.ajax({
url: createURL(apiCmd + array1.join("")),
dataType: "json",
@ -20905,8 +20941,8 @@
case "BrocadeVcs":
nspMap[ "brocadeVcs"] = items[i];
break;
case "BigSwitchVns":
nspMap[ "bigswitchVns"] = items[i];
case "BigSwitchBcf":
nspMap[ "bigswitchBcf"] = items[i];
break;
case "Ovs":
nspMap[ "Ovs"] = items[i];
@ -20947,9 +20983,9 @@
state: nspMap.brocadeVcs ? nspMap.brocadeVcs.state: 'Disabled'
},
{
id: 'bigswitchVns',
name: 'BigSwitch Vns',
state: nspMap.bigswitchVns ? nspMap.bigswitchVns.state: 'Disabled'
id: 'bigswitchBcf',
name: 'BigSwitch BCF',
state: nspMap.bigswitchBcf ? nspMap.bigswitchBcf.state: 'Disabled'
},
{
id: 'BaremetalDhcpProvider',

View File

@ -713,8 +713,8 @@
value: 'STT'
}).html('STT'),
$('<option>').attr({
value: 'VNS'
}).html('VNS'),
value: 'BCF_SEGMENT'
}).html('BCF_SEGMENT'),
$('<option>').attr({
value: 'SSP'
}).html('SSP'),