You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pe...@apache.org on 2025/06/24 22:19:59 UTC
(cloudstack) 01/02: FR01: Netris Integration (#1)
This is an automated email from the ASF dual-hosted git repository.
pearl11594 pushed a commit to branch support-acls-for-ipv6
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit 604137624db49e852c812728bac838068417b4a0
Author: Nicolas Vazquez <ni...@gmail.com>
AuthorDate: Tue May 20 06:49:35 2025 -0300
FR01: Netris Integration (#1)
* Add Netris module and Add netris provider
* Fix
* Add Netris Provider to the zone creation wizard
* add steps to zone wizard for adding netris controller and public traffic
* cleanup
* Add missing config key
* Add routed mode offerings for Netris VPC (#3)
* Add routed mode offerings for Netris VPC
* update vpc offering name
* generalize the offering creation method for network providers
* log
* remove debug log
* fix failing build
* Add dependency and Netris API client (#4)
* Add dependency and first approach to Netris API client
* Fix authentication and create Netris API client, in progress sites listing
* Fix get sites
* Support for listing VPCs (#5)
* List tenants
* Delegate API classes creation to the SDK and simply invoke the desired API class through CloudStack (#7)
* Delegate API classes creation to the SDK and simply invoke the desired API class through CloudStack
* Pass default auth scheme for now
* Support adding netris provider to CloudStack and Netris VPC Creation (#6)
* Support adding netris provider to CloudStack
* revert marvin change
* add license and perform session check when provider is added
* add license and remove unused import
* fix build failure - uunused imports
* address comments
* fix provider name
* add Netris network element
* add license
* Add netris management APIs and netris service provider
* add license
* revert change
* remove other network elements from Netris element
* fix api name in doc generator
* remove logs
* move session alive check to CheckHealthCommand exec
* Fix zone creation wizard to configure netris provider
* Upgrade GSON version - from PR 8756
* Add additional parametes to the add Netris provider API
* add netris as a host
* add additional params to the resoponse and update UI
* Rename site to site_name
* Create Netris VPC (#8)
* Delegate API classes creation to the SDK and simply invoke the desired API class through CloudStack (#7)
* Delegate API classes creation to the SDK and simply invoke the desired API class through CloudStack
* Pass default auth scheme for now
* Drop for_nsx and for_tungten columns in favour of checking the provider on the ntwserviceprovider map table
* Remove missing setForTungsten occurrence
* Remove forNsx from VPC offerings
* Create Netris VPC
* Fix VPC offerings listing and remove unused dao
* Create VPC fixes
* Upgrade GSON version - from PR 8756
* Fix VPC creation response by using the latest SDK code
* Fix unit test
* Remove unused import
* Fix NSX unit tests after refactoring
* Add Netris key to the VLAN Details table (#10)
* Add Netris key to the VLAN Details table
* update for_<provider> column to be generic
* Fix VPC and add IPAM allocation for the VPC CIDR (#9)
* Fix VPC and add IPAM allocation for the VPC CIDR
* Remove VPC logic
* Use zoneId accountId and domainId on resources creation
* Fix naming
* Fix VR public nic issue
* Fix Netris Public IP for VPC source NAT allocation
* Add Netris VPC Subnets and vNets (#11)
* Add Netris VPC Subnets and vNets
* fix compilation errors
* Add netris subnet
* refactor naming convention to differentiate between VPC tiers and Isolated networks
* revert marvin change
* fix constructor - build failure
* Add support to filter netris offerings, delete netris provider when zone is being deleted
* Fix build
* Fix VPC creation
* Fix vnet creation
* unnecesary log
---------
Co-authored-by: nvazquez <ni...@gmail.com>
---------
Co-authored-by: Pearl Dsilva <pe...@gmail.com>
---------
Co-authored-by: nvazquez <ni...@gmail.com>
* Fix unit tests
* Add support to delete VNets and Subnets (#13)
* Add support to delete VNets and Subnets
* Add support to delete vnet resources
* Add support to delete vnet resources
* extract code to method
---------
Co-authored-by: nvazquez <ni...@gmail.com>
* Add missing suffix return (#14)
* Set up Netris Public range on new zone addition (#15)
* Set up Netris Public range on new zone addition
* Add dependency to calculate subnet containing a start and end IP
* Remove unused import
* Move dependency to the netris module
* Rename Netris IP range
* Refactor logic
* Revert "Refactor logic"
This reverts commit 7ec36a81320444c37e7bb914dd895060b663411b.
* Fix setup range after adding Netris Provider
* Fix VXLAN range adding on zone creation
* Pass VXLAN ID during creation of Netris vNets (#16)
* add zone params to accepts management vnet
* Release vxlan associated to the netris broadcast domain type
* handle update network broadcast uri
* Update Subnet purpose for Netris Public Traffic (#17)
* Update Subnet purpose for Netris Public Traffic
* search for existing subnet of common purpose type
* Fix VR Public IP address (#20)
* Fix VR Public IP address
* Do not set the Public IP range on Netris side that is not part of the Netris IP Public Pool
* Leave only systemvms tag for the first element
* Fix NSX compatibility
* Pass network gateway instead of network CIDR for Netris vNet creation (#21)
* Run moodifyvxlan script if broadcast domain type is Netris (#18)
* Add support to create Netris VPC / Network offerings (#22)
* Add support to create Netris VPC / Network offerings
* fix support services for netris provider type
* Phase4 - Add support for Source NAT, Static NAT and Port Forwarding (#19)
* Run moodifyvxlan script if broadcast domain type is Netris
* Add Netris NAT offerings
* Add support to add Source nat rules for Natted offering
* fix api params while creating Netris source NAT rule
* Add support to add and delete source nat rule on netris
* Add support to create /32 NAT subnet
* Add support to add and delete Static NAT rules in Netris (#23)
* Add support to add and delete Static NAT rules in Netris
* fix static nat creation on netris & removal of subnet on deletion of static nat rule
* remove nat subnet after deltion of the static nat rule
* add check to see if subnet already exists and add license header
* Add port forwarding rules as DNAT rules in Netris (#24)
* Add port forwarding rules as DNAT rules in Netris
* Fixes
* Allow removing DNAT rules
* Fixes
* Fix subnet search
* Fix update SNAT only for SNAT rules
* Address comments
* Fix
* Fix netris pom xml
* Fix SNAT rule creation
* Fix IP and port placements (#27)
* Fix IP and port placements
* fix dnat to IP for PF rules
* change dnatport
---------
Co-authored-by: Nicolas Vazquez <ni...@gmail.com>
* List only Netris Public IPs for NAT operations (#26)
* List only Netris Public IPs for NAT operations
* rename getter and change type
* fix failing unit tests
* list all IPs if forProvider is not passed
* fix list public IPs for external providers with additional IP range
* filter provider Ips in a zone with external provider setup
* Prevent acquiring IP that is not from the external provider range
* formating
---------
Co-authored-by: nvazquez <ni...@gmail.com>
* Support to pass provider when creating public ip range and create IPAM on Netris (#28)
* UI: support to pass provider when creating public ip range
* prevent adding public ip range for a provider that isnt supported in zone
* Create public range on Netris when created on CloudStack
---------
Co-authored-by: nvazquez <ni...@gmail.com>
* Revert UI filtration for public IPs (#29)
* Fix issue with pagination of public addresses listed after filtering for external providers
* Revert UI filteration for public IPs for external network provider enabled zones
* Fix unit tests (#30)
* Add Netris Tag parameter to the Network provider and fix zone creation wizard (#33)
* Add Netris Tag parameter to the Network provider
* remove unused import
* Fix public IP ranges creation on zone creation (#34)
* use single quotes
---------
Co-authored-by: Nicolas Vazquez <ni...@gmail.com>
* Fix SourceAddress for SNAt to VPC cidr (#35)
* Fix VPC/network offering service list for external network providers in Routed mode (#32)
* Fix network offering service list for external network providers in Routed mode
* filter out unsupported services based on network mode
* fix supported services list for vpc offering for external providers in Routed mode
* Add support to add and delete and update static routes on Netris (#37)
* Add support to add static routes in Netris
* support to delete static routes on netris
* add defensive check for nextHop
* Add support to update static routes
* add state
* pass empty list for switched to avoid timeout
* Netris: search static route by name and next hop if exists
---------
Co-authored-by: Wei Zhou <we...@apache.org>
* Netris FR1b: Support Remote Access VPN and Site-to-Site VPN in VPC VR (#41)
* Static Routes: support nexthop
* Update api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
Co-authored-by: Pearl Dsilva <pe...@gmail.com>
* PR#10064 VR: apply iptables rules when add/remove static routes
* PR#10065 UI: fix cannot open 'Edit tags' modal for static routes
* PR#10066 Static Routes: fix check on wrong global configuration
* PR#10067 VR: fix site-2-site VPN if split connections is enabled
* PR#10081 server: do not allocate nic on public network for NSX VPC VR
* PR#10082 UI: create VPC network offering with conserve mode
* PR#10083 VR: allow outgoing traffic from RAS/VPN clients
* PR#10086 server: fix typo removeaccessvpn in VirtualRouterElement
* server: Add check on Public IP for remote access VPN
* Revert "PR#10083 VR: allow outgoing traffic from RAS/VPN clients"
This reverts commit 2f9b9f428947cac91de322fbdf4a980902a1c0a0.
* VPC: fetch same used IP for domain router if VR is not Source NAT
* VR: pass has_public_network to VR and configure RA/S2S VPN left peers
* Revert "PR#10081 server: do not allocate nic on public network for NSX VPC VR"
This reverts commit 809e269ed6b361d9df1fcef6537762c5612863e0.
* VPC: fetch same used IP for domain router if VR is not Source NAT (v2)
* VR: fix /etc/hosts and nameservers in dnsmasq.conf if VPC VR is not guest gateway
prior to this PR
```
root@r-1167-VM:~# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 r-1167-VM
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.21.1.33 dummy-vpc-vpn-001
172.21.1.1 r-1167-VM data-server
root@r-1167-VM:~# cat /etc/dnsmasq.d/cloud.conf
dhcp-hostsfile=/etc/dhcphosts.txt
listen-address=127.0.0.1,172.21.1.234
dhcp-range=set:interface-eth1-0,172.21.1.234,static
dhcp-option=tag:interface-eth1-0,15,cs2cloud.internal
dhcp-option=tag:interface-eth1-0,6,172.21.1.1,10.0.32.1,8.8.8.8
dhcp-option=tag:interface-eth1-0,3,172.21.1.1
dhcp-option=eth1,26,1500
dhcp-option=tag:interface-eth1-0,1,255.255.255.0
```
the lines should be
```
172.21.1.234 r-1167-VM data-server
dhcp-option=tag:interface-eth1-0,6,10.0.32.1,8.8.8.8
```
* server: Enable static NAT for Domain router if it is not Source NAT
* server: Enable static NAT for Domain router on UI
* server: assign Public IP to VPC VR and enable static nat if VR is not Source NAT
* server: configure dns1 if VR is not Source NAT
* server: remove check on Firewall service when list network service providers
* UI: remove dot from message.enabled.vpn
* systemvm: add default route via first guest gateway if VR does not have public IP/interface
* VR: add fw_dhcpserver for shared network
* VR: pass has_public_network to VR and configure RA/S2S VPN left peers (v2)
* UI: fix request error when create a VPC tier in a non-Netris/NSX env
* systemvm: add default route via first guest gateway (v2)
* VR: configure iptables rules for S2S vpn on first guest interface
* VR: allow FORWARD to guest interfaces if VR is not Public
* VR: configure remote access vpn on first guest interface if not public
* VR: fix error 789 in RA VPN client when both RA and S2S are configured
* server: Apply Static Route for RA/S2S VPN in VPC VR
* VR: do not set mark for Public interface when VR is not really public
* VPN: do not disable static nat if it is used by a RA/S2S VPN
* server: skip check on network conserve mode if disable/enable RA VPN on Router IP
* server: set forRouter to false when release a IP
* VR: diable IP spoofing protection on default guest network
* VR: fix iptables rules only when only S2S vpn is enabled
* UI: show 'VPN Connections' section
* VPC: new methods to configure/reconfigure Static NAT for VPC VR
* API: set Type in ip address response to DomainRouter if it is used by VR
* server: do not allow IP release if it is used by RA or S2S VPN gateway
* VR: check if interface is added
* VR: add default route only when ip is associated to first guest interface
* VR: fix ipsec conf for l2tp and s2s vpn
* server: save placeholder IP for VPC VR to fix the new VR IP when vpc tier is auto-shutdown
* server: get non-placeholder NIC for VPC VR
* VR: wait 15 seconds after starting password server
* server: fix unable to configure static nat due to 'invalid virtual machine id'
* UI: fix link of router in info card
* VPC: apply static route for VPC VPN if needed (refactoring)
* server: fix VR IP of first VPC tier is the VM gateway
* server: update or remove all existing static routes when shutdown a network
* server: update ipaddress after disabling static nat to fix vpc deletion issue
* servr: disable remote access VPN as part of VPC dstroy
* server: apply static routes when implement a vpc tier
* server: apply static routes even if next hop is null
* server: fix Cannot invoke "com.cloud.vm.NicProfile.getRequestedIPv4()" because "requested" is null
* Netris: Update Vpn provider to VpcVirtualRouter
* Netris: Add Vpn service to network offerings and networks
* server: fix CIDR of VPN ip range
* server: set isVrGuestGateway by SoureNat/Gateway service with Provider.VPCVirtualRouter
* VR: password server takes 10-15 seconds to start if VR IP is not configured in /etc/hosts
* Netris: add back routesPutBody.setStateStatus
* engine/schema: remove SQL changes in schema-41910to42000.sql
---------
Co-authored-by: Pearl Dsilva <pe...@gmail.com>
* Add support for Gateway service for Netris VPC and network offerings (#39)
* Add support for Gateway service for Netris VPC and network offerings
* Restore UserData service
* add gateway only to vpc service
* Add support for gateway service for external network providers for networks in routed mode
* add support for gateway svc
* Revert "add support for gateway svc"
This reverts commit 06645cd1c6d08a81ede5d1431497ea3f2efdc5dc.
* Fix VPC offering creation
* Fix VR public NIC after Gateway service is set to Netris
---------
Co-authored-by: nvazquez <ni...@gmail.com>
* Netris VPN: Fix s2s vpn status update and isolated network implementation (#42)
* server: fix NPE when deploy vm on isolated network
* vpn: fix s2s vpn status is not updated
Prior to this fix
```
java.lang.IllegalArgumentException: Class com.cloud.agent.api.CheckS2SVpnConnectionsAnswer declares multiple JSON fields named 'details'; conflict is caused by fields com.cloud.agent.api.CheckS2SVpnConnectionsAnswer#details and com.cloud.agent.api.Answer#details
at com.cloud.agent.transport.ResponseTest.testCheckS2SVpnConnectionsAnswer(ResponseTest.java:42)
```
* test: fix test_01_vpn_usage as now it is only possible to create VPN on Source NAT if it uses VR
* VR: fix unable to create remote access VPN on regular isolated network
the error is
```
File "/opt/cloud/bin/configure.py", line 1242, in process
self.remoteaccessvpn_iptables(self.dbag['public_interface'], public_ip, self.dbag[public_ip])
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
KeyError: 'public_interface'
```
* Release NAT IP subnet when VPC is removed or IP is released (#44)
* Release NAT IP subnet when VPC is removed or IP is released
* add license
* Add support to add IPv6 Public IP range as IPAM Allocation / Subnet on Netris (#36)
* Add support to add IPv6 Public IP range as IPAM Allocation / Subnet on Netris
* Add ipam alloc and subnet for the ipv6 subnet associated to the vpc tier network
* remove commented code
* Phase5 - Support for ACLs in Netris (#31)
* Add support for Netris ACLs
* acl support
* Make acl api call to netris to create the rule
* refactor add acl rule to populate the right fields
* support icmp type acl rule
* acl rule creation - move netrisnetworkRule
* Update ACL naming on Netris
* Add support for Deletion of netris acls
* Add support to delete and re-order ACL rules
* support creation of default acl rules and replacing acl rules
* fix NSXNetworkRule
* Add global routing flag on subnet creation (#45)
* Support change snat ip (#46)
* Support updating VPC Source NAT IP
* Optimize code
* Update source NAT IP
* Fix naming convention for NAT subnets to follow other resources (#47)
* Fix naming convention for NAT subnets to follow other resources
* Use vpc ID for nat subnets
* Use new nat subnet name for deletion of static nat rule
* fix naming convevntion for nat subnet
* Keep Vpn service to default VPC offering with Natted mode only (#50)
* Add Vpn service to default VPC offering with Routed mode
* Revert change on VPC offering and fix VPN service only for Netris NAT mode
* Validate if given CIDR belongs to a bigger allocation in Netris before creating the zone-level allocation (#48)
* Validate if given CIDR belongs to a bigger allocation in Netris before creating
* rename method
* Phase5 - Support for LB - create, delete and Update operations (#49)
* Add support for Netris ACLs
* acl support
* Make acl api call to netris to create the rule
* refactor add acl rule to populate the right fields
* support icmp type acl rule
* acl rule creation - move netrisnetworkRule
* Update ACL naming on Netris
* Add support for Deletion of netris acls
* Add support to delete and re-order ACL rules
* support creation of default acl rules and replacing acl rules
* fix NSXNetworkRule
* Fix naming convention for NAT subnets to follow other resources
* Use vpc ID for nat subnets
* Phase5 - Support for LB - create, delete and Update operations
* Use new nat subnet name for deletion of static nat rule
* add support to add netris lb rule
* support deletion of LB rule on Netris
* add checks when editing unsupported fields of LB rule for Netris and hide columns on the UI
* fix test failure
* fix imports
* add license
* address comments
* Enable Autoscaling on Netris for CPU and memory (#51)
* Enable Autoscaling on Netris for CPU and memory
* Fix monitor autoscale group and cleanup
* Rename autoscaling group method
* Integrate Autoscaling by allowing to update LB rules
* Refactor according to the SDK changes
* Fix the test failures noticed on #44 (#52)
* Increase code coverage (#54)
* Increase code coverage
* More unit tests
* Remove credentials and mock api client
* NetrisResource tests
* Fix unit test
* Add support to add and remove ACL rules when CIDR list is passed when creating LB rules (#53)
* Add support to add and remove ACL rules when CIDR list is passed when creating LB rules
* add deny all rule
* delete the deny rule as well
* Fix build (#57)
* Prevent Index Out of Bounds exception when naming IPAM subnets (#58)
* Prevent Index Out of Bounds exception when naming IPAM subnets
* fix linter
* Delete netris IPv6 subnet (#59)
* Netris VPN: add static route when update a non-existent static route (#60)
* Fix VPC tier creation failure - prevent creating IPv6 IPAM allocation if it already exists (#61)
* Update netris VPC and tier name (#56)
* Update netris VPC and tier name
* add support to update vpc tier name
* add license
* support editing names of dual stack VPCs
* VR/server: configure default gateway and RA/S2S VPN on the IP/interface with minimum network_id (#43)
* server: fix NPE when deploy vm on isolated network
* vpn: fix s2s vpn status is not updated
Prior to this fix
```
java.lang.IllegalArgumentException: Class com.cloud.agent.api.CheckS2SVpnConnectionsAnswer declares multiple JSON fields named 'details'; conflict is caused by fields com.cloud.agent.api.CheckS2SVpnConnectionsAnswer#details and com.cloud.agent.api.Answer#details
at com.cloud.agent.transport.ResponseTest.testCheckS2SVpnConnectionsAnswer(ResponseTest.java:42)
```
* test: fix test_01_vpn_usage as now it is only possible to create VPN on Source NAT if it uses VR
* VR: fix unable to create remote access VPN on regular isolated network
the error is
```
File "/opt/cloud/bin/configure.py", line 1242, in process
self.remoteaccessvpn_iptables(self.dbag['public_interface'], public_ip, self.dbag[public_ip])
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
KeyError: 'public_interface'
```
* VR/server: configure default gateway and RA/S2S VPN on the IP/interface with minimum network_id
* Don't add deny rule if no CIDR list is passed (#62)
* Hide the Stickiness Configure button for Netris Load Balancers (#72)
* Update IPAM subnet purpose to nat before NAT operations if its different (#71)
* Netris VPN: create vpc gateway with specified IP (#63)
* Netris: fix UnsupportedOperationException when create VPC offering with NATTED mode (#75)
fixes
```
2025-03-21T10:42:55,039 ERROR [c.c.a.ApiServer] (qtp1513608173-21:[ctx-f9c7f002, ctx-bcfe846d]) (logid:e12e798f) unhandled exception executing api command: [Ljava.lang.String;@3a1416cd java.lang.UnsupportedOperationException
at java.base/java.util.AbstractList.add(AbstractList.java:153)
at java.base/java.util.AbstractList.add(AbstractList.java:111)
at org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd.getServiceProviderMapForExternalProvider(CreateVPCOfferingCmd.java:248)
```
* [UI] Zone wizard creation improvements - rename hostname to url and remove port for Netris Provider (#77)
* [UI] Zone wizard creation improvements - rename hostname to url and remove port for Netris Provider
* Fix schema column for url instead of hostname
* Fix Static NAT rules naming (#83)
* Netris: create VPN gateway with specified public IP on UI (#82)
* Netris vpn: apply static routes when start or delete a VPN connection (#85)
* Netris VPN: apply static routes when start S2S VPN
* Netris: list static routes and revoke the routes which are not needed
* Netris: use route name (x.x.x.0/x) instead of prefix (x.x.x.0) and get clean cidr list
* Netris VPN: fix NPE when list static routes
* Update plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
* Delete IPv6 allocation after tier removal on VPC with dual stack offering (#86)
* Netris pass v6 gateway (#87)
* pass v6 gateway to netris
* pass v6 gateway to netris
* refactor to address comments
* remove imports
* [VR] Fix IPv6 NIC IP on the VR (#89)
* Add support to edit ACL rules (#74)
* Add support to edit ACL rules
* add support to update acl rules
* remove test file
* VR: advertise SLAAC prefix only if VR is gateway (#91)
* Make reorder ACL items invoke Netris controller (#90)
* VR: fix radvd misconfiguration for non-netris env (#92)
* [VR] Fix object comparisson to string comparisson on python (#93)
* Fix unit tests for ACL (#94)
* Use the previously assigned vNet for Netris Network when it transitions to Implemented state after gc (#88)
* Use the previously assigned vNet for Netris Network when it transitions to Implemented state after gc
* Fix unit tests
---------
Co-authored-by: nvazquez <ni...@gmail.com>
---------
Co-authored-by: Pearl Dsilva <pe...@gmail.com>
Co-authored-by: Wei Zhou <we...@apache.org>
---
.../cloud/configuration/ConfigurationService.java | 16 +
api/src/main/java/com/cloud/event/EventTypes.java | 2 +
api/src/main/java/com/cloud/network/IpAddress.java | 1 +
api/src/main/java/com/cloud/network/Network.java | 1 +
api/src/main/java/com/cloud/network/Networks.java | 3 +-
.../com/cloud/network/SDNProviderNetworkRule.java | 139 +-
.../com/cloud/network/Site2SiteVpnConnection.java | 2 +-
.../com/cloud/network/element/NetworkElement.java | 7 +
.../element/PortForwardingServiceProvider.java | 28 +
.../com/cloud/network/element/VpcProvider.java | 2 +
.../java/com/cloud/network/guru/NetworkGuru.java | 4 +
.../com/cloud/network/netris/NetrisLbBackend.java | 26 +-
.../cloud/network/netris/NetrisNetworkRule.java | 108 ++
.../com/cloud/network/netris/NetrisProvider.java | 15 +-
.../com/cloud/network/netris/NetrisService.java | 67 +
.../java/com/cloud/network/vpc/StaticRoute.java | 5 +-
.../com/cloud/network/vpc/StaticRouteProfile.java | 22 +-
.../java/com/cloud/network/vpc/VpcOffering.java | 4 +-
.../cloud/network/vpc/VpcProvisioningService.java | 2 +-
.../java/com/cloud/network/vpc/VpcService.java | 2 +-
.../java/com/cloud/offering/NetworkOffering.java | 6 +-
.../org/apache/cloudstack/api/ApiConstants.java | 11 +
.../admin/network/CreateNetworkOfferingCmd.java | 56 +-
.../command/admin/vlan/CreateVlanIpRangeCmd.java | 13 +-
.../command/admin/vpc/CreateVPCOfferingCmd.java | 56 +-
.../user/address/ListPublicIpAddressesCmd.java | 7 +
.../api/command/user/vpc/CreateStaticRouteCmd.java | 51 +-
.../api/command/user/vpn/CreateVpnGatewayCmd.java | 13 +-
.../cloudstack/api/response/AsyncJobResponse.java | 9 -
.../response/ClusterDrsPlanMigrationResponse.java | 12 +-
.../cloudstack/api/response/IPAddressResponse.java | 6 +
.../cloudstack/api/response/NetworkResponse.java | 16 -
.../api/response/StaticRouteResponse.java | 24 +-
.../cloudstack/api/response/SystemVmResponse.java | 8 -
.../api/response/VlanIpRangeResponse.java | 10 +-
.../cloudstack/api/response/ZoneResponse.java | 13 +
client/pom.xml | 5 +
.../agent/api/CheckS2SVpnConnectionsAnswer.java | 1 -
.../cloud/agent/api/SetupGuestNetworkCommand.java | 9 +
.../facade/SetGuestNetworkConfigItem.java | 1 +
.../virtualnetwork/model/GuestNetwork.java | 9 +
.../cloud/agent/transport/ArrayTypeAdaptor.java | 12 +-
.../com/cloud/agent/transport/ResponseTest.java | 46 +
deps/install-non-oss.sh | 3 +
.../service/NetworkOrchestrationService.java | 6 +
.../cloud/configuration/ConfigurationManager.java | 5 +-
.../main/java/com/cloud/network/addr/PublicIp.java | 4 +
.../java/com/cloud/network/rules/RulesManager.java | 2 +
.../com/cloud/network/vpc/NetworkACLManager.java | 2 +-
.../java/com/cloud/network/vpc/VpcManager.java | 17 +
.../engine/orchestration/NetworkOrchestrator.java | 74 +-
.../src/main/java/com/cloud/dc/dao/VlanDao.java | 2 +
.../main/java/com/cloud/dc/dao/VlanDaoImpl.java | 27 +
.../com/cloud/network/dao/IPAddressDaoImpl.java | 1 +
.../java/com/cloud/network/dao/IPAddressVO.java | 12 +
...teVpnGatewayDao.java => NetrisProviderDao.java} | 5 +-
...ewayDaoImpl.java => NetrisProviderDaoImpl.java} | 41 +-
.../com/cloud/network/dao/RemoteAccessVpnDao.java | 2 +
.../cloud/network/dao/RemoteAccessVpnDaoImpl.java | 7 +
.../cloud/network/dao/Site2SiteVpnGatewayDao.java | 2 +
.../network/dao/Site2SiteVpnGatewayDaoImpl.java | 8 +
.../cloud/network/element/NetrisProviderVO.java | 265 +++
.../java/com/cloud/network/vpc/StaticRouteVO.java | 35 +-
.../java/com/cloud/network/vpc/VpcOfferingVO.java | 11 -
.../network/vpc/dao/VpcOfferingServiceMapDao.java | 5 +
.../vpc/dao/VpcOfferingServiceMapDaoImpl.java | 19 +
.../network/vpc/dao/VpcServiceMapDaoImpl.java | 11 +-
.../com/cloud/offerings/NetworkOfferingVO.java | 24 -
.../src/main/java/com/cloud/vm/dao/NicDao.java | 4 +
.../src/main/java/com/cloud/vm/dao/NicDaoImpl.java | 20 +
.../spring-engine-schema-core-daos-context.xml | 1 +
.../resources/META-INF/db/schema-41910to42000.sql | 37 +
.../db/views/cloud.network_offering_view.sql | 2 -
.../META-INF/db/views/cloud.vpc_offering_view.sql | 1 -
.../networkservice/BaremetalDhcpElement.java | 6 +
.../networkservice/BaremetalPxeElement.java | 6 +
.../networkservice/BaremetalUserdataElement.java | 6 +
.../hypervisor/kvm/resource/BridgeVifDriver.java | 13 +-
.../network/element/CiscoNexusVSMElement.java | 7 +-
.../cluster/KubernetesClusterManagerImpl.java | 1 -
.../cloudstack/metrics/MetricsServiceImpl.java | 2 +-
.../cloudstack/response/HostMetricsResponse.java | 10 -
.../cloud/network/element/BigSwitchBcfElement.java | 6 +
.../cloud/network/element/BrocadeVcsElement.java | 6 +
.../cloud/network/element/CiscoVnmcElement.java | 5 +
.../cloudstack/network/element/DnsNotifier.java | 6 +
.../element/ElasticLoadBalancerElement.java | 6 +
.../cloudstack/element/GloboDnsElement.java | 6 +
.../element/InternalLoadBalancerElement.java | 6 +
.../contrail/management/ContrailElementImpl.java | 5 +
.../contrail/management/ContrailManagerImpl.java | 6 +-
.../management/ContrailVpcElementImpl.java | 5 +
plugins/network-elements/netris/pom.xml | 44 +
.../apache/cloudstack/StartupNetrisCommand.java | 11 +-
.../api/AddOrUpdateNetrisStaticRouteCommand.java | 48 +
.../agent/api/CreateNetrisACLCommand.java | 120 ++
.../agent/api/CreateNetrisVnetCommand.java | 85 +
.../agent/api/CreateNetrisVpcCommand.java | 16 +-
.../agent/api/CreateOrUpdateNetrisACLCommand.java | 120 ++
...reateOrUpdateNetrisLoadBalancerRuleCommand.java | 90 +
.../agent/api/CreateOrUpdateNetrisNatCommand.java | 149 ++
.../agent/api/DeleteNetrisACLCommand.java | 46 +-
.../api/DeleteNetrisLoadBalancerRuleCommand.java | 52 +
.../agent/api/DeleteNetrisNatRuleCommand.java | 72 +
.../agent/api/DeleteNetrisStaticRouteCommand.java | 10 +-
.../agent/api/DeleteNetrisVnetCommand.java | 51 +
.../agent/api/DeleteNetrisVpcCommand.java | 15 +-
.../agent/api/ListNetrisStaticRoutesAnswer.java | 28 +-
.../agent/api/ListNetrisStaticRoutesCommand.java | 10 +-
.../apache/cloudstack/agent/api/NetrisAnswer.java | 15 +-
.../apache/cloudstack/agent/api/NetrisCommand.java | 71 +
.../cloudstack/agent/api/ReleaseNatIpCommand.java | 15 +-
.../agent/api/SetupNetrisPublicRangeCommand.java | 31 +-
.../agent/api/UpdateNetrisVnetCommand.java | 51 +
.../agent/api/UpdateNetrisVpcCommand.java | 17 +-
.../api/command/AddNetrisProviderCmd.java | 123 ++
.../api/command/DeleteNetrisProviderCmd.java} | 45 +-
.../api/command/ListNetrisProvidersCmd.java | 73 +
.../api/response/NetrisProviderResponse.java | 135 ++
.../cloudstack/resource/NetrisPortGroup.java | 12 +-
.../apache/cloudstack/resource/NetrisResource.java | 441 +++++
.../resource/NetrisResourceObjectUtils.java | 103 +
.../apache/cloudstack/service/NetrisApiClient.java | 100 +
.../cloudstack/service/NetrisApiClientImpl.java | 2004 ++++++++++++++++++++
.../apache/cloudstack/service/NetrisElement.java} | 875 ++++-----
.../service/NetrisGuestNetworkGuru.java} | 186 +-
.../cloudstack/service/NetrisProviderService.java | 26 +-
.../service/NetrisProviderServiceImpl.java | 217 +++
.../service/NetrisPublicNetworkGuru.java} | 64 +-
.../cloudstack/service/NetrisServiceImpl.java | 532 ++++++
.../core/spring-netris-core-managers-context.xml | 31 +
.../META-INF/cloudstack/netris/module.properties | 21 +
.../cloudstack/netris/spring-netris-context.xml | 41 +
.../resource/NetrisResourceObjectUtilsTest.java | 109 ++
.../cloudstack/resource/NetrisResourceTest.java | 141 ++
.../service/NetrisApiClientImplTest.java | 103 +
.../cloudstack/service/NetrisElementTest.java | 141 ++
.../service/NetrisGuestNetworkGuruTest.java | 230 +++
.../service/NetrisPublicNetworkGuruTest.java | 225 +++
.../cloudstack/service/NetrisServiceImplTest.java | 18 +-
.../cloud/network/element/NetscalerElement.java | 5 +
.../cloud/network/element/NiciraNvpElement.java | 5 +
.../api/command/DeleteNsxControllerCmd.java | 3 +-
.../apache/cloudstack/resource/NsxNetworkRule.java | 353 +---
.../apache/cloudstack/service/NsxApiClient.java | 13 +-
.../org/apache/cloudstack/service/NsxElement.java | 148 +-
.../cloudstack/service/NsxGuestNetworkGuru.java | 9 -
.../cloudstack/service/NsxPublicNetworkGuru.java | 18 +-
.../apache/cloudstack/service/NsxServiceImpl.java | 17 +-
.../cloudstack/service/NsxApiClientTest.java | 6 +-
.../apache/cloudstack/service/NsxElementTest.java | 42 +-
.../service/NsxPublicNetworkGuruTest.java | 10 +-
.../network/opendaylight/OpendaylightElement.java | 6 +
.../java/com/cloud/network/element/OvsElement.java | 6 +
.../element/PaloAltoExternalFirewallElement.java | 6 +
.../cloudstack/network/element/SspElement.java | 6 +
.../command/ConfigTungstenFabricServiceCmd.java | 1 -
.../network/tungsten/service/TungstenElement.java | 6 +
plugins/pom.xml | 2 +
pom.xml | 2 +-
.../main/java/com/cloud/api/ApiResponseHelper.java | 72 +-
.../cloud/api/query/dao/DataCenterJoinDaoImpl.java | 23 +-
.../api/query/dao/VpcOfferingJoinDaoImpl.java | 9 +-
.../cloud/api/query/vo/NetworkOfferingJoinVO.java | 20 -
.../com/cloud/api/query/vo/VpcOfferingJoinVO.java | 8 -
.../cloud/api/response/ApiResponseSerializer.java | 4 +-
.../configuration/ConfigurationManagerImpl.java | 94 +-
.../deploy/DeploymentPlanningManagerImpl.java | 2 +-
.../com/cloud/network/IpAddressManagerImpl.java | 88 +
.../java/com/cloud/network/NetworkModelImpl.java | 9 +-
.../java/com/cloud/network/NetworkServiceImpl.java | 58 +-
.../com/cloud/network/SDNProviderOpObject.java | 8 +-
.../com/cloud/network/as/AutoScaleManagerImpl.java | 14 +-
.../network/element/ConfigDriveNetworkElement.java | 6 +
.../network/element/SecurityGroupElement.java | 6 +
.../network/element/VirtualRouterElement.java | 8 +-
.../network/element/VpcVirtualRouterElement.java | 5 +
.../network/guru/ExternalGuestNetworkGuru.java | 5 +-
.../com/cloud/network/guru/GuestNetworkGuru.java | 18 +-
.../com/cloud/network/guru/PublicNetworkGuru.java | 14 +-
.../network/lb/LoadBalancingRulesManagerImpl.java | 15 +
.../cloud/network/router/CommandSetupHelper.java | 11 +-
.../cloud/network/router/NetworkHelperImpl.java | 10 +-
.../cloud/network/router/NicProfileHelperImpl.java | 4 +-
.../router/VirtualNetworkApplianceManagerImpl.java | 8 +
.../VpcVirtualNetworkApplianceManagerImpl.java | 20 +-
.../com/cloud/network/rules/RulesManagerImpl.java | 35 +-
.../cloud/network/vpc/NetworkACLManagerImpl.java | 11 +-
.../cloud/network/vpc/NetworkACLServiceImpl.java | 11 +-
.../java/com/cloud/network/vpc/VpcManagerImpl.java | 561 +++++-
.../network/vpn/RemoteAccessVpnManagerImpl.java | 72 +-
.../cloud/network/vpn/Site2SiteVpnManagerImpl.java | 76 +-
.../com/cloud/server/ConfigurationServerImpl.java | 71 +-
.../com/cloud/server/ManagementServerImpl.java | 32 +-
.../deployment/RouterDeploymentDefinition.java | 19 +-
.../RouterDeploymentDefinitionBuilder.java | 4 +
.../deployment/VpcRouterDeploymentDefinition.java | 6 +-
.../ConfigurationManagerImplTest.java | 4 +
.../com/cloud/network/NetworkModelImplTest.java | 8 +-
.../cloud/network/as/AutoScaleManagerImplTest.java | 16 +-
.../cloud/network/lb/UpdateLoadBalancerTest.java | 7 +-
.../com/cloud/server/ManagementServerImplTest.java | 10 +
.../cloud/vpc/MockConfigurationManagerImpl.java | 4 +-
.../java/com/cloud/vpc/NetworkACLServiceTest.java | 6 +
.../vpc/dao/MockVpcOfferingServiceMapDaoImpl.java | 11 +
.../deployment/RouterDeploymentDefinitionTest.java | 3 +
.../VpcRouterDeploymentDefinitionTest.java | 3 +
.../networkoffering/CreateNetworkOfferingTest.java | 20 +-
.../cloudstack/service/NetrisServiceMockTest.java | 134 ++
.../src/test/resources/createNetworkOffering.xml | 2 +
systemvm/debian/opt/cloud/bin/configure.py | 42 +-
systemvm/debian/opt/cloud/bin/cs/CsAddress.py | 110 +-
systemvm/debian/opt/cloud/bin/cs/CsConfig.py | 3 +
systemvm/debian/opt/cloud/bin/cs/CsDatabag.py | 7 +
systemvm/debian/opt/cloud/bin/cs/CsDhcp.py | 4 +-
systemvm/debian/opt/cloud/bin/cs/CsGuestNetwork.py | 10 +-
systemvm/debian/opt/cloud/bin/cs/CsRoute.py | 21 +
.../debian/opt/cloud/bin/cs/CsVpcGuestNetwork.py | 15 +-
systemvm/debian/opt/cloud/bin/passwd_server_ip.py | 13 +-
test/integration/smoke/test_usage.py | 12 +-
tools/apidoc/gen_toc.py | 4 +
ui/public/locales/en.json | 32 +-
ui/src/components/CheckBoxSelectPair.vue | 8 +-
ui/src/components/view/InfoCard.vue | 2 +-
ui/src/config/section/infra/phynetworks.js | 2 +-
ui/src/config/section/network.js | 3 +-
ui/src/views/AutogenView.vue | 4 -
ui/src/views/infra/network/IpRangesTabPublic.vue | 21 +
ui/src/views/infra/network/ServiceProvidersTab.vue | 45 +-
ui/src/views/infra/network/TrafficTypesTab.vue | 2 +-
ui/src/views/infra/zone/IpAddressRangeForm.vue | 20 +-
ui/src/views/infra/zone/PhysicalNetworksTab.vue | 2 +-
ui/src/views/infra/zone/ZoneWizard.vue | 2 +-
ui/src/views/infra/zone/ZoneWizardLaunchZone.vue | 73 +-
.../infra/zone/ZoneWizardNetworkSetupStep.vue | 90 +-
.../zone/ZoneWizardPhysicalNetworkSetupStep.vue | 1 +
ui/src/views/network/IpAddressesTab.vue | 22 +-
ui/src/views/network/LoadBalancing.vue | 41 +-
ui/src/views/network/PublicIpResource.vue | 31 +-
ui/src/views/network/StaticRoutesTab.vue | 131 +-
ui/src/views/network/VpcTab.vue | 133 +-
ui/src/views/network/VpcTiersTab.vue | 6 +-
ui/src/views/network/VpnDetails.vue | 164 +-
ui/src/views/offering/AddNetworkOffering.vue | 156 +-
ui/src/views/offering/AddVpcOffering.vue | 100 +-
.../main/java/com/cloud/utils/net/NetUtils.java | 34 +
.../test/java/com/cloud/utils/LogUtilsTest.java | 2 +-
.../java/com/cloud/utils/net/NetUtilsTest.java | 19 +
248 files changed, 10404 insertions(+), 2088 deletions(-)
diff --git a/api/src/main/java/com/cloud/configuration/ConfigurationService.java b/api/src/main/java/com/cloud/configuration/ConfigurationService.java
index 97d4b42974b..5a4dcb3f569 100644
--- a/api/src/main/java/com/cloud/configuration/ConfigurationService.java
+++ b/api/src/main/java/com/cloud/configuration/ConfigurationService.java
@@ -17,7 +17,11 @@
package com.cloud.configuration;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import com.cloud.network.Network;
+import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.config.ResetCfgCmd;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
@@ -372,4 +376,16 @@ public interface ConfigurationService {
List<? extends PortableIp> listPortableIps(long id);
Boolean isAccountAllowedToCreateOfferingsWithTags(IsAccountAllowedToCreateOfferingsWithTagsCmd cmd);
+
+ public static final Map<String, String> ProviderDetailKeyMap = Map.of(
+ Network.Provider.Nsx.getName(), ApiConstants.NSX_DETAIL_KEY,
+ Network.Provider.Netris.getName(), ApiConstants.NETRIS_DETAIL_KEY
+ );
+
+ public static boolean IsIpRangeForProvider(Network.Provider provider) {
+ if (Objects.isNull(provider)) {
+ return false;
+ }
+ return ProviderDetailKeyMap.containsKey(provider.getName());
+ }
}
diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
index 5e5309965c1..6215afa4513 100644
--- a/api/src/main/java/com/cloud/event/EventTypes.java
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -495,6 +495,8 @@ public class EventTypes {
public static final String EVENT_ZONE_VLAN_ASSIGN = "ZONE.VLAN.ASSIGN";
public static final String EVENT_ZONE_VLAN_RELEASE = "ZONE.VLAN.RELEASE";
+ public static final String EVENT_ZONE_VXLAN_ASSIGN = "ZONE.VXLAN.ASSIGN";
+ public static final String EVENT_ZONE_VXLAN_RELEASE = "ZONE.VXLAN.RELEASE";
// Projects
public static final String EVENT_PROJECT_CREATE = "PROJECT.CREATE";
diff --git a/api/src/main/java/com/cloud/network/IpAddress.java b/api/src/main/java/com/cloud/network/IpAddress.java
index ae1af450577..70d652b54e9 100644
--- a/api/src/main/java/com/cloud/network/IpAddress.java
+++ b/api/src/main/java/com/cloud/network/IpAddress.java
@@ -99,4 +99,5 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity,
boolean isForSystemVms();
+ boolean isForRouter();
}
diff --git a/api/src/main/java/com/cloud/network/Network.java b/api/src/main/java/com/cloud/network/Network.java
index d3bc5005cb7..dc94932e31f 100644
--- a/api/src/main/java/com/cloud/network/Network.java
+++ b/api/src/main/java/com/cloud/network/Network.java
@@ -206,6 +206,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
public static final Provider Tungsten = new Provider("Tungsten", false);
public static final Provider Nsx = new Provider("Nsx", false);
+ public static final Provider Netris = new Provider("Netris", false);
private final String name;
private final boolean isExternal;
diff --git a/api/src/main/java/com/cloud/network/Networks.java b/api/src/main/java/com/cloud/network/Networks.java
index dfa0ddb84ca..9f06a044111 100644
--- a/api/src/main/java/com/cloud/network/Networks.java
+++ b/api/src/main/java/com/cloud/network/Networks.java
@@ -129,7 +129,8 @@ public class Networks {
UnDecided(null, null),
OpenDaylight("opendaylight", String.class),
TUNGSTEN("tf", String.class),
- NSX("nsx", String.class);
+ NSX("nsx", String.class),
+ Netris("netris", String.class);
private final String scheme;
private final Class<?> type;
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java b/api/src/main/java/com/cloud/network/SDNProviderNetworkRule.java
similarity index 74%
copy from plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java
copy to api/src/main/java/com/cloud/network/SDNProviderNetworkRule.java
index c11141db9d4..a22db4287dc 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java
+++ b/api/src/main/java/com/cloud/network/SDNProviderNetworkRule.java
@@ -14,41 +14,33 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package org.apache.cloudstack.resource;
-
-import com.cloud.network.Network;
+package com.cloud.network;
import java.util.List;
-public class NsxNetworkRule {
-
- public enum NsxRuleAction {
- ALLOW, DROP
- }
-
- private long domainId;
- private long accountId;
- private long zoneId;
- private Long networkResourceId;
- private String networkResourceName;
- private boolean isVpcResource;
- private long vmId;
- private long ruleId;
- private String publicIp;
- private String vmIp;
- private String publicPort;
- private String privatePort;
- private String protocol;
- private String algorithm;
- private List<NsxLoadBalancerMember> memberList;
- private NsxRuleAction aclAction;
- private List<String> sourceCidrList;
- private List<String> destinationCidrList;
- private Integer icmpCode;
-
- private Integer icmpType;
- private String trafficType;
- private Network.Service service;
+public class SDNProviderNetworkRule {
+
+ protected long domainId;
+ protected long accountId;
+ protected long zoneId;
+ protected Long networkResourceId;
+ protected String networkResourceName;
+ protected boolean isVpcResource;
+ protected long vmId;
+ protected long ruleId;
+ protected String publicIp;
+ protected String vmIp;
+ protected String publicPort;
+ protected String privatePort;
+ protected String protocol;
+ protected String algorithm;
+ protected List<String> sourceCidrList;
+ protected List<String> destinationCidrList;
+ protected Integer icmpCode;
+
+ protected Integer icmpType;
+ protected String trafficType;
+ protected Network.Service service;
public long getDomainId() {
return domainId;
@@ -162,22 +154,6 @@ public class NsxNetworkRule {
return algorithm;
}
- public List<NsxLoadBalancerMember> getMemberList() {
- return memberList;
- }
-
- public void setMemberList(List<NsxLoadBalancerMember> memberList) {
- this.memberList = memberList;
- }
-
- public NsxRuleAction getAclAction() {
- return aclAction;
- }
-
- public void setAclAction(NsxRuleAction aclAction) {
- this.aclAction = aclAction;
- }
-
public Network.Service getService() {
return service;
}
@@ -226,30 +202,28 @@ public class NsxNetworkRule {
this.trafficType = trafficType;
}
- public static final class Builder {
- private long domainId;
- private long accountId;
- private long zoneId;
- private Long networkResourceId;
- private String networkResourceName;
- private boolean isVpcResource;
- private long vmId;
-
- private long ruleId;
- private String publicIp;
- private String vmIp;
- private String publicPort;
- private String privatePort;
- private String protocol;
- private String algorithm;
- private List<NsxLoadBalancerMember> memberList;
- private NsxRuleAction aclAction;
- private List<String> sourceCidrList;
- private List<String> destinationidrList;
- private String trafficType;
- private Integer icmpType;
- private Integer icmpCode;
- private Network.Service service;
+ public static class Builder {
+ public long domainId;
+ public long accountId;
+ public long zoneId;
+ public Long networkResourceId;
+ public String networkResourceName;
+ public boolean isVpcResource;
+ public long vmId;
+
+ public long ruleId;
+ public String publicIp;
+ public String vmIp;
+ public String publicPort;
+ public String privatePort;
+ public String protocol;
+ public String algorithm;
+ public List<String> sourceCidrList;
+ public List<String> destinationCidrList;
+ public String trafficType;
+ public Integer icmpType;
+ public Integer icmpCode;
+ public Network.Service service;
public Builder() {
// Default constructor
@@ -326,17 +300,6 @@ public class NsxNetworkRule {
return this;
}
- public Builder setMemberList(List<NsxLoadBalancerMember> memberList) {
- this.memberList = memberList;
- return this;
- }
-
-
- public Builder setAclAction(NsxRuleAction aclAction) {
- this.aclAction = aclAction;
- return this;
- }
-
public Builder setTrafficType(String trafficType) {
this.trafficType = trafficType;
return this;
@@ -358,7 +321,7 @@ public class NsxNetworkRule {
}
public Builder setDestinationCidrList(List<String> destinationCidrList) {
- this.destinationidrList = destinationCidrList;
+ this.destinationCidrList = destinationCidrList;
return this;
}
@@ -367,8 +330,8 @@ public class NsxNetworkRule {
return this;
}
- public NsxNetworkRule build() {
- NsxNetworkRule rule = new NsxNetworkRule();
+ public SDNProviderNetworkRule build() {
+ SDNProviderNetworkRule rule = new SDNProviderNetworkRule();
rule.setDomainId(this.domainId);
rule.setAccountId(this.accountId);
rule.setZoneId(this.zoneId);
@@ -383,12 +346,10 @@ public class NsxNetworkRule {
rule.setProtocol(this.protocol);
rule.setRuleId(this.ruleId);
rule.setAlgorithm(this.algorithm);
- rule.setMemberList(this.memberList);
- rule.setAclAction(this.aclAction);
rule.setIcmpType(this.icmpType);
rule.setIcmpCode(this.icmpCode);
rule.setSourceCidrList(this.sourceCidrList);
- rule.setDestinationCidrList(this.destinationidrList);
+ rule.setDestinationCidrList(this.destinationCidrList);
rule.setTrafficType(this.trafficType);
rule.setService(service);
return rule;
diff --git a/api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java b/api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java
index 994df875f7d..51036abe060 100644
--- a/api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java
+++ b/api/src/main/java/com/cloud/network/Site2SiteVpnConnection.java
@@ -24,7 +24,7 @@ import org.apache.cloudstack.api.InternalIdentity;
public interface Site2SiteVpnConnection extends ControlledEntity, InternalIdentity, Displayable {
enum State {
- Pending, Connecting, Connected, Disconnected, Error,
+ Pending, Connecting, Connected, Disconnected, Error, Removed
}
@Override
diff --git a/api/src/main/java/com/cloud/network/element/NetworkElement.java b/api/src/main/java/com/cloud/network/element/NetworkElement.java
index fa67575edd3..00c530ce114 100644
--- a/api/src/main/java/com/cloud/network/element/NetworkElement.java
+++ b/api/src/main/java/com/cloud/network/element/NetworkElement.java
@@ -23,6 +23,7 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
@@ -87,6 +88,12 @@ public interface NetworkElement extends Adapter {
boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException,
ResourceUnavailableException;
+ /**
+ * Release IP from the network provider if reserved
+ * @param ipAddress
+ */
+ boolean releaseIp(IpAddress ipAddress);
+
/**
* The network is being shutdown.
* @param network
diff --git a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java b/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
index e99bc2fd416..8dcc8b6d0a4 100644
--- a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
+++ b/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
@@ -17,12 +17,40 @@
package com.cloud.network.element;
import java.util.List;
+import java.util.Objects;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.vpc.NetworkACLItem;
public interface PortForwardingServiceProvider extends NetworkElement, IpDeployingRequester {
+
+ static String getPublicPortRange(PortForwardingRule rule) {
+ return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
+ String.valueOf(rule.getSourcePortStart()) :
+ String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
+ }
+
+ static String getPrivatePFPortRange(PortForwardingRule rule) {
+ return rule.getDestinationPortStart() == rule.getDestinationPortEnd() ?
+ String.valueOf(rule.getDestinationPortStart()) :
+ String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
+ }
+
+ static String getPrivatePortRange(FirewallRule rule) {
+ return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
+ String.valueOf(rule.getSourcePortStart()) :
+ String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
+ }
+
+ static String getPrivatePortRangeForACLRule(NetworkACLItem rule) {
+ return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
+ String.valueOf(rule.getSourcePortStart()) :
+ String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
+ }
+
/**
* Apply rules
* @param network
diff --git a/api/src/main/java/com/cloud/network/element/VpcProvider.java b/api/src/main/java/com/cloud/network/element/VpcProvider.java
index 6debd1fbc2d..47e70d6597d 100644
--- a/api/src/main/java/com/cloud/network/element/VpcProvider.java
+++ b/api/src/main/java/com/cloud/network/element/VpcProvider.java
@@ -55,4 +55,6 @@ public interface VpcProvider extends NetworkElement {
boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException;
boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
+
+ boolean updateVpc(Vpc vpc, String previousVpcName);
}
diff --git a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
index 7b81c75ed84..ced664e54a9 100644
--- a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
+++ b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java
@@ -215,4 +215,8 @@ public interface NetworkGuru extends Adapter {
default boolean isSlaacV6Only() {
return true;
}
+
+ default boolean update(Network network, String prevNetworkName) {
+ return true;
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/api/src/main/java/com/cloud/network/netris/NetrisLbBackend.java
similarity index 64%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to api/src/main/java/com/cloud/network/netris/NetrisLbBackend.java
index d3fef252f50..afc21f7f511 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/api/src/main/java/com/cloud/network/netris/NetrisLbBackend.java
@@ -14,10 +14,28 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package com.cloud.network.netris;
-import com.cloud.utils.db.GenericDao;
+public class NetrisLbBackend {
+ private long vmId;
+ private String vmIp;
+ private int port;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ public NetrisLbBackend(long vmId, String vmIp, int port) {
+ this.vmId = vmId;
+ this.vmIp = vmIp;
+ this.port = port;
+ }
+
+ public long getVmId() {
+ return vmId;
+ }
+
+ public String getVmIp() {
+ return vmIp;
+ }
+
+ public int getPort() {
+ return port;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/netris/NetrisNetworkRule.java b/api/src/main/java/com/cloud/network/netris/NetrisNetworkRule.java
new file mode 100644
index 00000000000..211517ead49
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/netris/NetrisNetworkRule.java
@@ -0,0 +1,108 @@
+// 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.netris;
+
+import com.cloud.network.SDNProviderNetworkRule;
+
+
+import java.util.List;
+
+public class NetrisNetworkRule {
+ public enum NetrisRuleAction {
+ PERMIT, DENY
+ }
+
+ private SDNProviderNetworkRule baseRule;
+ private NetrisRuleAction aclAction;
+ private List<NetrisLbBackend> lbBackends;
+ private String lbRuleName;
+ private String lbCidrList;
+ private String reason;
+
+ public NetrisNetworkRule(Builder builder) {
+ this.baseRule = builder.baseRule;
+ this.aclAction = builder.aclAction;
+ this.lbBackends = builder.lbBackends;
+ this.reason = builder.reason;
+ this.lbCidrList = builder.lbCidrList;
+ this.lbRuleName = builder.lbRuleName;
+ }
+
+ public NetrisRuleAction getAclAction() {
+ return aclAction;
+ }
+
+ public List<NetrisLbBackend> getLbBackends() {
+ return lbBackends;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public String getLbCidrList() {return lbCidrList; }
+
+ public String getLbRuleName() { return lbRuleName; }
+
+ public SDNProviderNetworkRule getBaseRule() {
+ return baseRule;
+ }
+
+ // Builder class extending the parent builder
+ public static class Builder {
+ private SDNProviderNetworkRule baseRule;
+ private NetrisRuleAction aclAction;
+ private List<NetrisLbBackend> lbBackends;
+ private String reason;
+ private String lbCidrList;
+ private String lbRuleName;
+
+ public Builder baseRule(SDNProviderNetworkRule baseRule) {
+ this.baseRule = baseRule;
+ return this;
+ }
+
+ public Builder aclAction(NetrisRuleAction aclAction) {
+ this.aclAction = aclAction;
+ return this;
+ }
+
+ public Builder lbBackends(List<NetrisLbBackend> lbBackends) {
+ this.lbBackends = lbBackends;
+ return this;
+ }
+
+ public Builder reason(String reason) {
+ this.reason = reason;
+ return this;
+ }
+
+ public Builder lbCidrList(String lbCidrList) {
+ this.lbCidrList = lbCidrList;
+ return this;
+ }
+
+ public Builder lbRuleName(String lbRuleName) {
+ this.lbRuleName = lbRuleName;
+ return this;
+ }
+
+ public NetrisNetworkRule build() {
+ return new NetrisNetworkRule(this);
+ }
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/api/src/main/java/com/cloud/network/netris/NetrisProvider.java
similarity index 68%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to api/src/main/java/com/cloud/network/netris/NetrisProvider.java
index d3fef252f50..fccf2930e97 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/api/src/main/java/com/cloud/network/netris/NetrisProvider.java
@@ -14,10 +14,17 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package com.cloud.network.netris;
-import com.cloud.utils.db.GenericDao;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public interface NetrisProvider extends InternalIdentity, Identity {
+ long getZoneId();
+ String getName();
+ String getUrl();
+ String getUsername();
+ String getSiteName();
+ String getTenantName();
+ String getNetrisTag();
}
diff --git a/api/src/main/java/com/cloud/network/netris/NetrisService.java b/api/src/main/java/com/cloud/network/netris/NetrisService.java
new file mode 100644
index 00000000000..09d6b753980
--- /dev/null
+++ b/api/src/main/java/com/cloud/network/netris/NetrisService.java
@@ -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.netris;
+
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.SDNProviderNetworkRule;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.Vpc;
+
+import java.util.List;
+
+public interface NetrisService {
+ boolean createIPAMAllocationsForZoneLevelPublicRanges(long zoneId);
+
+ boolean createVpcResource(long zoneId, long accountId, long domainId, Long vpcId, String vpcName, boolean sourceNatEnabled, String cidr, boolean isVpcNetwork);
+
+ boolean updateVpcResource(long zoneId, long accountId, long domainId, Long vpcId, String vpcName, String previousVpcName);
+
+ boolean deleteVpcResource(long zoneId, long accountId, long domainId, Vpc vpc);
+
+ boolean createVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr, Boolean globalRouting);
+
+ boolean updateVnetResource(Long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String prevNetworkName);
+
+ boolean deleteVnetResource(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, String cidr);
+
+ boolean createSnatRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, long networkId, boolean isForVpc, String vpcCidr, String sourceNatIp);
+
+ boolean createPortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
+
+ boolean deletePortForwardingRule(long zoneId, long accountId, long domainId, String vpcName, Long vpcId, String networkName, Long networkId, boolean isForVpc, String vpcCidr, SDNProviderNetworkRule networkRule);
+
+ boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
+
+ boolean createStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String vpcCidr, String staticNatIp, String vmIp, long vmId);
+
+ boolean deleteStaticNatRule(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String staticNatIp, long vmId);
+
+ boolean addFirewallRules(Network network, List<NetrisNetworkRule> firewallRules);
+ boolean deleteFirewallRules(Network network, List<NetrisNetworkRule> firewallRules);
+
+ boolean addOrUpdateStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId, boolean updateRoute);
+
+ boolean deleteStaticRoute(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId);
+
+ List<StaticRoute> listStaticRoutes(long zoneId, long accountId, long domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, String prefix, String nextHop, Long routeId);
+
+ boolean releaseNatIp(long zoneId, String publicIp);
+
+ boolean createOrUpdateLbRule(NetrisNetworkRule rule);
+ boolean deleteLbRule(NetrisNetworkRule rule);
+}
diff --git a/api/src/main/java/com/cloud/network/vpc/StaticRoute.java b/api/src/main/java/com/cloud/network/vpc/StaticRoute.java
index 5707ca14024..739fca328b8 100644
--- a/api/src/main/java/com/cloud/network/vpc/StaticRoute.java
+++ b/api/src/main/java/com/cloud/network/vpc/StaticRoute.java
@@ -25,6 +25,7 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit
Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router.
Add, // Add means the route has been created and has gone through network rule conflict detection.
Active, // Route has been sent to the VPC router and reported to be active.
+ Update,
Revoke, // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database.
Deleting // rule has been revoked and is scheduled for deletion
}
@@ -32,7 +33,9 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit
/**
* @return
*/
- long getVpcGatewayId();
+ Long getVpcGatewayId();
+
+ String getNextHop();
/**
* @return
diff --git a/api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java b/api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java
index cb4849f1f7b..c8fc073911f 100644
--- a/api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java
+++ b/api/src/main/java/com/cloud/network/vpc/StaticRouteProfile.java
@@ -23,7 +23,8 @@ public class StaticRouteProfile implements StaticRoute {
private String targetCidr;
private long accountId;
private long domainId;
- private long gatewayId;
+ private Long gatewayId;
+ private String nextHop;
private StaticRoute.State state;
private long vpcId;
String vlanTag;
@@ -46,6 +47,18 @@ public class StaticRouteProfile implements StaticRoute {
ipAddress = gateway.getIp4Address();
}
+ public StaticRouteProfile(StaticRoute staticRoute) {
+ id = staticRoute.getId();
+ uuid = staticRoute.getUuid();
+ targetCidr = staticRoute.getCidr();
+ accountId = staticRoute.getAccountId();
+ domainId = staticRoute.getDomainId();
+ gatewayId = staticRoute.getVpcGatewayId();
+ state = staticRoute.getState();
+ vpcId = staticRoute.getVpcId();
+ gateway = staticRoute.getNextHop();
+ }
+
@Override
public long getAccountId() {
return accountId;
@@ -57,10 +70,15 @@ public class StaticRouteProfile implements StaticRoute {
}
@Override
- public long getVpcGatewayId() {
+ public Long getVpcGatewayId() {
return gatewayId;
}
+ @Override
+ public String getNextHop() {
+ return nextHop;
+ }
+
@Override
public String getCidr() {
return targetCidr;
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
index 38263f59667..17f49bb3652 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
@@ -32,6 +32,8 @@ public interface VpcOffering extends InternalIdentity, Identity {
public static final String redundantVPCOfferingName = "Redundant VPC offering";
public static final String DEFAULT_VPC_NAT_NSX_OFFERING_NAME = "VPC offering with NSX - NAT Mode";
public static final String DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME = "VPC offering with NSX - Route Mode";
+ public static final String DEFAULT_VPC_ROUTE_NETRIS_OFFERING_NAME = "VPC offering with Netris - Route Mode";
+ public static final String DEFAULT_VPC_NAT_NETRIS_OFFERING_NAME = "VPC offering with Netris - NAT Mode";
/**
*
@@ -56,8 +58,6 @@ public interface VpcOffering extends InternalIdentity, Identity {
*/
boolean isDefault();
- boolean isForNsx();
-
NetworkOffering.NetworkMode getNetworkMode();
/**
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
index 10f1ddcc12d..97b95339ecf 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
@@ -37,7 +37,7 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
Map<String, List<String>> serviceProviders,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
- Long serviceOfferingId, Boolean forNsx, NetworkOffering.NetworkMode networkMode,
+ Long serviceOfferingId, String externalProvider, NetworkOffering.NetworkMode networkMode,
List<Long> domainIds, List<Long> zoneIds, VpcOffering.State state,
NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber);
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcService.java b/api/src/main/java/com/cloud/network/vpc/VpcService.java
index af2a9847a62..4477f10d1a4 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcService.java
@@ -238,7 +238,7 @@ public interface VpcService {
* @param cidr
* @return
*/
- StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException;
+ StaticRoute createStaticRoute(Long gatewayId, Long vpcId, String nextHop, String cidr) throws NetworkRuleConflictException;
/**
* Lists static routes based on parameters passed to the call
diff --git a/api/src/main/java/com/cloud/offering/NetworkOffering.java b/api/src/main/java/com/cloud/offering/NetworkOffering.java
index 7011aea679e..5000a4f8c62 100644
--- a/api/src/main/java/com/cloud/offering/NetworkOffering.java
+++ b/api/src/main/java/com/cloud/offering/NetworkOffering.java
@@ -64,6 +64,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC = "DefaultNATNSXNetworkOfferingForVpc";
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC_WITH_ILB = "DefaultNATNSXNetworkOfferingForVpcWithInternalLB";
public static final String DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC = "DefaultRoutedNSXNetworkOfferingForVpc";
+ public static final String DEFAULT_ROUTED_NETRIS_OFFERING_FOR_VPC = "DefaultRoutedNetrisNetworkOfferingForVpc";
+ public static final String DEFAULT_NAT_NETRIS_OFFERING_FOR_VPC = "DefaultNATNetrisNetworkOfferingForVpc";
public static final String DEFAULT_NAT_NSX_OFFERING = "DefaultNATNSXNetworkOffering";
public static final String DEFAULT_ROUTED_NSX_OFFERING = "DefaultRoutedNSXNetworkOffering";
public final static String QuickCloudNoServices = "QuickCloudNoServices";
@@ -102,10 +104,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
boolean isForVpc();
- boolean isForTungsten();
-
- boolean isForNsx();
-
NetworkMode getNetworkMode();
TrafficType getTrafficType();
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index bb16b0ff90d..1c85e6a8c03 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -210,6 +210,7 @@ public class ApiConstants {
public static final String FORMAT = "format";
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
public static final String FOR_SYSTEM_VMS = "forsystemvms";
+ public static final String FOR_PROVIDER = "forprovider";
public static final String FULL_PATH = "fullpath";
public static final String GATEWAY = "gateway";
public static final String IP6_GATEWAY = "ip6gateway";
@@ -253,6 +254,7 @@ public class ApiConstants {
public static final String PREVIOUS_OWNER_ID = "previousownerid";
public static final String PREVIOUS_OWNER_NAME = "previousownername";
public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
+ public static final String NEXT_HOP = "nexthop";
public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
public static final String IMAGE_PATH = "imagepath";
public static final String INSTANCE_CONVERSION_SUPPORTED = "instanceconversionsupported";
@@ -325,6 +327,8 @@ public class ApiConstants {
public static final String MIN_CPU_NUMBER = "mincpunumber";
public static final String MIN_MEMORY = "minmemory";
public static final String MIGRATION_TYPE = "migrationtype";
+ public static final String MIGRATION_JOB_ID = "migrationjobid";
+ public static final String MIGRATION_JOB_STATUS = "migrationjobstatus";
public static final String MIGRATIONS = "migrations";
public static final String MEMORY = "memory";
public static final String MODE = "mode";
@@ -448,6 +452,7 @@ public class ApiConstants {
public static final String SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
public static final String SINCE = "since";
+ public static final String SITE_NAME = "sitename";
public static final String SIZE = "size";
public static final String SIZEGB = "sizegb";
public static final String SNAPSHOT = "snapshot";
@@ -490,6 +495,7 @@ public class ApiConstants {
public static final String TIMEOUT = "timeout";
public static final String TIMEZONE = "timezone";
public static final String TIMEZONEOFFSET = "timezoneoffset";
+ public static final String TENANT_NAME = "tenantname";
public static final String TOTAL = "total";
public static final String TOTAL_SUBNETS = "totalsubnets";
public static final String TYPE = "type";
@@ -858,6 +864,8 @@ public class ApiConstants {
public static final String NETWORK = "network";
public static final String VPC_ID = "vpcid";
public static final String VPC_NAME = "vpcname";
+ public static final String VPC_GATEWAY_ID = "vpcgatewayid";
+ public static final String VPC_GATEWAY_IP = "vpcgatewayip";
public static final String GATEWAY_ID = "gatewayid";
public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
public static final String RESOURCE_IDS = "resourceids";
@@ -1143,6 +1151,9 @@ public class ApiConstants {
public static final String SOURCE_NAT_IP_ID = "sourcenatipaddressid";
public static final String HAS_RULES = "hasrules";
public static final String NSX_DETAIL_KEY = "forNsx";
+ public static final String NETRIS_DETAIL_KEY = "forNetris";
+ public static final String NETRIS_TAG = "netristag";
+ public static final String NETRIS_VXLAN_ID = "netrisvxlanid";
public static final String DISK_PATH = "diskpath";
public static final String IMPORT_SOURCE = "importsource";
public static final String TEMP_PATH = "temppath";
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index af3db374a7c..603e34d600b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -17,6 +17,7 @@
package org.apache.cloudstack.api.command.admin.network;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -140,12 +141,19 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
description = "true if network offering is meant to be used for VPC, false otherwise.")
private Boolean forVpc;
+ @Deprecated
@Parameter(name = ApiConstants.FOR_NSX,
type = CommandType.BOOLEAN,
description = "true if network offering is meant to be used for NSX, false otherwise.",
since = "4.20.0")
private Boolean forNsx;
+ @Parameter(name = ApiConstants.PROVIDER,
+ type = CommandType.STRING,
+ description = "Name of the provider providing the service",
+ since = "4.20.0")
+ private String provider;
+
@Parameter(name = ApiConstants.NSX_SUPPORT_LB,
type = CommandType.BOOLEAN,
description = "true if network offering for NSX network offering supports Load balancer service.",
@@ -257,18 +265,38 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return serviceOfferingId;
}
+ public boolean isExternalNetworkProvider() {
+ return Arrays.asList("NSX", "Netris").stream()
+ .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
+ }
+
+ public boolean isForNsx() {
+ return provider != null && provider.equalsIgnoreCase("NSX");
+ }
+
+ public boolean isForNetris() {
+ return provider != null && provider.equalsIgnoreCase("Netris");
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
public List<String> getSupportedServices() {
- if (!isForNsx()) {
+ if (!isExternalNetworkProvider()) {
return supportedServices == null ? new ArrayList<String>() : supportedServices;
} else {
List<String> services = new ArrayList<>(List.of(
Dhcp.getName(),
Dns.getName(),
- StaticNat.getName(),
- SourceNat.getName(),
- PortForwarding.getName(),
UserData.getName()
));
+ if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
+ services.addAll(Arrays.asList(
+ StaticNat.getName(),
+ SourceNat.getName(),
+ PortForwarding.getName()));
+ }
if (getNsxSupportsLbService()) {
services.add(Lb.getName());
}
@@ -308,10 +336,6 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return forVpc;
}
- public boolean isForNsx() {
- return BooleanUtils.isTrue(forNsx);
- }
-
public String getNetworkMode() {
return networkMode;
}
@@ -345,7 +369,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
public Map<String, List<String>> getServiceProviders() {
Map<String, List<String>> serviceProviderMap = new HashMap<>();
- if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) {
+ if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
Collection servicesCollection = serviceProviderList.values();
Iterator iter = servicesCollection.iterator();
while (iter.hasNext()) {
@@ -361,17 +385,16 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
providerList.add(provider);
serviceProviderMap.put(service, providerList);
}
- } else if (Boolean.TRUE.equals(forNsx)) {
- getServiceProviderMapForNsx(serviceProviderMap);
+ } else if (isExternalNetworkProvider()) {
+ getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
}
return serviceProviderMap;
}
- private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) {
+ private void getServiceProviderMapForExternalProvider(Map<String, List<String>> serviceProviderMap, String provider) {
String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
VirtualRouterProvider.Type.VirtualRouter.name();
- List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "SecurityGroup", "Connectivity",
- "Gateway", "BaremetalPxeService"));
+ List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "Gateway", "SecurityGroup", "Connectivity", "BaremetalPxeService"));
List<String> routerSupported = List.of("Dhcp", "Dns", "UserData");
List<String> allServices = Service.listAllServices().stream().map(Service::getName).collect(Collectors.toList());
if (routerProvider.equals(VirtualRouterProvider.Type.VPCVirtualRouter.name())) {
@@ -384,8 +407,9 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
continue;
if (routerSupported.contains(service))
serviceProviderMap.put(service, List.of(routerProvider));
- else
- serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName()));
+ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) || NetworkACL.getName().equalsIgnoreCase(service)) {
+ serviceProviderMap.put(service, List.of(provider));
+ }
if (!getNsxSupportsLbService()) {
serviceProviderMap.remove(Lb.getName());
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
index c0ba99a8233..87a4bd07a68 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vlan/CreateVlanIpRangeCmd.java
@@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.api.command.admin.vlan;
+import com.cloud.configuration.ConfigurationService;
+import com.cloud.network.Network;
import com.cloud.utils.net.NetUtils;
import org.apache.cloudstack.api.APICommand;
@@ -39,7 +41,6 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
-import java.util.Objects;
@APICommand(name = "createVlanIpRange", description = "Creates a VLAN IP range.", responseObject = VlanIpRangeResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -114,8 +115,8 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
@Parameter(name = ApiConstants.FOR_SYSTEM_VMS, type = CommandType.BOOLEAN, description = "true if IP range is set to system vms, false if not")
private Boolean forSystemVms;
- @Parameter(name = ApiConstants.FOR_NSX, type = CommandType.BOOLEAN, description = "true if the IP range is used for NSX resource", since = "4.20.0")
- private boolean forNsx;
+ @Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "Provider name for which the IP range is reserved for", since = "4.20.0")
+ private String provider;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@@ -157,12 +158,12 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
return startIp;
}
- public boolean isForNsx() {
- return !Objects.isNull(forNsx) && forNsx;
+ public Network.Provider getProvider() {
+ return Network.Provider.getProvider(provider);
}
public String getVlan() {
- if ((vlan == null || vlan.isEmpty()) && !isForNsx()) {
+ if ((vlan == null || vlan.isEmpty()) && !ConfigurationService.IsIpRangeForProvider(getProvider())) {
vlan = "untagged";
}
return vlan;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
index 73b4f5df196..7ebe67a476b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
@@ -17,6 +17,7 @@
package org.apache.cloudstack.api.command.admin.vpc;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -25,10 +26,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Network;
import com.cloud.network.VirtualRouterProvider;
+import com.cloud.offering.NetworkOffering;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.commons.collections.CollectionUtils;
@@ -57,6 +60,7 @@ import static com.cloud.network.Network.Service.SourceNat;
import static com.cloud.network.Network.Service.PortForwarding;
import static com.cloud.network.Network.Service.NetworkACL;
import static com.cloud.network.Network.Service.UserData;
+import static com.cloud.network.Network.Service.Gateway;
@APICommand(name = "createVPCOffering", description = "Creates VPC offering", responseObject = VpcOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -112,12 +116,19 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
since = "4.13")
private List<Long> zoneIds;
+ @Deprecated
@Parameter(name = ApiConstants.FOR_NSX,
type = CommandType.BOOLEAN,
description = "true if network offering is meant to be used for NSX, false otherwise.",
since = "4.20.0")
private Boolean forNsx;
+ @Parameter(name = ApiConstants.PROVIDER,
+ type = CommandType.STRING,
+ description = "Name of the provider providing the service",
+ since = "4.20.0")
+ private String provider;
+
@Parameter(name = ApiConstants.NSX_SUPPORT_LB,
type = CommandType.BOOLEAN,
description = "true if network offering for NSX VPC offering supports Load balancer service.",
@@ -158,20 +169,31 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
return StringUtils.isEmpty(displayText) ? vpcOfferingName : displayText;
}
+ public boolean isExternalNetworkProvider() {
+ return Arrays.asList("NSX", "Netris").stream()
+ .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
+ }
+
public List<String> getSupportedServices() {
- if (!isForNsx() && CollectionUtils.isEmpty(supportedServices)) {
+ if (!isExternalNetworkProvider() && CollectionUtils.isEmpty(supportedServices)) {
throw new InvalidParameterValueException("Supported services needs to be provided");
}
- if (isForNsx()) {
+ if (isExternalNetworkProvider()) {
supportedServices = new ArrayList<>(List.of(
Dhcp.getName(),
Dns.getName(),
- StaticNat.getName(),
- SourceNat.getName(),
NetworkACL.getName(),
- PortForwarding.getName(),
UserData.getName()
));
+ if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
+ supportedServices.addAll(Arrays.asList(
+ StaticNat.getName(),
+ SourceNat.getName(),
+ PortForwarding.getName()));
+ }
+ if (NetworkOffering.NetworkMode.ROUTED.name().equalsIgnoreCase(getNetworkMode())) {
+ supportedServices.add(Gateway.getName());
+ }
if (getNsxSupportsLbService()) {
supportedServices.add(Lb.getName());
}
@@ -179,8 +201,8 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
return supportedServices;
}
- public boolean isForNsx() {
- return BooleanUtils.isTrue(forNsx);
+ public String getProvider() {
+ return provider;
}
public String getNetworkMode() {
@@ -193,7 +215,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
public Map<String, List<String>> getServiceProviders() {
Map<String, List<String>> serviceProviderMap = new HashMap<>();
- if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) {
+ if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
Collection<? extends Map<String, String>> servicesCollection = serviceProviderList.values();
Iterator<? extends Map<String, String>> iter = servicesCollection.iterator();
while (iter.hasNext()) {
@@ -213,16 +235,18 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
providerList.add(provider);
serviceProviderMap.put(service, providerList);
}
- } else if (Boolean.TRUE.equals(forNsx)) {
- getServiceProviderMapForNsx(serviceProviderMap);
+ } else if (isExternalNetworkProvider()) {
+ getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
}
return serviceProviderMap;
}
- private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) {
- List<String> unsupportedServices = List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity",
- "Gateway", "Firewall");
+ private void getServiceProviderMapForExternalProvider(Map<String, List<String>> serviceProviderMap, String provider) {
+ List<String> unsupportedServices = new ArrayList<>(List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity", "Firewall"));
+ if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
+ unsupportedServices.add("Gateway");
+ }
List<String> routerSupported = List.of("Dhcp", "Dns", "UserData");
List<String> allServices = Network.Service.listAllServices().stream().map(Network.Service::getName).collect(Collectors.toList());
for (String service : allServices) {
@@ -230,8 +254,10 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
continue;
if (routerSupported.contains(service))
serviceProviderMap.put(service, List.of(VirtualRouterProvider.Type.VPCVirtualRouter.name()));
- else
- serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName()));
+ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) ||
+ Stream.of(NetworkACL.getName(), Gateway.getName()).anyMatch(s -> s.equalsIgnoreCase(service))) {
+ serviceProviderMap.put(service, List.of(provider));
+ }
}
if (!getNsxSupportsLbService()) {
serviceProviderMap.remove(Lb.getName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
index 5760ca3ba1c..a9d651ae5fe 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/address/ListPublicIpAddressesCmd.java
@@ -108,6 +108,9 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
@Parameter(name = ApiConstants.FOR_SYSTEM_VMS, type = CommandType.BOOLEAN, description = "true if range is dedicated for system VMs", since = "4.20.0")
private Boolean forSystemVMs;
+ @Parameter(name = ApiConstants.FOR_PROVIDER, type = CommandType.BOOLEAN, description = "true if range is dedicated for external network provider", since = "4.20.0")
+ private Boolean forProvider;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -183,6 +186,10 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
return BooleanUtils.isTrue(forSystemVMs);
}
+ public boolean isForProvider() {
+ return BooleanUtils.isTrue(forProvider);
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
index b28c02cb800..41779ccdeb1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpc/CreateStaticRouteCmd.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
import org.apache.cloudstack.api.response.StaticRouteResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.context.CallContext;
import com.cloud.event.EventTypes;
@@ -45,20 +46,38 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.GATEWAY_ID,
type = CommandType.UUID,
entityType = PrivateGatewayResponse.class,
- required = true,
- description = "the gateway id we are creating static route for")
+ description = "the gateway id we are creating static route for. Mutually exclusive with the nexthop parameter")
private Long gatewayId;
+ @Parameter(name = ApiConstants.VPC_ID,
+ type = CommandType.UUID,
+ entityType = VpcResponse.class,
+ description = "the vpc id for which the static route is created. This is required for nexthop parameter")
+ private Long vpcId;
+
+ @Parameter(name = ApiConstants.NEXT_HOP,
+ type = CommandType.STRING,
+ description = "the next hop of static route. Mutually exclusive with the gatewayid parameter")
+ private String nextHop;
+
@Parameter(name = ApiConstants.CIDR, required = true, type = CommandType.STRING, description = "static route cidr")
private String cidr;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
- public long getGatewayId() {
+ public Long getGatewayId() {
return gatewayId;
}
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public String getNextHop() {
+ return nextHop;
+ }
+
public String getCidr() {
return cidr;
}
@@ -69,7 +88,7 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd {
@Override
public void create() throws ResourceAllocationException {
try {
- StaticRoute result = _vpcService.createStaticRoute(getGatewayId(), getCidr());
+ StaticRoute result = _vpcService.createStaticRoute(getGatewayId(), getVpcId(), getNextHop(), getCidr());
setEntityId(result.getId());
setEntityUuid(result.getUuid());
} catch (NetworkRuleConflictException ex) {
@@ -114,11 +133,8 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd {
@Override
public long getEntityOwnerId() {
- VpcGateway gateway = _entityMgr.findById(VpcGateway.class, gatewayId);
- if (gateway == null) {
- throw new InvalidParameterValueException("Invalid gateway id is specified");
- }
- return _entityMgr.findById(Vpc.class, gateway.getVpcId()).getAccountId();
+ Long vpcId = getSyncObjId();
+ return _entityMgr.findById(Vpc.class, vpcId).getAccountId();
}
@Override
@@ -128,11 +144,20 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd {
@Override
public Long getSyncObjId() {
- VpcGateway gateway = _entityMgr.findById(VpcGateway.class, gatewayId);
- if (gateway == null) {
- throw new InvalidParameterValueException("Invalid id is specified for the gateway");
+ if (gatewayId != null) {
+ VpcGateway gateway = _entityMgr.findById(VpcGateway.class, gatewayId);
+ if (gateway == null) {
+ throw new InvalidParameterValueException("Invalid id is specified for the gateway");
+ }
+ return gateway.getVpcId();
+ } else if (vpcId != null) {
+ Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+ if (vpc == null) {
+ throw new InvalidParameterValueException("Invalid vpc id is specified");
+ }
+ return vpc.getId();
}
- return gateway.getVpcId();
+ throw new InvalidParameterValueException("One of vpcId or gatewayId must be specified");
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
index 6f31176c4ff..f7230e6f8e8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vpn/CreateVpnGatewayCmd.java
@@ -28,6 +28,7 @@ import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.IPAddressResponse;
import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.context.CallContext;
@@ -44,9 +45,15 @@ public class CreateVpnGatewayCmd extends BaseAsyncCreateCmd {
type = CommandType.UUID,
entityType = VpcResponse.class,
required = true,
- description = "public ip address id of the vpn gateway")
+ description = "id of the vpc")
private Long vpcId;
+ @Parameter(name = ApiConstants.IP_ADDRESS_ID,
+ type = CommandType.UUID,
+ entityType = IPAddressResponse.class,
+ description = "the public IP address ID for which VPN gateway is being enabled. By default the source NAT IP or router IP will be used.")
+ private Long ipAddressId;
+
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vpn to the end user or not", since = "4.4", authorized = {RoleType.Admin})
private Boolean display;
@@ -58,6 +65,10 @@ public class CreateVpnGatewayCmd extends BaseAsyncCreateCmd {
return vpcId;
}
+ public Long getIpAddressId() {
+ return ipAddressId;
+ }
+
@Deprecated
public Boolean getDisplay() {
return display;
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java
index 3eeaaef2afa..e1db5aa6824 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/AsyncJobResponse.java
@@ -55,10 +55,6 @@ public class AsyncJobResponse extends BaseResponse {
@Param(description = "the async command executed")
private String cmd;
- @SerializedName("jobstatus")
- @Param(description = "the current job status-should be 0 for PENDING")
- private Integer jobStatus;
-
@SerializedName("jobprocstatus")
@Param(description = "the progress information of the PENDING job")
private Integer jobProcStatus;
@@ -119,11 +115,6 @@ public class AsyncJobResponse extends BaseResponse {
this.cmd = cmd;
}
- @Override
- public void setJobStatus(Integer jobStatus) {
- this.jobStatus = jobStatus;
- }
-
public void setJobProcStatus(Integer jobProcStatus) {
this.jobProcStatus = jobProcStatus;
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ClusterDrsPlanMigrationResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ClusterDrsPlanMigrationResponse.java
index 4114c228e26..f399c1260f7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/ClusterDrsPlanMigrationResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ClusterDrsPlanMigrationResponse.java
@@ -50,13 +50,13 @@ public class ClusterDrsPlanMigrationResponse extends BaseResponse {
@Param(description = "Destination host for VM migration")
String destHostName;
- @SerializedName(ApiConstants.JOB_ID)
+ @SerializedName(ApiConstants.MIGRATION_JOB_ID)
@Param(description = "id of VM migration async job")
- private Long jobId;
+ private Long migrationJobId;
- @SerializedName(ApiConstants.JOB_STATUS)
+ @SerializedName(ApiConstants.MIGRATION_JOB_STATUS)
@Param(description = "Job status of VM migration async job")
- private JobInfo.Status jobStatus;
+ private JobInfo.Status migrationJobStatus;
public ClusterDrsPlanMigrationResponse(String vmId, String vmName, String srcHostId, String srcHostName,
@@ -68,8 +68,8 @@ public class ClusterDrsPlanMigrationResponse extends BaseResponse {
this.srcHostName = srcHostName;
this.destHostId = destHostId;
this.destHostName = destHostName;
- this.jobId = jobId;
- this.jobStatus = jobStatus;
+ this.migrationJobId = jobId;
+ this.migrationJobStatus = jobStatus;
this.setObjectName(ApiConstants.MIGRATIONS);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java
index 0018edc8638..0f339d5d5b1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/IPAddressResponse.java
@@ -175,6 +175,10 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
@Param(description="true if range is dedicated for System VMs")
private boolean forSystemVms;
+ @SerializedName(ApiConstants.FOR_PROVIDER)
+ @Param(description="true if range is dedicated for external network providers")
+ private boolean forProvider;
+
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
@@ -332,4 +336,6 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
public void setForSystemVms(boolean forSystemVms) {
this.forSystemVms = forSystemVms;
}
+
+ public void setForProvider(boolean forProvider) { this.forProvider = forProvider; }
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java
index a80317c83cd..e7ad244e1da 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/NetworkResponse.java
@@ -208,14 +208,6 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
@Param(description = "Name of the VPC to which this network belongs", since = "4.15")
private String vpcName;
- @SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID)
- @Param(description = "the ID of the Network associated with this network")
- private String associatedNetworkId;
-
- @SerializedName(ApiConstants.ASSOCIATED_NETWORK)
- @Param(description = "the name of the Network associated with this network")
- private String associatedNetworkName;
-
@SerializedName(ApiConstants.TUNGSTEN_VIRTUAL_ROUTER_UUID)
@Param(description = "Tungsten-Fabric virtual router the network belongs to")
private String tungstenVirtualRouterUuid;
@@ -612,14 +604,6 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
this.vpcName = vpcName;
}
- public void setAssociatedNetworkId(String associatedNetworkId) {
- this.associatedNetworkId = associatedNetworkId;
- }
-
- public void setAssociatedNetworkName(String associatedNetworkName) {
- this.associatedNetworkName = associatedNetworkName;
- }
-
@Override
public void setResourceIconResponse(ResourceIconResponse icon) {
this.icon = icon;
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java
index 51f8a130383..9d0f90459a7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/StaticRouteResponse.java
@@ -42,9 +42,17 @@ public class StaticRouteResponse extends BaseResponse implements ControlledEntit
@Param(description = "VPC the static route belongs to")
private String vpcId;
- @SerializedName(ApiConstants.GATEWAY_ID)
+ @SerializedName(ApiConstants.VPC_GATEWAY_ID)
@Param(description = "VPC gateway the route is created for")
- private String gatewayId;
+ private String vpcGatewayId;
+
+ @SerializedName(ApiConstants.VPC_GATEWAY_IP)
+ @Param(description = "IP of VPC gateway the route is created for")
+ private String vpcGatewayIp;
+
+ @SerializedName(ApiConstants.NEXT_HOP)
+ @Param(description = "Next hop of the static route")
+ private String nextHop;
@SerializedName(ApiConstants.CIDR)
@Param(description = "static route CIDR")
@@ -95,8 +103,16 @@ public class StaticRouteResponse extends BaseResponse implements ControlledEntit
this.vpcId = vpcId;
}
- public void setGatewayId(String gatewayId) {
- this.gatewayId = gatewayId;
+ public void setVpcGatewayId(String vpcGatewayId) {
+ this.vpcGatewayId = vpcGatewayId;
+ }
+
+ public void setVpcGatewayIp(String vpcGatewayIp) {
+ this.vpcGatewayIp = vpcGatewayIp;
+ }
+
+ public void setNextHop(String nextHop) {
+ this.nextHop = nextHop;
}
public void setCidr(String cidr) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java
index 31a8b731491..c98235b2347 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/SystemVmResponse.java
@@ -38,14 +38,6 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
@Param(description = "the system VM type")
private String systemVmType;
- @SerializedName("jobid")
- @Param(description = "the job ID associated with the system VM. This is only displayed if the router listed is part of a currently running asynchronous job.")
- private String jobId;
-
- @SerializedName("jobstatus")
- @Param(description = "the job status associated with the system VM. This is only displayed if the router listed is part of a currently running asynchronous job.")
- private Integer jobStatus;
-
@SerializedName("zoneid")
@Param(description = "the Zone ID for the system VM")
private String zoneId;
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
index 1492c23e882..2ee748f0c59 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/VlanIpRangeResponse.java
@@ -127,9 +127,9 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
@Param(description = "indicates whether VLAN IP range is dedicated to system vms or not")
private Boolean forSystemVms;
- @SerializedName(ApiConstants.FOR_NSX)
- @Param(description = "indicates whether IP range is dedicated to NSX resources or not")
- private Boolean forNsx;
+ @SerializedName(ApiConstants.PROVIDER)
+ @Param(description = "indicates whether IP range is dedicated to NSX resources or not", since = "4.20.0")
+ private String provider;
public void setId(String id) {
this.id = id;
@@ -249,7 +249,7 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
this.ip6Cidr = ip6Cidr;
}
- public void setForNsx(Boolean forNsx) {
- this.forNsx = forNsx;
+ public void setProvider(String provider) {
+ this.provider = provider;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
index 143dfad0eaf..475c8b9eef2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -145,10 +145,15 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
@Param(description = "the type of the zone - core or edge", since = "4.18.0")
String type;
+ @Deprecated(since = "4.20")
@SerializedName(ApiConstants.NSX_ENABLED)
@Param(description = "true, if zone is NSX enabled", since = "4.20.0")
private boolean nsxEnabled = false;
+ @SerializedName(ApiConstants.PROVIDER)
+ @Param(description = "External network provider if any", since = "4.20.0")
+ private String provider = null;
+
@SerializedName(ApiConstants.MULTI_ARCH)
@Param(description = "true, if zone contains clusters and hosts from different CPU architectures", since = "4.20")
private boolean multiArch;
@@ -368,6 +373,14 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
return nsxEnabled;
}
+ public String getProvider() {
+ return provider;
+ }
+
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
@Override
public void setResourceIconResponse(ResourceIconResponse resourceIconResponse) {
this.resourceIconResponse = resourceIconResponse;
diff --git a/client/pom.xml b/client/pom.xml
index eddf49c040f..4cdb93d89e7 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -1097,6 +1097,11 @@
<artifactId>cloud-plugin-network-nsx</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-plugin-network-netris</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-tungsten</artifactId>
diff --git a/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java b/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
index b299c602dde..351702a048c 100644
--- a/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
+++ b/core/src/main/java/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
@@ -25,7 +25,6 @@ import java.util.Map;
public class CheckS2SVpnConnectionsAnswer extends Answer {
Map<String, Boolean> ipToConnected;
Map<String, String> ipToDetail;
- String details;
protected CheckS2SVpnConnectionsAnswer() {
ipToConnected = new HashMap<String, Boolean>();
diff --git a/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java b/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java
index 06583f2d0d3..fef0ceed6b8 100644
--- a/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java
+++ b/core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java
@@ -36,6 +36,7 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
String routerIpv6Gateway = null;
String routerIpv6Cidr = null;
boolean isVrGuestGateway = false;
+ long networkId;
public NicTO getNic() {
return nic;
@@ -123,4 +124,12 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
public void setVrGuestGateway(boolean vrGuestGateway) {
isVrGuestGateway = vrGuestGateway;
}
+
+ public long getNetworkId() {
+ return networkId;
+ }
+
+ public void setNetworkId(long networkId) {
+ this.networkId = networkId;
+ }
}
diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
index 1a6824ceb7f..57c96ec4bc9 100644
--- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
+++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java
@@ -76,6 +76,7 @@ public class SetGuestNetworkConfigItem extends AbstractConfigItemFacade {
guestNetwork.setRouterIp6Gateway(command.getRouterIpv6Gateway());
guestNetwork.setRouterIp6Cidr(command.getRouterIpv6Cidr());
guestNetwork.setVrGuestGateway(command.isVrGuestGateway());
+ guestNetwork.setNetworkId(command.getNetworkId());
return generateConfigItems(guestNetwork);
}
diff --git a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
index a416b4bc5e4..6bf36d62bf9 100644
--- a/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
+++ b/core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java
@@ -38,6 +38,7 @@ public class GuestNetwork extends ConfigBase {
private String routerIp6Gateway;
private String routerIp6Cidr;
private boolean isVrGuestGateway;
+ long networkId;
private Integer mtu;
@@ -211,4 +212,12 @@ public class GuestNetwork extends ConfigBase {
public void setVrGuestGateway(boolean vrGuestGateway) {
isVrGuestGateway = vrGuestGateway;
}
+
+ public long getNetworkId() {
+ return networkId;
+ }
+
+ public void setNetworkId(long networkId) {
+ this.networkId = networkId;
+ }
}
diff --git a/core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java b/core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java
index 7229f0903b7..eabcc82040d 100644
--- a/core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java
+++ b/core/src/main/java/com/cloud/agent/transport/ArrayTypeAdaptor.java
@@ -75,13 +75,17 @@ public class ArrayTypeAdaptor<T> implements JsonDeserializer<T[]>, JsonSerialize
try {
clazz = Class.forName(name);
} catch (ClassNotFoundException e) {
- throw new CloudRuntimeException("can't find " + name);
+ throw new JsonParseException("can't find " + name);
}
T cmd = (T)_gson.fromJson(entry.getValue(), clazz);
cmds.add(cmd);
}
- Class<?> type = ((Class<?>)typeOfT).getComponentType();
- T[] ts = (T[])Array.newInstance(type, cmds.size());
- return cmds.toArray(ts);
+ try {
+ Class<?> type = Class.forName(typeOfT.getTypeName().replace("[]", ""));
+ T[] ts = (T[])Array.newInstance(type, cmds.size());
+ return cmds.toArray(ts);
+ } catch (ClassNotFoundException e) {
+ throw new CloudRuntimeException("can't find " + typeOfT.getTypeName());
+ }
}
}
diff --git a/core/src/test/java/com/cloud/agent/transport/ResponseTest.java b/core/src/test/java/com/cloud/agent/transport/ResponseTest.java
new file mode 100644
index 00000000000..06869b42eb9
--- /dev/null
+++ b/core/src/test/java/com/cloud/agent/transport/ResponseTest.java
@@ -0,0 +1,46 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.agent.transport;
+
+import junit.framework.TestCase;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.junit.Assert;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+
+import com.cloud.agent.transport.Request.Version;
+
+public class ResponseTest extends TestCase {
+ protected Logger logger = LogManager.getLogger(getClass());
+
+ public void testCheckS2SVpnConnectionsAnswer() {
+ logger.info("Testing CheckS2SVpnConnectionsAnswer");
+ String content = "[{\"com.cloud.agent.api.CheckS2SVpnConnectionsAnswer\":{\"ipToConnected\":{\"10.0.53.13\":true}," +
+ "\"ipToDetail\":{\"10.0.53.13\":\"IPsec SA found;Site-to-site VPN have connected\"}," +
+ "\"details\":\"10.0.53.13:0:IPsec SA found;Site-to-site VPN have connected\\u0026\\n\"," +
+ "\"result\":true,\"contextMap\":{},\"wait\":0,\"bypassHostMaintenance\":false}}]";
+ Response response = new Response(Version.v2, 1L, 2L, 3L, 1L, (short)1, content);
+ Answer answer = response.getAnswer();
+ Assert.assertTrue(answer instanceof CheckS2SVpnConnectionsAnswer);
+ }
+
+}
diff --git a/deps/install-non-oss.sh b/deps/install-non-oss.sh
index 56cfc2cba9c..e40946ce312 100755
--- a/deps/install-non-oss.sh
+++ b/deps/install-non-oss.sh
@@ -85,4 +85,7 @@ mvn install:install-file -Dfile=juniper-contrail-api-1.0-SNAPSHOT.jar -DgroupId=
# From https://github.com/radu-todirica/tungsten-api/raw/master/net/juniper/tungsten/juniper-tungsten-api/2.0/juniper-tungsten-api-2.0.jar
mvn install:install-file -Dfile=juniper-tungsten-api-2.0.jar -DgroupId=net.juniper.tungsten -DartifactId=juniper-tungsten-api -Dversion=2.0 -Dpackaging=jar
+# Netris Integration
+mvn install:install-file -Dfile=netris-java-sdk-1.0.0.jar -DgroupId=io.netris -DartifactId=netris-java-sdk -Dversion=1.0.0 -Dpackaging=jar
+
exit 0
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
index d8e97f0277b..adce5f2f8b4 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
@@ -82,6 +82,9 @@ public interface NetworkOrchestrationService {
ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600",
"Lock wait timeout (seconds) while implementing network", true, Scope.Global, null);
+ ConfigKey<String> DeniedRoutes = new ConfigKey<String>(String.class, "denied.routes", "Network", "",
+ "Routes that are denied, can not be used for Static Routes creation for the VPC Private Gateway", true, ConfigKey.Scope.Zone, null);
+
ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal",
"Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null);
@@ -109,6 +112,9 @@ public interface NetworkOrchestrationService {
static final ConfigKey<Boolean> NSX_ENABLED = new ConfigKey<>(Boolean.class, "nsx.plugin.enable", "Advanced", "false",
"Indicates whether to enable the NSX plugin", false, ConfigKey.Scope.Zone, null);
+ ConfigKey<Boolean> NETRIS_ENABLED = new ConfigKey<>(Boolean.class, "netris.plugin.enable", "Advanced", "false",
+ "Indicates whether to enable the Netris plugin", false, ConfigKey.Scope.Zone, null);
+
List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
throws ConcurrentOperationException;
diff --git a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
index 01fd54430d6..3191d014c66 100644
--- a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
+++ b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java
@@ -214,6 +214,7 @@ public interface ConfigurationManager {
* @param forVpc
* @param forTungsten
* @param forNsx
+ * @param forNetris
* @param domainIds
* @param zoneIds
* @return network offering object
@@ -223,11 +224,11 @@ public interface ConfigurationManager {
Integer networkRate, Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId,
boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent,
Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc,
- Boolean forTungsten, boolean forNsx, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol,
+ Boolean forTungsten, boolean forNsx, boolean forNetris, NetworkOffering.NetworkMode networkMode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol,
NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber);
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP,
- String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr, boolean forNsx)
+ String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr, Provider provider)
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException;
diff --git a/engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java b/engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java
index d69a72a02c5..7132094ce11 100644
--- a/engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java
+++ b/engine/components-api/src/main/java/com/cloud/network/addr/PublicIp.java
@@ -275,5 +275,9 @@ public class PublicIp implements PublicIpAddress {
return false;
}
+ @Override
+ public boolean isForRouter() {
+ return _addr.isForRouter();
+ }
}
diff --git a/engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java b/engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java
index c77874329fc..7bab2a26fb4 100644
--- a/engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java
+++ b/engine/components-api/src/main/java/com/cloud/network/rules/RulesManager.java
@@ -53,6 +53,8 @@ public interface RulesManager extends RulesService {
boolean disableStaticNat(long ipAddressId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException;
+ boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke);
+
/**
* @param networkId
* @param continueOnError
diff --git a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
index de69b894183..b192cd8d71c 100644
--- a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
+++ b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
@@ -93,5 +93,5 @@ public interface NetworkACLManager {
boolean applyACLToPrivateGw(PrivateGateway gateway) throws ResourceUnavailableException;
- boolean reorderAclRules(VpcVO vpc, List<? extends Network> networks, List<? extends NetworkACLItem> networkACLItems);
+ boolean reorderAclRules(VpcVO vpc, List<? extends Network> networks, List<? extends NetworkACLItem> networkACLItems, Network.Provider networkProvider);
}
diff --git a/engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java b/engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java
index a340f49c13f..9018c0d17a3 100644
--- a/engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java
+++ b/engine/components-api/src/main/java/com/cloud/network/vpc/VpcManager.java
@@ -35,6 +35,7 @@ import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
@@ -174,4 +175,20 @@ public interface VpcManager {
* @return
*/
boolean isSrcNatIpRequired(long vpcOfferingId);
+
+ boolean isSrcNatIpRequiredForVpcVr(long vpcOfferingId);
+
+ List<StaticRouteVO> getVpcStaticRoutes(Long vpcId);
+
+ List<StaticRouteProfile> getVpcStaticRoutes(List<? extends StaticRoute> routes);
+
+ boolean isProviderSupportServiceInVpc(long vpcId, Service service, Provider provider);
+
+ IPAddressVO getIpAddressForVpcVr(Vpc vpc, IPAddressVO ipAddress, boolean allocateIpIfNeeded);
+
+ boolean configStaticNatForVpcVr(Vpc vpc, IPAddressVO ipAddress);
+
+ void reconfigStaticNatForVpcVr(Long vpcId);
+
+ boolean applyStaticRouteForVpcVpnIfNeeded(Long vpcId, boolean updateAllVpn) throws ResourceUnavailableException;
}
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index e1b798d16d6..30b63053927 100644
--- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -43,6 +43,8 @@ import com.cloud.bgp.BGPService;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.dao.ASNumberDao;
import com.cloud.dc.dao.VlanDetailsDao;
+import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
+import com.cloud.network.dao.NetrisProviderDao;
import com.cloud.network.dao.NsxProviderDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.annotation.AnnotationService;
@@ -355,9 +357,13 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Inject
private NsxProviderDao nsxProviderDao;
@Inject
+ private NetrisProviderDao netrisProviderDao;
+ @Inject
private ASNumberDao asNumberDao;
@Inject
private BGPService bgpService;
+ @Inject
+ private Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
@Override
public List<NetworkGuru> getNetworkGurus() {
@@ -558,27 +564,27 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true, Network.GuestType.Shared, false, null, true, null, true,
- false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
+ false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
}
//#2 - SG enabled network offering
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
- null, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
+ null, true, false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
}
//#3 - shared network offering with no SG service
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true,
Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false,
- null, true, false, false, false, null,null, null, true, null, null, false);
+ null, true, false, false, false, false,null,null, null, true, null, null, false);
}
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE, "Offering for Tungsten Shared Security group enabled networks",
TrafficType.Guest, null, true, Availability.Optional, null, defaultTungstenSharedSGEnabledNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
- null, true, false, null, false, null, true, false, true, false, null, null,null, true, null, null, false);
+ null, true, false, null, false, null, true, false, true, false, false,null, null,null, true, null, null, false);
offering.setState(NetworkOffering.State.Enabled);
_networkOfferingDao.update(offering.getId(), offering);
}
@@ -588,14 +594,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
"Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null,
defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null,
- true, false, false, false, null, null,null, true, null, null, false);
+ true, false, false, false, false,null, null,null, true, null, null, false);
}
//#5 - default vpc offering with LB service
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
"Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null,
- defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null, null, false);
+ defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null,true, null, null, false);
}
//#6 - default vpc offering with no LB service
@@ -604,14 +610,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
defaultVPCOffProviders.remove(Service.Lb);
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
"Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional,
- null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null, null, false);
+ null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null,true, null, null, false);
}
//#7 - isolated offering with source nat disabled
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service",
TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null,
- true, null, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
+ true, null, true, false, null, false, null, true, false, false, false, false,null, null, null, true, null, null, false);
}
//#8 - network offering with internal lb service
@@ -633,7 +639,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
"Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders,
- true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, true, null, null, false);
+ true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, false,null, null, null, true, null, null, false);
offering.setInternalLb(true);
offering.setPublicLb(false);
_networkOfferingDao.update(offering.getId(), offering);
@@ -664,7 +670,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
"Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null,
- netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false, null, null, null, true, null, null, false);
+ netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false,false, null, null, null, true, null, null, false);
offering.setDedicatedLB(false);
_networkOfferingDao.update(offering.getId(), offering);
}
@@ -821,6 +827,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (domainId != null && aclType == ACLType.Domain) {
_networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null || subdomainAccess);
}
+ String ipv6Cidr = network.getIp6Cidr();
+ String ipv6Gateway = network.getIp6Gateway();
+ if (StringUtils.isNoneBlank(ipv6Cidr, ipv6Gateway)) {
+ ipv6Service.assignIpv6SubnetToNetwork(ipv6Cidr, networkPersisted.getId());
+ }
}
});
guru.setup(network, relatedFile);
@@ -1055,7 +1066,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return Transaction.execute(new TransactionCallback<NicVO>() {
@Override
public NicVO doInTransaction(TransactionStatus status) {
- NicVO vo = _nicDao.findByIp4AddressAndNetworkId(profile.getIPv4Address(), networkId);
+ NicVO vo = _nicDao.findNonPlaceHolderByIp4AddressAndNetworkId(profile.getIPv4Address(), networkId);
if (vo == null) {
applyProfileToNic(nic, profile, deviceId);
vo = _nicDao.persist(nic);
@@ -1082,10 +1093,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return null;
}
- if (isNicAllocatedForNsxPublicNetworkOnVR(network, profile, vm)) {
+ if (isNicAllocatedForProviderPublicNetworkOnVR(network, profile, vm, Provider.Nsx)) {
String guruName = "NsxPublicNetworkGuru";
NetworkGuru nsxGuru = AdapterBase.getAdapterByName(networkGurus, guruName);
nsxGuru.allocate(network, profile, vm);
+ } else if (isNicAllocatedForProviderPublicNetworkOnVR(network, profile, vm, Provider.Netris)) {
+ String guruName = "NetrisPublicNetworkGuru";
+ NetworkGuru netrisGuru = AdapterBase.getAdapterByName(networkGurus, guruName);
+ netrisGuru.allocate(network, profile, vm);
}
if (isDefaultNic != null) {
@@ -1148,7 +1163,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return new Pair<NicProfile, Integer>(vmNic, Integer.valueOf(deviceId));
}
- private boolean isNicAllocatedForNsxPublicNetworkOnVR(Network network, NicProfile requested, VirtualMachineProfile vm) {
+ private boolean isNicAllocatedForProviderPublicNetworkOnVR(Network network, NicProfile requested, VirtualMachineProfile vm, Provider provider) {
if (ObjectUtils.anyNull(network, requested, vm)) {
return false;
}
@@ -1158,7 +1173,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return false;
}
long dataCenterId = vm.getVirtualMachine().getDataCenterId();
- if (nsxProviderDao.findByZoneId(dataCenterId) == null) {
+ if (Provider.Nsx == provider && nsxProviderDao.findByZoneId(dataCenterId) == null) {
+ return false;
+ } else if (Provider.Netris == provider && netrisProviderDao.findByZoneId(dataCenterId) == null) {
return false;
}
@@ -1168,14 +1185,16 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (CollectionUtils.isEmpty(ips)) {
return false;
}
+
ips = ips.stream().filter(x -> !x.getAddress().addr().equals(requested.getIPv4Address())).collect(Collectors.toList());
IPAddressVO ip = ips.get(0);
- VlanDetailsVO vlanDetail = vlanDetailsDao.findDetail(ip.getVlanId(), ApiConstants.NSX_DETAIL_KEY);
+ String detailKey = Provider.Nsx == provider ? ApiConstants.NSX_DETAIL_KEY : ApiConstants.NETRIS_DETAIL_KEY;
+ VlanDetailsVO vlanDetail = vlanDetailsDao.findDetail(ip.getVlanId(), detailKey);
if (vlanDetail == null) {
return false;
}
- boolean isForNsx = vlanDetail.getValue().equalsIgnoreCase("true");
- return isForNsx && !ip.isForSystemVms();
+ boolean isForProvider = vlanDetail.getValue().equalsIgnoreCase("true");
+ return isForProvider && !ip.isForSystemVms();
}
private void setMtuDetailsInVRNic(final Pair<NetworkVO, VpcVO> networks, Network network, NicVO vo) {
@@ -1696,6 +1715,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
}
+ if (network.getVpcId() != null) {
+ _vpcMgr.reconfigStaticNatForVpcVr(network.getVpcId());
+ try {
+ _vpcMgr.applyStaticRouteForVpcVpnIfNeeded(network.getVpcId(), true);
+ } catch (ResourceUnavailableException e) {
+ logger.error("Unable to apply static routes for vpc " + network.getVpcId() + " due to " + e.getMessage());
+ }
+ }
} finally {
for (final NetworkElement element : networkElements) {
if (element instanceof AggregatedCommandExecutor && providersToImplement.contains(element.getProvider())) {
@@ -1941,6 +1968,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
ip.setOneToOneNat(false);
ip.setAssociatedWithVmId(null);
ip.setVmIp(null);
+ ip.setForRouter(false);
_ipAddressDao.update(ip.getId(), ip);
}
}
@@ -3283,6 +3311,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
}
+ if (network.getVpcId() != null) {
+ _vpcMgr.reconfigStaticNatForVpcVr(network.getVpcId());
+ try {
+ _vpcMgr.applyStaticRouteForVpcVpnIfNeeded(network.getVpcId(), true);
+ } catch (ResourceUnavailableException e) {
+ logger.error("Unable to apply static routes for vpc " + network.getVpcId() + " due to " + e.getMessage());
+ }
+ }
return success;
}
@@ -4863,9 +4899,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Override
public ConfigKey<?>[] getConfigKeys() {
- return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
+ return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout, DeniedRoutes,
GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RollingRestartEnabled,
- TUNGSTEN_ENABLED, NSX_ENABLED };
+ TUNGSTEN_ENABLED, NSX_ENABLED, NETRIS_ENABLED };
}
}
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
index 84f38f05441..a6c267bb189 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDao.java
@@ -64,4 +64,6 @@ public interface VlanDao extends GenericDao<VlanVO, Long> {
List<VlanVO> listIpv6RangeByZoneIdAndVlanId(long zoneId, String vlanId);
List<VlanVO> listIpv6SupportingVlansByZone(long zoneId);
+
+ List<VlanVO> listVlansForExternalNetworkProvider(long zoneId, String detailKey);
}
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
index 461a9a13b10..d9fad3cad12 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/dc/dao/VlanDaoImpl.java
@@ -26,6 +26,7 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.dc.VlanDetailsVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@@ -67,6 +68,8 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
protected SearchBuilder<VlanVO> ZoneVlanIp6Search;
protected SearchBuilder<VlanVO> ZoneIp6Search;
protected SearchBuilder<VlanVO> ZoneVlansSearch;
+ protected SearchBuilder<VlanVO> ProviderVlanSearch;
+ protected SearchBuilder<VlanDetailsVO> VlanDetailsProviderSearch;
protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch;
protected SearchBuilder<DomainVlanMapVO> DomainVlanMapSearch;
@@ -79,6 +82,8 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
protected DomainVlanMapDao _domainVlanMapDao;
@Inject
protected IPAddressDao _ipAddressDao;
+ @Inject
+ protected VlanDetailsDao vlanDetailsDao;
@Override
public VlanVO findByZoneAndVlanId(long zoneId, String vlanId) {
@@ -277,6 +282,19 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
ZoneVlansSearch.and("zoneId", ZoneVlansSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneVlansSearch.and("vlan", ZoneVlansSearch.entity().getVlanTag(), SearchCriteria.Op.IN);
ZoneVlansSearch.done();
+
+ ProviderVlanSearch = createSearchBuilder();
+ ProviderVlanSearch.and("removed", ProviderVlanSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
+ ProviderVlanSearch.and("dataCenterId", ProviderVlanSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
+ VlanDetailsProviderSearch = vlanDetailsDao.createSearchBuilder();
+ VlanDetailsProviderSearch.and("name", VlanDetailsProviderSearch.entity().getName(), SearchCriteria.Op.EQ);
+ VlanDetailsProviderSearch.and("value", VlanDetailsProviderSearch.entity().getValue(), SearchCriteria.Op.EQ);
+ ProviderVlanSearch.join("VlanDetailsProviderSearch", VlanDetailsProviderSearch, ProviderVlanSearch.entity().getId(),
+ VlanDetailsProviderSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
+
+ VlanDetailsProviderSearch.done();
+ ProviderVlanSearch.done();
+
return result;
}
@@ -434,4 +452,13 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
return listBy(sc);
}
+ @Override
+ public List<VlanVO> listVlansForExternalNetworkProvider(long zoneId, String detailKey) {
+ SearchCriteria<VlanVO> sc = ProviderVlanSearch.create();
+ sc.setParameters("dataCenterId", zoneId);
+ sc.setJoinParameters("VlanDetailsProviderSearch", "name", detailKey);
+ sc.setJoinParameters("VlanDetailsProviderSearch", "value", "true");
+ return search(sc, null);
+ }
+
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java
index aa143838c34..2b5277f1560 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressDaoImpl.java
@@ -197,6 +197,7 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
address.setSourceNat(false);
address.setOneToOneNat(false);
address.setAssociatedWithVmId(null);
+ address.setForRouter(false);
address.setState(State.Free);
address.setAssociatedWithNetworkId(null);
address.setVpcId(null);
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java
index 4c7569a55b9..6be7d24e367 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/IPAddressVO.java
@@ -116,6 +116,9 @@ public class IPAddressVO implements IpAddress {
@Column(name = "forsystemvms")
private boolean forSystemVms = false;
+ @Column(name = "for_router")
+ private boolean forRouter = false;
+
@Column(name= GenericDao.REMOVED_COLUMN)
private Date removed;
@@ -385,4 +388,13 @@ public class IPAddressVO implements IpAddress {
public boolean isForSystemVms() {
return forSystemVms;
}
+
+ @Override
+ public boolean isForRouter() {
+ return forRouter;
+ }
+
+ public void setForRouter(boolean forRouter) {
+ this.forRouter = forRouter;
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDao.java
similarity index 83%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDao.java
index d3fef252f50..fe21f72e4db 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDao.java
@@ -16,8 +16,9 @@
// under the License.
package com.cloud.network.dao;
+import com.cloud.network.element.NetrisProviderVO;
import com.cloud.utils.db.GenericDao;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public interface NetrisProviderDao extends GenericDao<NetrisProviderVO, Long> {
+ NetrisProviderVO findByZoneId(long zoneId);
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDaoImpl.java
similarity index 51%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
copy to engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDaoImpl.java
index d1fde963217..86ea04f1db0 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/NetrisProviderDaoImpl.java
@@ -16,32 +16,37 @@
// under the License.
package com.cloud.network.dao;
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
+import com.cloud.network.element.NetrisProviderVO;
+import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
+import org.springframework.stereotype.Component;
@Component
-public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase<Site2SiteVpnGatewayVO, Long> implements Site2SiteVpnGatewayDao {
- @Inject
- protected IPAddressDao _addrDao;
-
-
- private final SearchBuilder<Site2SiteVpnGatewayVO> AllFieldsSearch;
-
- protected Site2SiteVpnGatewayDaoImpl() {
- AllFieldsSearch = createSearchBuilder();
- AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), SearchCriteria.Op.EQ);
- AllFieldsSearch.done();
+@DB()
+public class NetrisProviderDaoImpl extends GenericDaoBase<NetrisProviderVO, Long> implements NetrisProviderDao {
+
+ final SearchBuilder<NetrisProviderVO> allFieldsSearch;
+
+ public NetrisProviderDaoImpl() {
+ super();
+ allFieldsSearch = createSearchBuilder();
+ allFieldsSearch.and("id", allFieldsSearch.entity().getId(),
+ SearchCriteria.Op.EQ);
+ allFieldsSearch.and("uuid", allFieldsSearch.entity().getUuid(),
+ SearchCriteria.Op.EQ);
+ allFieldsSearch.and("hostname", allFieldsSearch.entity().getUrl(),
+ SearchCriteria.Op.EQ);
+ allFieldsSearch.and("zone_id", allFieldsSearch.entity().getZoneId(),
+ SearchCriteria.Op.EQ);
+ allFieldsSearch.done();
}
@Override
- public Site2SiteVpnGatewayVO findByVpcId(long vpcId) {
- SearchCriteria<Site2SiteVpnGatewayVO> sc = AllFieldsSearch.create();
- sc.setParameters("vpcId", vpcId);
+ public NetrisProviderVO findByZoneId(long zoneId) {
+ SearchCriteria<NetrisProviderVO> sc = allFieldsSearch.create();
+ sc.setParameters("zone_id", zoneId);
return findOneBy(sc);
}
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java
index 8113c06c866..f4120a138ac 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDao.java
@@ -33,4 +33,6 @@ public interface RemoteAccessVpnDao extends GenericDao<RemoteAccessVpnVO, Long>
List<RemoteAccessVpnVO> findByAccount(Long accountId);
List<RemoteAccessVpnVO> listByNetworkId(Long networkId);
+
+ List<RemoteAccessVpnVO> listByVpcId(Long vpcId);
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
index 484aa6f6631..ccbc60a5562 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/RemoteAccessVpnDaoImpl.java
@@ -85,4 +85,11 @@ public class RemoteAccessVpnDaoImpl extends GenericDaoBase<RemoteAccessVpnVO, Lo
sc.setParameters("networkId", networkId);
return listBy(sc);
}
+
+ @Override
+ public List<RemoteAccessVpnVO> listByVpcId(Long vpcId) {
+ SearchCriteria<RemoteAccessVpnVO> sc = AllFieldsSearch.create();
+ sc.setParameters("vpcId", vpcId);
+ return listBy(sc);
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
index d3fef252f50..3475003c269 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
@@ -20,4 +20,6 @@ import com.cloud.utils.db.GenericDao;
public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+
+ Site2SiteVpnGatewayVO findByPublicIpAddress(long ipAddressId);
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
index d1fde963217..0aeefe90c29 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java
@@ -35,6 +35,7 @@ public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase<Site2SiteVpnGatew
protected Site2SiteVpnGatewayDaoImpl() {
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("ipAddressId", AllFieldsSearch.entity().getAddrId(), SearchCriteria.Op.EQ);
AllFieldsSearch.done();
}
@@ -44,4 +45,11 @@ public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase<Site2SiteVpnGatew
sc.setParameters("vpcId", vpcId);
return findOneBy(sc);
}
+
+ @Override
+ public Site2SiteVpnGatewayVO findByPublicIpAddress(long ipAddressId) {
+ SearchCriteria<Site2SiteVpnGatewayVO> sc = AllFieldsSearch.create();
+ sc.setParameters("ipAddressId", ipAddressId);
+ return findOneBy(sc);
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/element/NetrisProviderVO.java b/engine/schema/src/main/java/com/cloud/network/element/NetrisProviderVO.java
new file mode 100644
index 00000000000..113678f7b01
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/network/element/NetrisProviderVO.java
@@ -0,0 +1,265 @@
+// 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 com.cloud.network.netris.NetrisProvider;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+import java.util.UUID;
+
+@Entity
+@Table(name = "netris_providers")
+public class NetrisProviderVO implements NetrisProvider {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ long id;
+
+ @Column(name = "uuid")
+ private String uuid;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "zone_id")
+ private long zoneId;
+
+ @Column(name = "host_id")
+ private long hostId;
+
+ @Column(name = "url")
+ private String url;
+
+ @Column(name = "username")
+ private String username;
+
+ @Column(name = "password")
+ private String password;
+
+ @Column(name = "site_name")
+ private String siteName;
+
+ @Column(name = "tenant_name")
+ private String tenantName;
+
+ @Column(name = "netris_tag")
+ private String netrisTag;
+
+ @Column(name = "created")
+ private Date created;
+
+ @Column(name = "removed")
+ private Date removed;
+
+ public NetrisProviderVO() {
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ @Override
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ public void setZoneId(long zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ public long getHostId() {
+ return hostId;
+ }
+
+ public void setHostId(long hostId) {
+ this.hostId = hostId;
+ }
+
+ @Override
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ @Override
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getSiteName() {
+ return siteName;
+ }
+
+ public void setSiteName(String siteName) {
+ this.siteName = siteName;
+ }
+
+ public String getTenantName() {
+ return tenantName;
+ }
+
+ public void setTenantName(String tenantName) {
+ this.tenantName = tenantName;
+ }
+
+ public String getNetrisTag() {
+ return netrisTag;
+ }
+
+ public void setNetrisTag(String netrisTag) {
+ this.netrisTag = netrisTag;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
+ public Date getRemoved() {
+ return removed;
+ }
+
+ public void setRemoved(Date removed) {
+ this.removed = removed;
+ }
+
+ public static final class Builder {
+ private long zoneId;
+ private long hostId;
+ private String name;
+ private String url;
+ private String username;
+ private String password;
+ private String siteName;
+ private String tenantName;
+ private String netrisTag;
+
+ public Builder() {
+ // Default constructor
+ }
+
+ public Builder setZoneId(long zoneId) {
+ this.zoneId = zoneId;
+ return this;
+ }
+
+ public Builder setHostId(long hostId) {
+ this.hostId = hostId;
+ return this;
+ }
+
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder setUrl(String url) {
+ this.url = url;
+ return this;
+ }
+
+ public Builder setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public Builder setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public Builder setSiteName(String siteName) {
+ this.siteName = siteName;
+ return this;
+ }
+
+ public Builder setTenantName(String tenantName) {
+ this.tenantName = tenantName;
+ return this;
+ }
+
+ public Builder setNetrisTag(String netrisTag) {
+ this.netrisTag = netrisTag;
+ return this;
+ }
+
+ public NetrisProviderVO build() {
+ NetrisProviderVO provider = new NetrisProviderVO();
+ provider.setZoneId(this.zoneId);
+ provider.setHostId(this.hostId);
+ provider.setUuid(UUID.randomUUID().toString());
+ provider.setName(this.name);
+ provider.setUrl(this.url);
+ provider.setUsername(this.username);
+ provider.setPassword(this.password);
+ provider.setSiteName(this.siteName);
+ provider.setTenantName(this.tenantName);
+ provider.setNetrisTag(this.netrisTag);
+ provider.setCreated(new Date());
+ return provider;
+ }
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java
index 2246bd6eed2..632d96819cd 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/StaticRouteVO.java
@@ -27,6 +27,7 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
+import javax.persistence.Transient;
import com.cloud.utils.db.GenericDao;
@@ -42,7 +43,10 @@ public class StaticRouteVO implements StaticRoute {
String uuid;
@Column(name = "vpc_gateway_id", updatable = false)
- long vpcGatewayId;
+ Long vpcGatewayId;
+
+ @Column(name = "next_hop")
+ private String nextHop;
@Column(name = "cidr")
private String cidr;
@@ -67,6 +71,9 @@ public class StaticRouteVO implements StaticRoute {
uuid = UUID.randomUUID().toString();
}
+ @Transient
+ boolean forVpn = false;
+
/**
* @param vpcGatewayId
* @param cidr
@@ -74,7 +81,7 @@ public class StaticRouteVO implements StaticRoute {
* @param accountId TODO
* @param domainId TODO
*/
- public StaticRouteVO(long vpcGatewayId, String cidr, Long vpcId, long accountId, long domainId) {
+ public StaticRouteVO(Long vpcGatewayId, String cidr, Long vpcId, long accountId, long domainId, String nextHop) {
super();
this.vpcGatewayId = vpcGatewayId;
this.cidr = cidr;
@@ -82,14 +89,32 @@ public class StaticRouteVO implements StaticRoute {
this.vpcId = vpcId;
this.accountId = accountId;
this.domainId = domainId;
+ this.nextHop = nextHop;
+ uuid = UUID.randomUUID().toString();
+ }
+
+ public StaticRouteVO(String cidr, Long vpcId, long accountId, long domainId, String nextHop, State state, boolean forVpn) {
+ super();
+ this.cidr = cidr;
+ this.state = state;
+ this.vpcId = vpcId;
+ this.accountId = accountId;
+ this.domainId = domainId;
+ this.nextHop = nextHop;
uuid = UUID.randomUUID().toString();
+ this.forVpn = forVpn;
}
@Override
- public long getVpcGatewayId() {
+ public Long getVpcGatewayId() {
return vpcGatewayId;
}
+ @Override
+ public String getNextHop() {
+ return nextHop;
+ }
+
@Override
public String getCidr() {
return cidr;
@@ -145,4 +170,8 @@ public class StaticRouteVO implements StaticRoute {
public String getName() {
return null;
}
+
+ public boolean isForVpn() {
+ return forVpn;
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java
index 41254ba4a8b..7945642c1d6 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java
@@ -59,9 +59,6 @@ public class VpcOfferingVO implements VpcOffering {
@Column(name = "default")
boolean isDefault = false;
- @Column(name = "for_nsx")
- boolean forNsx = false;
-
@Column(name = "network_mode")
NetworkOffering.NetworkMode networkMode;
@@ -158,14 +155,6 @@ public class VpcOfferingVO implements VpcOffering {
return isDefault;
}
- public boolean isForNsx() {
- return forNsx;
- }
-
- public void setForNsx(boolean forNsx) {
- this.forNsx = forNsx;
- }
-
public NetworkOffering.NetworkMode getNetworkMode() {
return networkMode;
}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
index 06cfd25e670..020536e97ec 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
@@ -18,6 +18,7 @@ package com.cloud.network.vpc.dao;
import java.util.List;
+import com.cloud.network.Network;
import com.cloud.network.Network.Service;
import com.cloud.network.vpc.VpcOfferingServiceMapVO;
import com.cloud.utils.db.GenericDao;
@@ -37,4 +38,8 @@ public interface VpcOfferingServiceMapDao extends GenericDao<VpcOfferingServiceM
VpcOfferingServiceMapVO findByServiceProviderAndOfferingId(String service, String provider, long vpcOfferingId);
+ boolean isProviderForVpcOffering(Network.Provider provider, long vpcOfferingId);
+
+ List<VpcOfferingServiceMapVO> listProvidersForServiceForVpcOffering(long vpcOfferingId, Service service);
+
}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
index c7400f6edfd..dcb1becf9e8 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
@@ -19,6 +19,7 @@ package com.cloud.network.vpc.dao;
import java.util.List;
+import com.cloud.network.Network;
import org.springframework.stereotype.Component;
import com.cloud.network.Network.Service;
@@ -110,4 +111,22 @@ public class VpcOfferingServiceMapDaoImpl extends GenericDaoBase<VpcOfferingServ
return findOneBy(sc);
}
+
+ @Override
+ public boolean isProviderForVpcOffering(Network.Provider provider, long vpcOfferingId) {
+ SearchCriteria<VpcOfferingServiceMapVO> sc = AllFieldsSearch.create();
+ sc.setParameters("vpcOffId", vpcOfferingId);
+ sc.setParameters("provider", provider.getName());
+ return findOneBy(sc) != null;
+ }
+
+ @Override
+ public List<VpcOfferingServiceMapVO> listProvidersForServiceForVpcOffering(long vpcOfferingId, Service service) {
+ SearchCriteria<VpcOfferingServiceMapVO> sc = AllFieldsSearch.create();
+
+ sc.setParameters("vpcOffId", vpcOfferingId);
+ sc.setParameters("service", service.getName());
+
+ return customSearch(sc, null);
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
index 753c45fcc78..a5c4c83ff0f 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcServiceMapDaoImpl.java
@@ -68,8 +68,15 @@ public class VpcServiceMapDaoImpl extends GenericDaoBase<VpcServiceMapVO, Long>
@Override
public boolean canProviderSupportServiceInVpc(long vpcId, Service service, Provider provider) {
- // TODO Auto-generated method stub
- return false;
+ SearchCriteria<VpcServiceMapVO> sc = AllFieldsSearch.create();
+ sc.setParameters("vpcId", vpcId);
+ sc.setParameters("service", service.getName());
+ sc.setParameters("provider", provider.getName());
+ if (findOneBy(sc) != null) {
+ return true;
+ } else {
+ return false;
+ }
}
@Override
diff --git a/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java
index 0bf110757d7..cf766551421 100644
--- a/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java
+++ b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java
@@ -133,12 +133,6 @@ public class NetworkOfferingVO implements NetworkOffering {
@Column(name = "for_vpc")
boolean forVpc;
- @Column(name = "for_tungsten")
- boolean forTungsten = false;
-
- @Column(name = "for_nsx")
- boolean forNsx = false;
-
@Column(name = "network_mode")
NetworkMode networkMode;
@@ -199,24 +193,6 @@ public class NetworkOfferingVO implements NetworkOffering {
this.forVpc = isForVpc;
}
- @Override
- public boolean isForTungsten() {
- return forTungsten;
- }
-
- public void setForTungsten(boolean forTungsten) {
- this.forTungsten = forTungsten;
- }
-
- @Override
- public boolean isForNsx() {
- return forNsx;
- }
-
- public void setForNsx(boolean forNsx) {
- this.forNsx = forNsx;
- }
-
@Override
public NetworkMode getNetworkMode() {
return networkMode;
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
index d34b03c4cb0..70a2558e2d4 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java
@@ -46,8 +46,12 @@ public interface NicDao extends GenericDao<NicVO, Long> {
NicVO findByNetworkIdAndTypeIncludingRemoved(long networkId, VirtualMachine.Type vmType);
+ NicVO findNonPlaceHolderByNetworkIdAndType(long networkId, VirtualMachine.Type vmType);
+
NicVO findByIp4AddressAndNetworkId(String ip4Address, long networkId);
+ NicVO findNonPlaceHolderByIp4AddressAndNetworkId(String ip4Address, long networkId);
+
NicVO findByNetworkIdAndMacAddress(long networkId, String mac);
NicVO findDefaultNicForVM(long instanceId);
diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
index 7d1af1982ae..3618785c1b8 100644
--- a/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java
@@ -69,6 +69,7 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
AllFieldsSearch.and("secondaryip", AllFieldsSearch.entity().getSecondaryIp(), Op.EQ);
AllFieldsSearch.and("nicid", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.and("strategy", AllFieldsSearch.entity().getReservationStrategy(), Op.EQ);
+ AllFieldsSearch.and("strategyNEQ", AllFieldsSearch.entity().getReservationStrategy(), Op.NEQ);
AllFieldsSearch.and("reserverName",AllFieldsSearch.entity().getReserver(),Op.EQ);
AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.EQ);
AllFieldsSearch.and("deviceid", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
@@ -195,6 +196,15 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
return findByNetworkIdAndTypeInternal(networkId, vmType, true);
}
+ @Override
+ public NicVO findNonPlaceHolderByNetworkIdAndType(long networkId, VirtualMachine.Type vmType) {
+ SearchCriteria<NicVO> sc = AllFieldsSearch.create();
+ sc.setParameters("network", networkId);
+ sc.setParameters("vmType", vmType);
+ sc.setParameters("strategyNEQ", Nic.ReservationStrategy.PlaceHolder.toString());
+ return findOneBy(sc);
+ }
+
@Override
public NicVO findByNetworkIdTypeAndGateway(long networkId, VirtualMachine.Type vmType, String gateway) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
@@ -222,6 +232,16 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
return findOneBy(sc);
}
+ @Override
+ public NicVO findNonPlaceHolderByIp4AddressAndNetworkId(String ip4Address, long networkId) {
+ SearchCriteria<NicVO> sc = AllFieldsSearch.create();
+ sc.setParameters("address", ip4Address);
+ sc.setParameters("network", networkId);
+ sc.setParameters("strategyNEQ", Nic.ReservationStrategy.PlaceHolder.toString());
+ return findOneBy(sc);
+ }
+
+
@Override
public NicVO findByNetworkIdAndMacAddress(long networkId, String mac) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index 171685ce413..9a0bd416aca 100644
--- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -137,6 +137,7 @@
<bean id="objectInDataStoreDaoImpl" class="org.apache.cloudstack.storage.db.ObjectInDataStoreDaoImpl" />
<bean id="ovsProviderDaoImpl" class="com.cloud.network.dao.OvsProviderDaoImpl" />
<bean id="nsxControllerDaoImpl" class="com.cloud.network.dao.NsxProviderDaoImpl" />
+ <bean id="netrisProviderDaoImpl" class="com.cloud.network.dao.NetrisProviderDaoImpl" />
<bean id="tungstenControllerDaoImpl" class="com.cloud.network.dao.TungstenProviderDaoImpl"/>
<bean id="physicalNetworkDaoImpl" class="com.cloud.network.dao.PhysicalNetworkDaoImpl" />
<bean id="physicalNetworkIsolationMethodDaoImpl" class="com.cloud.network.dao.PhysicalNetworkIsolationMethodDaoImpl" />
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql
index c36b71c2f25..133a8b582b9 100644
--- a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql
@@ -425,3 +425,40 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervi
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_instance', 'delete_protection', 'boolean DEFAULT FALSE COMMENT "delete protection for vm" ');
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.volumes', 'delete_protection', 'boolean DEFAULT FALSE COMMENT "delete protection for volumes" ');
+
+-- Netris Plugin
+CREATE TABLE `cloud`.`netris_providers` (
+ `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
+ `uuid` varchar(40),
+ `zone_id` bigint unsigned NOT NULL COMMENT 'Zone ID',
+ `host_id` bigint unsigned NOT NULL COMMENT 'Host ID',
+ `name` varchar(40),
+ `url` varchar(255) NOT NULL,
+ `username` varchar(255) NOT NULL,
+ `password` varchar(255) NOT NULL,
+ `site_name` varchar(255) NOT NULL,
+ `tenant_name` varchar(255) NOT NULL,
+ `netris_tag` varchar(255) NOT NULL,
+ `created` datetime NOT NULL COMMENT 'created date',
+ `removed` datetime COMMENT 'removed date if not null',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_netris_providers__zone_id` FOREIGN KEY `fk_netris_providers__zone_id` (`zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE,
+ INDEX `i_netris_providers__zone_id`(`zone_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- Drop the Tungsten and NSX columns from the network offerings (replaced by checking the provider on the ntwk_offering_service_map table)
+ALTER TABLE `cloud`.`network_offerings` DROP COLUMN `for_tungsten`;
+ALTER TABLE `cloud`.`network_offerings` DROP COLUMN `for_nsx`;
+
+-- Drop the Tungsten and NSX columns from the VPC offerings (replaced by checking the provider on the vpc_offering_service_map table)
+ALTER TABLE `cloud`.`vpc_offerings` DROP COLUMN `for_nsx`;
+
+-- Add next_hop to the static_routes table
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.static_routes', 'next_hop', 'varchar(50) COMMENT "next hop of the static route" AFTER `vpc_gateway_id`');
+
+-- Add `for_router` to `user_ip_address` table
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user_ip_address', 'for_router', 'tinyint(1) DEFAULT 0 COMMENT "True if the ip address is used by Domain Router to expose services"');
+
+-- Add Netris Autoscaling rules
+INSERT IGNORE INTO `cloud`.`counter` (uuid, provider, source, name, value, created) VALUES (UUID(), 'Netris', 'cpu', 'VM CPU - average percentage', 'vm.cpu.average.percentage', NOW());
+INSERT IGNORE INTO `cloud`.`counter` (uuid, provider, source, name, value, created) VALUES (UUID(), 'Netris', 'memory', 'VM Memory - average percentage', 'vm.memory.average.percentage', NOW());
diff --git a/engine/schema/src/main/resources/META-INF/db/views/cloud.network_offering_view.sql b/engine/schema/src/main/resources/META-INF/db/views/cloud.network_offering_view.sql
index b6abaabcd48..4fb12ce0388 100644
--- a/engine/schema/src/main/resources/META-INF/db/views/cloud.network_offering_view.sql
+++ b/engine/schema/src/main/resources/META-INF/db/views/cloud.network_offering_view.sql
@@ -59,8 +59,6 @@ SELECT
`network_offerings`.`supports_public_access` AS `supports_public_access`,
`network_offerings`.`supports_vm_autoscaling` AS `supports_vm_autoscaling`,
`network_offerings`.`for_vpc` AS `for_vpc`,
- `network_offerings`.`for_tungsten` AS `for_tungsten`,
- `network_offerings`.`for_nsx` AS `for_nsx`,
`network_offerings`.`network_mode` AS `network_mode`,
`network_offerings`.`service_package_id` AS `service_package_id`,
`network_offerings`.`routing_mode` AS `routing_mode`,
diff --git a/engine/schema/src/main/resources/META-INF/db/views/cloud.vpc_offering_view.sql b/engine/schema/src/main/resources/META-INF/db/views/cloud.vpc_offering_view.sql
index c74d50590de..751d8f91a25 100644
--- a/engine/schema/src/main/resources/META-INF/db/views/cloud.vpc_offering_view.sql
+++ b/engine/schema/src/main/resources/META-INF/db/views/cloud.vpc_offering_view.sql
@@ -28,7 +28,6 @@ select
`vpc_offerings`.`display_text` AS `display_text`,
`vpc_offerings`.`state` AS `state`,
`vpc_offerings`.`default` AS `default`,
- `vpc_offerings`.`for_nsx` AS `for_nsx`,
`vpc_offerings`.`network_mode` AS `network_mode`,
`vpc_offerings`.`created` AS `created`,
`vpc_offerings`.`removed` AS `removed`,
diff --git a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
index e39b40cfc68..2e9d6989550 100644
--- a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
+++ b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
@@ -34,6 +34,7 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.GuestType;
@@ -125,6 +126,11 @@ public class BaremetalDhcpElement extends AdapterBase implements DhcpServiceProv
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return true;
diff --git a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
index fa708e7be4c..adcb96f6116 100644
--- a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
+++ b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
@@ -29,6 +29,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.GuestType;
@@ -161,6 +162,11 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement {
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
private void releaseVlan(Network network, VirtualMachineProfile vm) {
vlanMgr.releaseVlan(network, vm);
}
diff --git a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
index d2c9731ddd1..2ec05d443aa 100644
--- a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
+++ b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
@@ -30,6 +30,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
@@ -124,6 +125,11 @@ public class BaremetalUserdataElement extends AdapterBase implements NetworkElem
return false;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
// TODO Auto-generated method stub
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
index 26b8de53083..8ed780a9714 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java
@@ -51,6 +51,10 @@ public class BridgeVifDriver extends VifDriverBase {
private String _controlCidr = NetUtils.getLinkLocalCIDR();
private Long libvirtVersion;
+ private static boolean isVxlanOrNetris(String protocol) {
+ return protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme()) || protocol.equals(Networks.BroadcastDomainType.Netris.scheme());
+ }
+
@Override
public void configure(Map<String, Object> params) throws ConfigurationException {
@@ -177,7 +181,7 @@ public class BridgeVifDriver extends VifDriverBase {
protected boolean isBroadcastTypeVlanOrVxlan(final NicTO nic) {
return nic != null && (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
- || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan);
+ || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Netris);
}
protected boolean isValidProtocolAndVnetId(final String vNetId, final String protocol) {
@@ -284,7 +288,7 @@ public class BridgeVifDriver extends VifDriverBase {
private String createVnetBr(String vNetId, String pifKey, String protocol) throws InternalErrorException {
String nic = _pifs.get(pifKey);
- if (nic == null || protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+ if (nic == null || isVxlanOrNetris(protocol)) {
// if not found in bridge map, maybe traffic label refers to pif already?
File pif = new File("/sys/class/net/" + pifKey);
if (pif.isDirectory()) {
@@ -292,7 +296,7 @@ public class BridgeVifDriver extends VifDriverBase {
}
}
String brName = "";
- if (protocol.equals(Networks.BroadcastDomainType.Vxlan.scheme())) {
+ if (isVxlanOrNetris(protocol)) {
brName = generateVxnetBrName(nic, vNetId);
} else {
brName = generateVnetBrName(nic, vNetId);
@@ -304,7 +308,7 @@ public class BridgeVifDriver extends VifDriverBase {
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())) {
+ if (isVxlanOrNetris(protocol)) {
script = _modifyVxlanPath;
}
final Script command = new Script(script, _timeout, logger);
@@ -358,6 +362,7 @@ public class BridgeVifDriver extends VifDriverBase {
}
String scriptPath = null;
+ // TODO: check for netris as well
if (cmdout != null && cmdout.contains("vxlan")) {
scriptPath = _modifyVxlanPath;
} else {
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
index 2503e0ac7fd..441bdb83854 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
@@ -24,7 +24,7 @@ import java.util.Set;
import javax.inject.Inject;
-
+import com.cloud.network.IpAddress;
import com.cloud.api.commands.DeleteCiscoNexusVSMCmd;
import com.cloud.api.commands.DisableCiscoNexusVSMCmd;
import com.cloud.api.commands.EnableCiscoNexusVSMCmd;
@@ -106,6 +106,11 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return true;
diff --git a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
index 71be8b1a475..b5afc13dadd 100644
--- a/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
+++ b/plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java
@@ -2008,7 +2008,6 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
forVpc, true, false, false);
if (forNsx) {
defaultKubernetesServiceNetworkOffering.setNetworkMode(NetworkOffering.NetworkMode.NATTED);
- defaultKubernetesServiceNetworkOffering.setForNsx(true);
}
defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true);
defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled);
diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
index 6025a41d69c..b6cdbccf69c 100644
--- a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
+++ b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -712,7 +712,7 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
metricsResponse.setCpuTotal(hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
metricsResponse.setCpuUsed(hostResponse.getCpuUsed(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
metricsResponse.setCpuAllocated(hostResponse.getCpuAllocated(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
- metricsResponse.setLoadAverage(hostResponse.getAverageLoad());
+ metricsResponse.setCpuAverageLoad(hostResponse.getAverageLoad());
metricsResponse.setMemTotal(hostResponse.getMemoryTotal());
metricsResponse.setMemAllocated(hostResponse.getMemoryAllocated());
metricsResponse.setMemUsed(hostResponse.getMemoryUsed());
diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java
index 8e12d2cbb6d..39d759f333f 100644
--- a/plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java
+++ b/plugins/metrics/src/main/java/org/apache/cloudstack/response/HostMetricsResponse.java
@@ -52,10 +52,6 @@ public class HostMetricsResponse extends HostResponse {
@Param(description = "the total cpu allocated in Ghz")
private String cpuAllocated;
- @SerializedName("cpuloadaverage")
- @Param(description = "the average cpu load the last minute")
- private Double loadAverage;
-
@SerializedName("memorytotalgb")
@Param(description = "the total memory capacity in GiB")
private String memTotal;
@@ -132,12 +128,6 @@ public class HostMetricsResponse extends HostResponse {
}
}
- public void setLoadAverage(final Double loadAverage) {
- if (loadAverage != null) {
- this.loadAverage = loadAverage;
- }
- }
-
public void setCpuAllocated(final String cpuAllocated, final Integer cpuNumber, final Long cpuSpeed) {
if (cpuAllocated != null && cpuNumber != null && cpuSpeed != null) {
this.cpuAllocated = String.format("%.2f Ghz", parseCPU(cpuAllocated) * cpuNumber * cpuSpeed / (100.0 * 1000.0));
diff --git a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
index 5fc9480c610..f3624ebeb40 100644
--- a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
+++ b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
@@ -29,6 +29,7 @@ import java.util.UUID;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.network.IpAddress;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import org.apache.commons.net.util.SubnetUtils;
@@ -318,6 +319,11 @@ NetworkACLServiceProvider, FirewallServiceProvider, ResourceStateAdapter {
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
if (!canHandle(network, Service.Connectivity)) {
diff --git a/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
index daf9c1c4e08..510900cc105 100644
--- a/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
+++ b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
@@ -27,6 +27,7 @@ import java.util.UUID;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.network.IpAddress;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
import org.springframework.stereotype.Component;
@@ -194,6 +195,11 @@ public class BrocadeVcsElement extends AdapterBase implements NetworkElement, Re
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
if (!canHandle(network, Service.Connectivity)) {
diff --git a/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
index bea5a2c3f25..352eba4674d 100644
--- a/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
+++ b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
@@ -434,6 +434,11 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
private boolean cleanupLogicalEdgeFirewall(long vlanId, long hostId) {
CleanupLogicalEdgeFirewallCommand cmd = new CleanupLogicalEdgeFirewallCommand(vlanId);
Answer answer = _agentMgr.easySend(hostId, cmd);
diff --git a/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java b/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
index 0b96aa35150..04f092648c2 100644
--- a/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
+++ b/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
@@ -26,6 +26,7 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
@@ -86,6 +87,11 @@ public class DnsNotifier extends AdapterBase implements NetworkElement {
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return true;
diff --git a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
index c1ea7823811..f512a08dffd 100644
--- a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
+++ b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
@@ -24,6 +24,7 @@ import java.util.Set;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.network.IpAddress;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -136,6 +137,11 @@ public class ElasticLoadBalancerElement extends AdapterBase implements LoadBalan
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
// TODO kill all loadbalancer vms by calling the ElasticLoadBalancerManager
diff --git a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
index 09830d9a810..c83a913a61c 100644
--- a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
+++ b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
@@ -26,6 +26,7 @@ import java.util.Set;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.network.IpAddress;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.springframework.stereotype.Component;
@@ -175,6 +176,11 @@ public class GloboDnsElement extends AdapterBase implements ResourceStateAdapter
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return true;
diff --git a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
index 0a9b4a7131a..dc48d70f8a7 100644
--- a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
+++ b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
@@ -26,6 +26,7 @@ import java.util.Set;
import javax.inject.Inject;
+import com.cloud.network.IpAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -221,6 +222,11 @@ public class InternalLoadBalancerElement extends AdapterBase implements LoadBala
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return true;
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
List<? extends VirtualRouter> internalLbVms = _routerDao.listByNetworkAndRole(network.getId(), Role.INTERNAL_LB_VM);
diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
index 44cbc6c305f..fb832bf1d82 100644
--- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
+++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
@@ -244,6 +244,11 @@ public class ContrailElementImpl extends AdapterBase
return true;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return false;
+ }
+
/**
* Network disable
*/
diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
index 6da2e216ff8..da08ba2a6c2 100644
--- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
+++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
@@ -217,7 +217,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
ConfigurationManager configMgr = (ConfigurationManager) _configService;
NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText,
TrafficType.Public, null, true, Availability.Optional, null, serviceProviderMap, true,
- Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, null, null, null, true, null, null, false);
+ Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, false,null, null, null, true, null, null, false);
long id = voffer.getId();
_networkOfferingDao.update(id, voffer);
return _networkOfferingDao.findById(id);
@@ -252,7 +252,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
ConfigurationManager configMgr = (ConfigurationManager)_configService;
NetworkOfferingVO voffer =
configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true,
- Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, null, null, null, true, null, null, false);
+ Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, false,null, null, null, true, null, null, false);
if (offeringName.equals(vpcRouterOfferingName)) {
voffer.setInternalLb(true);
}
@@ -293,7 +293,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
}
serviceProviderMap.put(svc, providerSet);
}
- vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, false, null, null, null, VpcOffering.State.Enabled, null, false);
+ vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, null, null, null, null, VpcOffering.State.Enabled, null, false);
long id = vpcOffer.getId();
_vpcOffDao.update(id, (VpcOfferingVO)vpcOffer);
return _vpcOffDao.findById(id);
diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
index d5060443c9e..d492e6214ec 100644
--- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
+++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
@@ -201,4 +201,9 @@ public class ContrailVpcElementImpl extends ContrailElementImpl implements Netwo
public boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address) {
return true;
}
+
+ @Override
+ public boolean updateVpc(Vpc vpc, String previousVpcName) {
+ return true;
+ }
}
diff --git a/plugins/network-elements/netris/pom.xml b/plugins/network-elements/netris/pom.xml
new file mode 100644
index 00000000000..a50013ee351
--- /dev/null
+++ b/plugins/network-elements/netris/pom.xml
@@ -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.
+-->
+<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-netris</artifactId>
+ <name>Apache CloudStack Plugin - Netris</name>
+
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-plugins</artifactId>
+ <version>4.20.0.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>io.netris</groupId>
+ <artifactId>netris-java-sdk</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.seancfoley</groupId>
+ <artifactId>ipaddress</artifactId>
+ <version>5.5.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/StartupNetrisCommand.java
similarity index 76%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/StartupNetrisCommand.java
index d3fef252f50..04be93067a6 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/StartupNetrisCommand.java
@@ -14,10 +14,13 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack;
-import com.cloud.utils.db.GenericDao;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.host.Host;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public class StartupNetrisCommand extends StartupCommand {
+ public StartupNetrisCommand() {
+ super(Host.Type.L2Networking);
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/AddOrUpdateNetrisStaticRouteCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/AddOrUpdateNetrisStaticRouteCommand.java
new file mode 100644
index 00000000000..392016fc238
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/AddOrUpdateNetrisStaticRouteCommand.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.agent.api;
+
+public class AddOrUpdateNetrisStaticRouteCommand extends NetrisCommand {
+ private String prefix;
+ private String nextHop;
+ private Long routeId;
+ private boolean updateRoute;
+
+ public AddOrUpdateNetrisStaticRouteCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String prefix, String nextHop, Long routeId, boolean updateRoute) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.prefix = prefix;
+ this.nextHop = nextHop;
+ this.routeId = routeId;
+ this.updateRoute = updateRoute;
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public String getNextHop() {
+ return nextHop;
+ }
+
+ public Long getRouteId() {
+ return routeId;
+ }
+
+ public boolean isUpdateRoute() {
+ return updateRoute;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisACLCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisACLCommand.java
new file mode 100644
index 00000000000..ea39cd7f366
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisACLCommand.java
@@ -0,0 +1,120 @@
+// 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 org.apache.cloudstack.agent.api;
+
+import org.apache.cloudstack.resource.NetrisPortGroup;
+
+public class CreateNetrisACLCommand extends NetrisCommand {
+ private String vpcName;
+ private Long vpcId;
+ private String action;
+ private String destPrefix;
+ private String sourcePrefix;
+ private Integer destPortStart;
+ private Integer destPortEnd;
+ private Integer icmpType;
+ private String protocol;
+ private NetrisPortGroup portGroup;
+ private String netrisAclName;
+ private String reason;
+
+
+ public CreateNetrisACLCommand(long zoneId, Long accountId, Long domainId, String name, Long id, String vpcName, Long vpcId, boolean isVpc, String action,
+ String sourcePrefix, String destPrefix, Integer destPortStart, Integer destPortEnd, String protocol) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.vpcName = vpcName;
+ this.vpcId = vpcId;
+ this.action = action;
+ this.sourcePrefix = sourcePrefix;
+ this.destPrefix = destPrefix;
+ this.destPortStart = destPortStart;
+ this.destPortEnd = destPortEnd;
+ this.protocol = protocol;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public void setVpcName(String vpcName) {
+ this.vpcName = vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public void setVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public String getDestPrefix() {
+ return destPrefix;
+ }
+
+ public String getSourcePrefix() {
+ return sourcePrefix;
+ }
+
+ public Integer getDestPortStart() {
+ return destPortStart;
+ }
+
+ public Integer getDestPortEnd() {
+ return destPortEnd;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public NetrisPortGroup getPortGroup() {
+ return portGroup;
+ }
+
+ public void setPortGroup(NetrisPortGroup portGroup) {
+ this.portGroup = portGroup;
+ }
+
+ public Integer getIcmpType() {
+ return icmpType;
+ }
+
+ public void setIcmpType(Integer icmpType) {
+ this.icmpType = icmpType;
+ }
+
+ public String getNetrisAclName() {
+ return netrisAclName;
+ }
+
+ public void setNetrisAclName(String netrisAclName) {
+ this.netrisAclName = netrisAclName;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
new file mode 100644
index 00000000000..e6de0244e48
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVnetCommand.java
@@ -0,0 +1,85 @@
+// 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 org.apache.cloudstack.agent.api;
+
+public class CreateNetrisVnetCommand extends NetrisCommand {
+ private String vpcName;
+ private Long vpcId;
+ private String cidr;
+ private Integer vxlanId;
+ private String gateway;
+ private String netrisTag;
+ private String ipv6Cidr;
+ private Boolean globalRouting;
+
+ public CreateNetrisVnetCommand(Long zoneId, Long accountId, Long domainId, String vpcName, Long vpcId, String vNetName, Long networkId, String cidr, String gateway, boolean isVpc) {
+ super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
+ this.vpcId = vpcId;
+ this.vpcName = vpcName;
+ this.cidr = cidr;
+ this.gateway = gateway;
+ }
+
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public String getCidr() {
+ return cidr;
+ }
+
+ public Integer getVxlanId() {
+ return vxlanId;
+ }
+
+ public void setVxlanId(Integer vxlanId) {
+ this.vxlanId = vxlanId;
+ }
+
+ public String getGateway() {
+ return gateway;
+ }
+
+ public String getNetrisTag() {
+ return netrisTag;
+ }
+
+ public void setNetrisTag(String netrisTag) {
+ this.netrisTag = netrisTag;
+ }
+
+ public String getIpv6Cidr() {
+ return ipv6Cidr;
+ }
+
+ public void setIpv6Cidr(String ipv6Cidr) {
+ this.ipv6Cidr = ipv6Cidr;
+ }
+
+ public Boolean isGlobalRouting() {
+ return globalRouting;
+ }
+
+ public void setGlobalRouting(Boolean globalRouting) {
+ this.globalRouting = globalRouting;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVpcCommand.java
similarity index 65%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVpcCommand.java
index d3fef252f50..cff25f78287 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateNetrisVpcCommand.java
@@ -14,10 +14,18 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
+public class CreateNetrisVpcCommand extends NetrisCommand {
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ private final String cidr;
+
+ public CreateNetrisVpcCommand(long zoneId, long accountId, long domainId, String name, String cidr, long vpcId, boolean isVpc) {
+ super(zoneId, accountId, domainId, name, vpcId, isVpc);
+ this.cidr = cidr;
+ }
+
+ public String getCidr() {
+ return cidr;
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisACLCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisACLCommand.java
new file mode 100644
index 00000000000..00fc5bafb7e
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisACLCommand.java
@@ -0,0 +1,120 @@
+// 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 org.apache.cloudstack.agent.api;
+
+import org.apache.cloudstack.resource.NetrisPortGroup;
+
+public class CreateOrUpdateNetrisACLCommand extends NetrisCommand {
+ private String vpcName;
+ private Long vpcId;
+ private String action;
+ private String destPrefix;
+ private String sourcePrefix;
+ private Integer destPortStart;
+ private Integer destPortEnd;
+ private Integer icmpType;
+ private String protocol;
+ private NetrisPortGroup portGroup;
+ private String netrisAclName;
+ private String reason;
+
+
+ public CreateOrUpdateNetrisACLCommand(long zoneId, Long accountId, Long domainId, String name, Long id, String vpcName, Long vpcId, boolean isVpc, String action,
+ String sourcePrefix, String destPrefix, Integer destPortStart, Integer destPortEnd, String protocol) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.vpcName = vpcName;
+ this.vpcId = vpcId;
+ this.action = action;
+ this.sourcePrefix = sourcePrefix;
+ this.destPrefix = destPrefix;
+ this.destPortStart = destPortStart;
+ this.destPortEnd = destPortEnd;
+ this.protocol = protocol;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public void setVpcName(String vpcName) {
+ this.vpcName = vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public void setVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public String getDestPrefix() {
+ return destPrefix;
+ }
+
+ public String getSourcePrefix() {
+ return sourcePrefix;
+ }
+
+ public Integer getDestPortStart() {
+ return destPortStart;
+ }
+
+ public Integer getDestPortEnd() {
+ return destPortEnd;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public NetrisPortGroup getPortGroup() {
+ return portGroup;
+ }
+
+ public void setPortGroup(NetrisPortGroup portGroup) {
+ this.portGroup = portGroup;
+ }
+
+ public Integer getIcmpType() {
+ return icmpType;
+ }
+
+ public void setIcmpType(Integer icmpType) {
+ this.icmpType = icmpType;
+ }
+
+ public String getNetrisAclName() {
+ return netrisAclName;
+ }
+
+ public void setNetrisAclName(String netrisAclName) {
+ this.netrisAclName = netrisAclName;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisLoadBalancerRuleCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisLoadBalancerRuleCommand.java
new file mode 100644
index 00000000000..a2a080b33d9
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisLoadBalancerRuleCommand.java
@@ -0,0 +1,90 @@
+// 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 org.apache.cloudstack.agent.api;
+
+import com.cloud.network.netris.NetrisLbBackend;
+
+import java.util.List;
+
+public class CreateOrUpdateNetrisLoadBalancerRuleCommand extends NetrisCommand {
+ private final String publicPort;
+ private final String privatePort;
+ private final String algorithm;
+ private final String protocol;
+ List<NetrisLbBackend> lbBackends;
+ private String publicIp;
+ private final Long lbId;
+ private String cidrList;
+ private String ruleName;
+
+ public CreateOrUpdateNetrisLoadBalancerRuleCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc,
+ List<NetrisLbBackend> lbBackends, long lbId, String publicIp, String publicPort,
+ String privatePort, String algorithm, String protocol) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.lbId = lbId;
+ this.publicIp = publicIp;
+ this.publicPort = publicPort;
+ this.privatePort = privatePort;
+ this.algorithm = algorithm;
+ this.protocol = protocol;
+ this.lbBackends = lbBackends;
+ }
+
+ public String getPublicPort() {
+ return publicPort;
+ }
+
+ public String getPrivatePort() {
+ return privatePort;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public List<NetrisLbBackend> getLbBackends() {
+ return lbBackends;
+ }
+
+ public Long getLbId() {
+ return lbId;
+ }
+
+ public String getPublicIp() {
+ return publicIp;
+ }
+
+ public String getCidrList() {
+ return cidrList;
+ }
+
+ public void setCidrList(String cidrList) {
+ this.cidrList = cidrList;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public void setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisNatCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisNatCommand.java
new file mode 100644
index 00000000000..5e0546a8256
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisNatCommand.java
@@ -0,0 +1,149 @@
+// 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 org.apache.cloudstack.agent.api;
+
+public class CreateOrUpdateNetrisNatCommand extends NetrisCommand {
+ private String vpcName;
+ private Long vpcId;
+ private String vpcCidr;
+ private String natRuleName;
+ private String natIp;
+ private String natRuleType;
+
+ // Parameters for DNAT
+ private String protocol;
+ private String sourceAddress;
+ private String sourcePort;
+ private String destinationAddress;
+ private String destinationPort;
+ private String state;
+
+ // Parameters for SNAT (Static NAT)
+ private String vmIp;
+
+
+ public CreateOrUpdateNetrisNatCommand(long zoneId, Long accountId, Long domainId, String vpcName, Long vpcId, String vNetName, Long networkId, boolean isVpc, String vpcCidr) {
+ super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
+ this.vpcName = vpcName;
+ this.vpcId = vpcId;
+ this.vpcCidr = vpcCidr;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public String getNatIp() {
+ return natIp;
+ }
+
+ public void setNatRuleName(String natRuleName) {
+ this.natRuleName = natRuleName;
+ }
+
+ public String getNatRuleName() {
+ return natRuleName;
+ }
+
+ public String getVpcCidr() {
+ return vpcCidr;
+ }
+
+ public void setNatIp(String natIp) {
+ this.natIp = natIp;
+ }
+
+ public String getVmIp() {
+ return vmIp;
+ }
+
+ public void setVmIp(String vmIp) {
+ this.vmIp = vmIp;
+ }
+
+ public String getNatRuleType() {
+ return natRuleType;
+ }
+
+ public void setNatRuleType(String natRuleType) {
+ this.natRuleType = natRuleType;
+ }
+
+ public void setVpcName(String vpcName) {
+ this.vpcName = vpcName;
+ }
+
+ public void setVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+
+ public void setVpcCidr(String vpcCidr) {
+ this.vpcCidr = vpcCidr;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getSourceAddress() {
+ return sourceAddress;
+ }
+
+ public void setSourceAddress(String sourceAddress) {
+ this.sourceAddress = sourceAddress;
+ }
+
+ public String getSourcePort() {
+ return sourcePort;
+ }
+
+ public void setSourcePort(String sourcePort) {
+ this.sourcePort = sourcePort;
+ }
+
+ public String getDestinationAddress() {
+ return destinationAddress;
+ }
+
+ public void setDestinationAddress(String destinationAddress) {
+ this.destinationAddress = destinationAddress;
+ }
+
+ public String getDestinationPort() {
+ return destinationPort;
+ }
+
+ public void setDestinationPort(String destinationPort) {
+ this.destinationPort = destinationPort;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisACLCommand.java
similarity index 52%
copy from engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisACLCommand.java
index 06cfd25e670..e4a4993a257 100644
--- a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisACLCommand.java
@@ -14,27 +14,33 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.vpc.dao;
+package org.apache.cloudstack.agent.api;
import java.util.List;
-import com.cloud.network.Network.Service;
-import com.cloud.network.vpc.VpcOfferingServiceMapVO;
-import com.cloud.utils.db.GenericDao;
-
-public interface VpcOfferingServiceMapDao extends GenericDao<VpcOfferingServiceMapVO, Long> {
-
- List<VpcOfferingServiceMapVO> listByVpcOffId(long vpcOffId);
-
- /**
- * @param networkOfferingId
- * @param services
- * @return
- */
- boolean areServicesSupportedByVpcOffering(long vpcOfferingId, Service[] services);
-
- List<String> listServicesForVpcOffering(long vpcOfferingId);
-
- VpcOfferingServiceMapVO findByServiceProviderAndOfferingId(String service, String provider, long vpcOfferingId);
-
+public class DeleteNetrisACLCommand extends NetrisCommand {
+ Long vpcId;
+ String vpcName;
+ List<String> aclRuleNames;
+ public DeleteNetrisACLCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, Long vpcId, String vpcName) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.vpcId = vpcId;
+ this.vpcName = vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public List<String> getAclRuleNames() {
+ return aclRuleNames;
+ }
+
+ public void setAclRuleNames(List<String> aclRuleNames) {
+ this.aclRuleNames = aclRuleNames;
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisLoadBalancerRuleCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisLoadBalancerRuleCommand.java
new file mode 100644
index 00000000000..3ca32c8112c
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisLoadBalancerRuleCommand.java
@@ -0,0 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.agent.api;
+
+public class DeleteNetrisLoadBalancerRuleCommand extends NetrisCommand {
+ private Long lbId;
+ private String ruleName;
+ private String cidrList;
+
+ public DeleteNetrisLoadBalancerRuleCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, Long lbId) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.lbId = lbId;
+ }
+
+ public Long getLbId() {
+ return lbId;
+ }
+
+ public void setLbId(Long lbId) {
+ this.lbId = lbId;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public void setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ }
+
+ public String getCidrList() {
+ return cidrList;
+ }
+
+ public void setCidrList(String cidrList) {
+ this.cidrList = cidrList;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisNatRuleCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisNatRuleCommand.java
new file mode 100644
index 00000000000..b01b2f45192
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisNatRuleCommand.java
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.agent.api;
+
+public class DeleteNetrisNatRuleCommand extends NetrisCommand {
+
+ private String vpcName;
+ private Long vpcId;
+ private String natRuleType;
+ private String natRuleName;
+ private String natIp;
+
+ public DeleteNetrisNatRuleCommand(long zoneId, Long accountId, Long domainId, String vpcName, Long vpcId, String vNetName, Long networkId, boolean isVpc) {
+ super(zoneId, accountId, domainId, vNetName, networkId, isVpc);
+ this.vpcName = vpcName;
+ this.vpcId = vpcId;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public void setVpcName(String vpcName) {
+ this.vpcName = vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public void setVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+
+ public String getNatRuleType() {
+ return natRuleType;
+ }
+
+ public void setNatRuleType(String natRuleType) {
+ this.natRuleType = natRuleType;
+ }
+
+ public String getNatRuleName() {
+ return natRuleName;
+ }
+
+ public void setNatRuleName(String natRuleName) {
+ this.natRuleName = natRuleName;
+ }
+
+ public String getNatIp() {
+ return natIp;
+ }
+
+ public void setNatIp(String natIp) {
+ this.natIp = natIp;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisStaticRouteCommand.java
similarity index 66%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisStaticRouteCommand.java
index d3fef252f50..b531a049b0f 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisStaticRouteCommand.java
@@ -14,10 +14,10 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
-
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public class DeleteNetrisStaticRouteCommand extends AddOrUpdateNetrisStaticRouteCommand {
+ public DeleteNetrisStaticRouteCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String prefix, String nextHop, Long routeId) {
+ super(zoneId, accountId, domainId, name, id, isVpc, prefix, nextHop, routeId, false);
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVnetCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVnetCommand.java
new file mode 100644
index 00000000000..240c6c5417c
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVnetCommand.java
@@ -0,0 +1,51 @@
+// 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 org.apache.cloudstack.agent.api;
+
+public class DeleteNetrisVnetCommand extends NetrisCommand {
+ private String vpcName;
+ private Long vpcId;
+ private final String vNetCidr;
+ private String vNetV6Cidr;
+
+ public DeleteNetrisVnetCommand(long zoneId, long accountId, long domainId, String name, long id, String vpcName, Long vpcId, String vNetCidr, boolean isVpc) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.vpcName = vpcName;
+ this.vpcId = vpcId;
+ this.vNetCidr = vNetCidr;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public String getVNetCidr() {
+ return vNetCidr;
+ }
+
+ public String getvNetV6Cidr() {
+ return vNetV6Cidr;
+ }
+
+ public void setvNetV6Cidr(String vNetV6Cidr) {
+ this.vNetV6Cidr = vNetV6Cidr;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVpcCommand.java
similarity index 65%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVpcCommand.java
index d3fef252f50..d560f0b8cd9 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisVpcCommand.java
@@ -14,10 +14,17 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
+public class DeleteNetrisVpcCommand extends NetrisCommand {
+ private final String cidr;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ public DeleteNetrisVpcCommand(long zoneId, long accountId, long domainId, String name, String cidr, long vpcId, boolean isVpc) {
+ super(zoneId, accountId, domainId, name, vpcId, isVpc);
+ this.cidr = cidr;
+ }
+
+ public String getCidr() {
+ return cidr;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesAnswer.java
similarity index 61%
copy from api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesAnswer.java
index e99bc2fd416..421dc3359b6 100644
--- a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesAnswer.java
@@ -14,21 +14,23 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.element;
+package org.apache.cloudstack.agent.api;
+
+import com.cloud.agent.api.Command;
+import com.cloud.network.vpc.StaticRoute;
import java.util.List;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.rules.PortForwardingRule;
+public class ListNetrisStaticRoutesAnswer extends NetrisAnswer {
+
+ List<StaticRoute> staticRoutes;
+
+ public ListNetrisStaticRoutesAnswer(final Command command, final List<StaticRoute> staticRoutes) {
+ super(command, true, "OK");
+ this.staticRoutes = staticRoutes;
+ }
-public interface PortForwardingServiceProvider extends NetworkElement, IpDeployingRequester {
- /**
- * Apply rules
- * @param network
- * @param rules
- * @return
- * @throws ResourceUnavailableException
- */
- boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException;
+ public List<StaticRoute> getStaticRoutes() {
+ return staticRoutes;
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesCommand.java
similarity index 66%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesCommand.java
index d3fef252f50..e116a2386cb 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ListNetrisStaticRoutesCommand.java
@@ -14,10 +14,10 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
-
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public class ListNetrisStaticRoutesCommand extends AddOrUpdateNetrisStaticRouteCommand {
+ public ListNetrisStaticRoutesCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String prefix, String nextHop, Long routeId) {
+ super(zoneId, accountId, domainId, name, id, isVpc, prefix, nextHop, routeId, false);
+ }
}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisAnswer.java
similarity index 66%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisAnswer.java
index d3fef252f50..197500a3cce 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisAnswer.java
@@ -14,10 +14,17 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+public class NetrisAnswer extends Answer {
+ public NetrisAnswer(final Command command, final boolean success, final String details) {
+ super(command, success, details);
+ }
+
+ public NetrisAnswer(final Command command, final Exception e) {
+ super(command, e);
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisCommand.java
new file mode 100644
index 00000000000..ceb33ea24ed
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/NetrisCommand.java
@@ -0,0 +1,71 @@
+// 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 org.apache.cloudstack.agent.api;
+
+import com.cloud.agent.api.Command;
+
+public class NetrisCommand extends Command {
+ private final long zoneId;
+ private final Long accountId;
+ private final Long domainId;
+ private String name;
+ private final Long id;
+ private final boolean isVpc;
+
+ public NetrisCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc) {
+ this.zoneId = zoneId;
+ this.accountId = accountId;
+ this.domainId = domainId;
+ this.name = name;
+ this.id = id;
+ this.isVpc = isVpc;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ public Long getAccountId() {
+ return accountId;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public boolean isVpc() {
+ return isVpc;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
similarity index 66%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
index d3fef252f50..ac3a4faba4d 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
@@ -14,10 +14,17 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
+public class ReleaseNatIpCommand extends NetrisCommand {
+ private String natIp;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ public ReleaseNatIpCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, String natIp) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ this.natIp = natIp;
+ }
+
+ public String getNatIp() {
+ return natIp;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/SetupNetrisPublicRangeCommand.java
similarity index 59%
copy from api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/SetupNetrisPublicRangeCommand.java
index e99bc2fd416..5cbdd96e76a 100644
--- a/api/src/main/java/com/cloud/network/element/PortForwardingServiceProvider.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/SetupNetrisPublicRangeCommand.java
@@ -14,21 +14,24 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.element;
+package org.apache.cloudstack.agent.api;
-import java.util.List;
+public class SetupNetrisPublicRangeCommand extends NetrisCommand {
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.Network;
-import com.cloud.network.rules.PortForwardingRule;
+ private final String superCidr;
+ private final String exactCidr;
-public interface PortForwardingServiceProvider extends NetworkElement, IpDeployingRequester {
- /**
- * Apply rules
- * @param network
- * @param rules
- * @return
- * @throws ResourceUnavailableException
- */
- boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException;
+ public SetupNetrisPublicRangeCommand(long zoneId, String superCidr, String exactCidr) {
+ super(zoneId, null, null, null, zoneId, false);
+ this.superCidr = superCidr;
+ this.exactCidr = exactCidr;
+ }
+
+ public String getSuperCidr() {
+ return superCidr;
+ }
+
+ public String getExactCidr() {
+ return exactCidr;
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVnetCommand.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVnetCommand.java
new file mode 100644
index 00000000000..99a266e15ad
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVnetCommand.java
@@ -0,0 +1,51 @@
+// 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 org.apache.cloudstack.agent.api;
+
+public class UpdateNetrisVnetCommand extends NetrisCommand{
+ private String prevNetworkName;
+ private String vpcName;
+ private Long vpcId;
+
+ public UpdateNetrisVnetCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ }
+
+ public String getPrevNetworkName() {
+ return prevNetworkName;
+ }
+
+ public void setPrevNetworkName(String prevNetworkName) {
+ this.prevNetworkName = prevNetworkName;
+ }
+
+ public String getVpcName() {
+ return vpcName;
+ }
+
+ public void setVpcName(String vpcName) {
+ this.vpcName = vpcName;
+ }
+
+ public Long getVpcId() {
+ return vpcId;
+ }
+
+ public void setVpcId(Long vpcId) {
+ this.vpcId = vpcId;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVpcCommand.java
similarity index 60%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVpcCommand.java
index d3fef252f50..764d9155a02 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/UpdateNetrisVpcCommand.java
@@ -14,10 +14,19 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.agent.api;
-import com.cloud.utils.db.GenericDao;
+public class UpdateNetrisVpcCommand extends NetrisCommand {
+ private String previousVpcName;
+ public UpdateNetrisVpcCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc) {
+ super(zoneId, accountId, domainId, name, id, isVpc);
+ }
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ public String getPreviousVpcName() {
+ return previousVpcName;
+ }
+
+ public void setPreviousVpcName(String previousVpcName) {
+ this.previousVpcName = previousVpcName;
+ }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/AddNetrisProviderCmd.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/AddNetrisProviderCmd.java
new file mode 100644
index 00000000000..a7ac3843020
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/AddNetrisProviderCmd.java
@@ -0,0 +1,123 @@
+// 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 org.apache.cloudstack.api.command;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.network.netris.NetrisProvider;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetrisProviderResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.service.NetrisProviderService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+
+@APICommand(name = AddNetrisProviderCmd.APINAME, description = "Add Netris Provider to CloudStack",
+ responseObject = NetrisProviderResponse.class, requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false, since = "4.20")
+public class AddNetrisProviderCmd extends BaseCmd {
+ public static final String APINAME = "addNetrisProvider";
+ public static final Logger LOGGER = LoggerFactory.getLogger(AddNetrisProviderCmd.class.getName());
+
+ @Inject
+ NetrisProviderService netrisProviderService;
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true,
+ description = "the ID of zone")
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Netris provider name")
+ private String name;
+
+ @Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "Netris provider URL")
+ private String url;
+
+ @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Username to log into Netris")
+ private String username;
+
+ @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Password to login into Netris")
+ private String password;
+
+ @Parameter(name = ApiConstants.SITE_NAME, type = CommandType.STRING, required = true, description = "Netris Site name")
+ private String siteName;
+
+ @Parameter(name = ApiConstants.TENANT_NAME, type = CommandType.STRING, required = true, description = "Password to login into Netris")
+ private String tenantName;
+
+ @Parameter(name = ApiConstants.NETRIS_TAG, type = CommandType.STRING, required = true, description = "Netris tag for vNets")
+ private String netrisTag;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getSiteName() {
+ return siteName;
+ }
+
+ public String getTenantName() {
+ return tenantName;
+ }
+
+ public String getNetrisTag() {
+ return netrisTag;
+ }
+
+ @Override
+ public void execute() throws ServerApiException, ConcurrentOperationException {
+ NetrisProvider provider = netrisProviderService.addProvider(this);
+ NetrisProviderResponse response = netrisProviderService.createNetrisProviderResponse(provider);
+ if (response == null)
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Netris provider");
+ else {
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/command/DeleteNsxControllerCmd.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/DeleteNetrisProviderCmd.java
similarity index 70%
copy from plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/command/DeleteNsxControllerCmd.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/DeleteNetrisProviderCmd.java
index 5a3e5586400..27e29071c45 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/command/DeleteNsxControllerCmd.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/DeleteNetrisProviderCmd.java
@@ -16,62 +16,59 @@
// under the License.
package org.apache.cloudstack.api.command;
-import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.response.NsxControllerResponse;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetrisProviderResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
-import org.apache.cloudstack.service.NsxProviderService;
+import org.apache.cloudstack.service.NetrisProviderService;
import javax.inject.Inject;
-import static org.apache.cloudstack.api.command.DeleteNsxControllerCmd.APINAME;
+import static org.apache.cloudstack.api.command.DeleteNetrisProviderCmd.APINAME;
-@APICommand(name = APINAME, description = "delete NSX Controller to CloudStack",
- responseObject = NsxControllerResponse.class, requestHasSensitiveInfo = false,
- responseHasSensitiveInfo = false, since = "4.19.0")
-public class DeleteNsxControllerCmd extends BaseCmd {
- public static final String APINAME = "deleteNsxController";
+@APICommand(name = APINAME, description = "delete Netris Provider to CloudStack",
+ responseObject = NetrisProviderResponse.class, requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false, since = "4.20.0")
+public class DeleteNetrisProviderCmd extends BaseCmd {
+ public static final String APINAME = "deleteNetrisProvider";
@Inject
- protected NsxProviderService nsxProviderService;
-/////////////////////////////////////////////////////
+ private NetrisProviderService netrisProviderService;
+
+ /////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
-
- @Parameter(name = ApiConstants.NSX_CONTROLLER_ID, type = CommandType.UUID, entityType = NsxControllerResponse.class,
- required = true, description = "NSX Controller ID")
- private Long nsxControllerId;
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = NetrisProviderResponse.class,
+ required = true, description = "Netris Provider ID")
+ private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
- public Long getNsxControllerId() {
- return nsxControllerId;
- }
+ public Long getId() { return id; }
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
-
@Override
public void execute() throws ServerApiException, ConcurrentOperationException {
try {
- boolean deleted = nsxProviderService.deleteNsxController(getNsxControllerId());
+ boolean deleted = netrisProviderService.deleteNetrisProvider(getId());
if (deleted) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
- throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NSX Controller from Zone");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to Netris provider from zone");
}
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/ListNetrisProvidersCmd.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/ListNetrisProvidersCmd.java
new file mode 100644
index 00000000000..ed3d64e867a
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/command/ListNetrisProvidersCmd.java
@@ -0,0 +1,73 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.utils.StringUtils;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.NetrisProviderResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.service.NetrisProviderService;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListNetrisProvidersCmd.APINAME, description = "list all Netris providers added to CloudStack",
+ responseObject = NetrisProviderResponse.class, requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false, since = "4.20.0")
+public class ListNetrisProvidersCmd extends BaseListCmd {
+ public static final String APINAME = "listNetrisProviders";
+
+ @Inject
+ NetrisProviderService netrisProviderService;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ ///
+ @Parameter(name = ApiConstants.ZONE_ID, description = "Netris provider added to the specific zone",
+ type = CommandType.UUID, entityType = ZoneResponse.class)
+ Long zoneId;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() throws ServerApiException, ConcurrentOperationException {
+ List<BaseResponse> baseResponseList = netrisProviderService.listNetrisProviders(zoneId);
+ List<BaseResponse> pagingList = StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
+ ListResponse<BaseResponse> listResponse = new ListResponse<>();
+ listResponse.setResponses(pagingList);
+ listResponse.setResponseName(getCommandName());
+ setResponseObject(listResponse);
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/response/NetrisProviderResponse.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/response/NetrisProviderResponse.java
new file mode 100644
index 00000000000..d130c3a7372
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/api/response/NetrisProviderResponse.java
@@ -0,0 +1,135 @@
+// 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 org.apache.cloudstack.api.response;
+
+import com.cloud.network.netris.NetrisProvider;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+@EntityReference(value = {NetrisProvider.class})
+public class NetrisProviderResponse extends BaseResponse {
+ @SerializedName(ApiConstants.NAME)
+ @Param(description = "Netris Provider name")
+ private String name;
+
+ @SerializedName(ApiConstants.UUID)
+ @Param(description = "Netris provider uuid")
+ private String uuid;
+
+ @SerializedName(ApiConstants.ZONE_ID)
+ @Param(description = "Zone ID to which the Netris Provider is associated with")
+ private String zoneId;
+
+ @SerializedName(ApiConstants.ZONE_NAME)
+ @Param(description = "Zone name to which the Netris Provider is associated with")
+ private String zoneName;
+
+ @SerializedName(ApiConstants.HOST_NAME)
+ @Param(description = "Netris Provider hostname or IP address")
+ private String hostname;
+
+ @SerializedName(ApiConstants.PORT)
+ @Param(description = "Netris Provider port")
+ private String port;
+
+ @SerializedName(ApiConstants.SITE_NAME)
+ @Param(description = "Netris Provider site")
+ private String siteName;
+
+ @SerializedName(ApiConstants.TENANT_NAME)
+ @Param(description = "Netris Admin tenant name")
+ private String tenantName;
+
+ @SerializedName(ApiConstants.NETRIS_TAG)
+ @Param(description = "Netris Tag for vNets")
+ private String netrisTag;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getZoneId() {
+ return zoneId;
+ }
+
+ public void setZoneId(String zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ public String getZoneName() {
+ return zoneName;
+ }
+
+ public void setZoneName(String zoneName) {
+ this.zoneName = zoneName;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public String getSiteName() {
+ return siteName;
+ }
+
+ public void setSiteName(String siteName) {
+ this.siteName = siteName;
+ }
+
+ public String getTenantName() {
+ return tenantName;
+ }
+
+ public void setTenantName(String tenantName) {
+ this.tenantName = tenantName;
+ }
+
+ public String getNetrisTag() {
+ return netrisTag;
+ }
+
+ public void setNetrisTag(String netrisTag) {
+ this.netrisTag = netrisTag;
+ }
+}
diff --git a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisPortGroup.java
similarity index 78%
copy from engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisPortGroup.java
index d3fef252f50..13c4c90cf3f 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/Site2SiteVpnGatewayDao.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisPortGroup.java
@@ -14,10 +14,14 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-package com.cloud.network.dao;
+package org.apache.cloudstack.resource;
-import com.cloud.utils.db.GenericDao;
+public class NetrisPortGroup {
+ private String ports;
-public interface Site2SiteVpnGatewayDao extends GenericDao<Site2SiteVpnGatewayVO, Long> {
- Site2SiteVpnGatewayVO findByVpcId(long vpcId);
+ public NetrisPortGroup(String ports) {
+ this.ports = ports;
+ }
+
+ public String getPorts() { return ports; }
}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
new file mode 100644
index 00000000000..4aef6d2d80a
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
@@ -0,0 +1,441 @@
+// 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 org.apache.cloudstack.resource;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.host.Host;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
+import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisACLCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.ListNetrisStaticRoutesAnswer;
+import org.apache.cloudstack.agent.api.ListNetrisStaticRoutesCommand;
+import org.apache.cloudstack.agent.api.NetrisAnswer;
+import org.apache.cloudstack.StartupNetrisCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
+import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVpcCommand;
+import org.apache.cloudstack.service.NetrisApiClient;
+import org.apache.cloudstack.service.NetrisApiClientImpl;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.naming.ConfigurationException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class NetrisResource implements ServerResource {
+ protected Logger logger = LogManager.getLogger(getClass());
+
+ private String name;
+ protected String endpointUrl;
+ protected String username;
+ protected String password;
+ protected String guid;
+ protected String zoneId;
+ protected String siteName;
+ protected String adminTenantName;
+
+ protected NetrisApiClient netrisApiClient;
+
+ @Override
+ public Host.Type getType() {
+ return Host.Type.Routing;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupNetrisCommand sc = new StartupNetrisCommand();
+ sc.setGuid(guid);
+ sc.setName(name);
+ sc.setDataCenter(zoneId);
+ sc.setPod("");
+ sc.setPrivateIpAddress("");
+ sc.setStorageIpAddress("");
+ sc.setVersion("");
+ return new StartupCommand[] {sc};
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ return null;
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof ReadyCommand) {
+ return executeRequest((ReadyCommand) cmd);
+ } else if (cmd instanceof CheckHealthCommand) {
+ return executeRequest((CheckHealthCommand) cmd);
+ } else if (cmd instanceof CreateNetrisVpcCommand) {
+ return executeRequest((CreateNetrisVpcCommand) cmd);
+ } else if (cmd instanceof UpdateNetrisVpcCommand) {
+ return executeRequest((UpdateNetrisVpcCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisVpcCommand) {
+ return executeRequest((DeleteNetrisVpcCommand) cmd);
+ } else if (cmd instanceof CreateNetrisVnetCommand) {
+ return executeRequest((CreateNetrisVnetCommand) cmd);
+ } else if (cmd instanceof UpdateNetrisVnetCommand) {
+ return executeRequest((UpdateNetrisVnetCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisVnetCommand) {
+ return executeRequest((DeleteNetrisVnetCommand) cmd);
+ } else if (cmd instanceof SetupNetrisPublicRangeCommand) {
+ return executeRequest((SetupNetrisPublicRangeCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisNatRuleCommand) {
+ return executeRequest((DeleteNetrisNatRuleCommand) cmd);
+ } else if (cmd instanceof CreateOrUpdateNetrisNatCommand) {
+ return executeRequest((CreateOrUpdateNetrisNatCommand) cmd);
+ } else if (cmd instanceof CreateOrUpdateNetrisACLCommand) {
+ return executeRequest((CreateOrUpdateNetrisACLCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisACLCommand) {
+ return executeRequest((DeleteNetrisACLCommand) cmd);
+ } else if (cmd instanceof ListNetrisStaticRoutesCommand) {
+ return executeRequest((ListNetrisStaticRoutesCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisStaticRouteCommand) {
+ return executeRequest((DeleteNetrisStaticRouteCommand) cmd);
+ } else if (cmd instanceof AddOrUpdateNetrisStaticRouteCommand) {
+ return executeRequest((AddOrUpdateNetrisStaticRouteCommand) cmd);
+ } else if (cmd instanceof ReleaseNatIpCommand) {
+ return executeRequest((ReleaseNatIpCommand) cmd);
+ } else if (cmd instanceof CreateOrUpdateNetrisLoadBalancerRuleCommand) {
+ return executeRequest((CreateOrUpdateNetrisLoadBalancerRuleCommand) cmd);
+ } else if (cmd instanceof DeleteNetrisLoadBalancerRuleCommand) {
+ return executeRequest((DeleteNetrisLoadBalancerRuleCommand) cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ @Override
+ public void disconnected() {
+ // Do nothing
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ return null;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ // Do nothing
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void setConfigParams(Map<String, Object> params) {
+ // Do nothing
+ }
+
+ @Override
+ public Map<String, Object> getConfigParams() {
+ return new HashMap<>();
+ }
+
+ @Override
+ public int getRunLevel() {
+ return 0;
+ }
+
+ @Override
+ public void setRunLevel(int level) {
+
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ endpointUrl = (String) params.get("url");
+ if (endpointUrl == null) {
+ throw new ConfigurationException("Missing Netris provider URL from params: " + params);
+ }
+
+ username = (String) params.get("username");
+ if (username == null) {
+ throw new ConfigurationException("Missing Netris username from params: " + params);
+ }
+
+ password = (String) params.get("password");
+ if (password == null) {
+ throw new ConfigurationException("Missing Netris password from params: " + params);
+ }
+
+ this.name = (String) params.get("name");
+ if (this.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");
+ }
+
+ siteName = (String) params.get("siteName");
+ if (siteName == null) {
+ throw new ConfigurationException("Unable to find the Netris site name");
+ }
+
+ adminTenantName = (String) params.get("tenantName");
+ if (adminTenantName == null) {
+ throw new ConfigurationException("Unable to find the Netris admin tenant name");
+ }
+
+ netrisApiClient = new NetrisApiClientImpl(endpointUrl, username, password, siteName, adminTenantName);
+ return netrisApiClient.isSessionAlive();
+ }
+
+ private Answer executeRequest(ReadyCommand cmd) {
+ return new ReadyAnswer(cmd);
+ }
+
+ private Answer executeRequest(CheckHealthCommand cmd) {
+ return new CheckHealthAnswer(cmd, netrisApiClient.isSessionAlive());
+ }
+
+ private Answer executeRequest(CreateNetrisVpcCommand cmd) {
+ try {
+ boolean result = netrisApiClient.createVpc(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris VPC %s creation failed", cmd.getName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ } catch (CloudRuntimeException e) {
+ String msg = String.format("Error creating Netris VPC: %s", e.getMessage());
+ logger.error(msg, e);
+ return new NetrisAnswer(cmd, new CloudRuntimeException(msg));
+ }
+ }
+
+ private Answer executeRequest(UpdateNetrisVpcCommand cmd) {
+ try {
+ boolean result = netrisApiClient.updateVpc(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris VPC %s creation failed", cmd.getName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ } catch (CloudRuntimeException e) {
+ String msg = String.format("Error creating Netris VPC: %s", e.getMessage());
+ logger.error(msg, e);
+ return new NetrisAnswer(cmd, new CloudRuntimeException(msg));
+ }
+ }
+
+ private Answer executeRequest(CreateNetrisVnetCommand cmd) {
+ try {
+ String vpcName = cmd.getVpcName();
+ boolean result = netrisApiClient.createVnet(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris VPC %s creation failed", vpcName));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ } catch (CloudRuntimeException e) {
+ String msg = String.format("Error creating Netris VPC: %s", e.getMessage());
+ logger.error(msg, e);
+ return new NetrisAnswer(cmd, new CloudRuntimeException(msg));
+ }
+ }
+
+ private Answer executeRequest(UpdateNetrisVnetCommand cmd) {
+ try {
+ String networkName = cmd.getName();
+ String prevNetworkName = cmd.getPrevNetworkName();
+ boolean result = netrisApiClient.updateVnet(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to update network name from %s to %s", prevNetworkName, networkName));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ } catch (CloudRuntimeException e) {
+ String msg = String.format("Error updating Netris vNet: %s", e.getMessage());
+ logger.error(msg, e);
+ return new NetrisAnswer(cmd, new CloudRuntimeException(msg));
+ }
+ }
+
+ private Answer executeRequest(DeleteNetrisVnetCommand cmd) {
+ try {
+ String networkName = cmd.getName();
+ boolean result = netrisApiClient.deleteVnet(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris vNet: %s deletion failed", networkName));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ } catch (CloudRuntimeException e) {
+ String msg = String.format("Error deleting Netris vNet: %s", e.getMessage());
+ logger.error(msg, e);
+ return new NetrisAnswer(cmd, new CloudRuntimeException(msg));
+ }
+ }
+
+ private Answer executeRequest(DeleteNetrisVpcCommand cmd) {
+ boolean result = netrisApiClient.deleteVpc(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris VPC %s deletion failed", cmd.getName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(SetupNetrisPublicRangeCommand cmd) {
+ boolean result = netrisApiClient.setupZoneLevelPublicRange(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, "Netris Setup for Public Range failed");
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(CreateOrUpdateNetrisNatCommand cmd) {
+ String natRuleType = cmd.getNatRuleType();
+ if ("SNAT".equals(natRuleType)) {
+ boolean result = netrisApiClient.createOrUpdateSNATRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to create SNAT rule on Netris for network %s", cmd.getName()));
+ }
+ } else if ("DNAT".equals(natRuleType)) {
+ boolean result = netrisApiClient.createOrUpdateDNATRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to create DNAT rule on Netris for network %s", cmd.getName()));
+ }
+ } else if ("STATICNAT".equals(natRuleType)) {
+ boolean result = netrisApiClient.createStaticNatRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to create SNAT rule on Netris for network %s", cmd.getName()));
+ }
+ }
+
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(DeleteNetrisNatRuleCommand cmd) {
+ boolean result = netrisApiClient.deleteNatRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Netris NAT rule: %s deletion failed", cmd.getNatRuleName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(CreateOrUpdateNetrisACLCommand cmd) {
+ boolean result = netrisApiClient.addOrUpdateAclRule(cmd, false);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Creation of Netris ACL rule: %s failed", cmd.getNetrisAclName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(DeleteNetrisACLCommand cmd) {
+ boolean result = netrisApiClient.deleteAclRule(cmd, false);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to delete Netris ACLs: %s", String.join("'", cmd.getAclRuleNames())));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(ListNetrisStaticRoutesCommand cmd) {
+ List<StaticRoute> staticRoutes = netrisApiClient.listStaticRoutes(cmd);
+ return new ListNetrisStaticRoutesAnswer(cmd, staticRoutes);
+ }
+
+ private Answer executeRequest(AddOrUpdateNetrisStaticRouteCommand cmd) {
+ boolean result = netrisApiClient.addOrUpdateStaticRoute(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to add static route for VPC: %s, prefix: %s, nextHop: %s ", cmd.getName(), cmd.getPrefix(), cmd.getNextHop()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(DeleteNetrisStaticRouteCommand cmd) {
+ boolean result = netrisApiClient.deleteStaticRoute(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to add static route for VPC: %s, prefix: %s, nextHop: %s ", cmd.getName(), cmd.getPrefix(), cmd.getNextHop()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(ReleaseNatIpCommand cmd) {
+ boolean result = netrisApiClient.releaseNatIp(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to release NAT IP: %s", cmd.getNatIp()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd) {
+ boolean result = netrisApiClient.createOrUpdateLbRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to create Netris LB rule for %s: %s, " +
+ "for private port: %s and public port: %s", getNetworkType(cmd.isVpc()), cmd.getName(), cmd.getPrivatePort(), cmd.getPublicPort()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private Answer executeRequest(DeleteNetrisLoadBalancerRuleCommand cmd) {
+ boolean result = netrisApiClient.deleteLbRule(cmd);
+ if (!result) {
+ return new NetrisAnswer(cmd, false, String.format("Failed to delete Netris LB rule for %s: %s", getNetworkType(cmd.isVpc()), cmd.getName()));
+ }
+ return new NetrisAnswer(cmd, true, "OK");
+ }
+
+ private String getNetworkType(Boolean isVpc) {
+ if (isVpc) {
+ return "VPC";
+ }
+ return "Network";
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java
new file mode 100644
index 00000000000..164c56cd763
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResourceObjectUtils.java
@@ -0,0 +1,103 @@
+// 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 org.apache.cloudstack.resource;
+
+import org.apache.cloudstack.agent.api.NetrisCommand;
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.util.Objects;
+
+public class NetrisResourceObjectUtils {
+
+ public enum NetrisObjectType {
+ VPC, IPAM_ALLOCATION, IPAM_SUBNET, VNET, SNAT, STATICNAT, DNAT, STATICROUTE, ACL, LB
+ }
+
+ public static String retrieveNetrisResourceObjectName(NetrisCommand cmd, NetrisObjectType netrisObjectType, String... suffixes) {
+ long zoneId = cmd.getZoneId();
+ Long accountId = cmd.getAccountId();
+ Long domainId = cmd.getDomainId();
+ Long objectId = cmd.getId();
+ String objectName = cmd.getName();
+ boolean isVpc = cmd.isVpc();
+ boolean isZoneLevel = accountId == null && domainId == null;
+
+ StringBuilder stringBuilder = new StringBuilder();
+ if (isZoneLevel) {
+ stringBuilder.append(String.format("Z%s", zoneId));
+ } else {
+ stringBuilder.append(String.format("D%s-A%s-Z%s", domainId, accountId, zoneId));
+ }
+ String prefix = isVpc ? "-V" : "-N";
+ switch (netrisObjectType) {
+ case VPC:
+ if (ArrayUtils.isEmpty(suffixes)) {
+ stringBuilder.append(String.format("%s%s-%s", prefix, objectId, objectName));
+ } else {
+ stringBuilder.append(String.format("%s%s", prefix, suffixes[0]));
+ suffixes = new String[0];
+ }
+ break;
+ case IPAM_ALLOCATION:
+ if (!isZoneLevel) {
+ stringBuilder.append(String.format("%s%s", prefix, objectId));
+ }
+ break;
+ case IPAM_SUBNET:
+ if (!isZoneLevel) {
+ if (Objects.nonNull(objectId) && Objects.nonNull(objectName) && !isVpc) {
+ stringBuilder.append(String.format("-N%s", objectId));
+ } else {
+ stringBuilder.append(String.format("-V%s-%s", suffixes[0], suffixes[1]));
+ return stringBuilder.toString();
+ }
+ }
+ break;
+ case SNAT:
+ stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "SNAT"));
+ suffixes = new String[0];
+ break;
+ case STATICNAT:
+ stringBuilder.append(String.format("%s%s-VM%s-%s", prefix, suffixes[0], suffixes[1], "STATICNAT"));
+ suffixes = new String[0];
+ break;
+ case DNAT:
+ stringBuilder.append(String.format("%s%s-%s", prefix, suffixes[0], "DNAT"));
+ suffixes = ArrayUtils.subarray(suffixes, 1, suffixes.length);
+ break;
+ case STATICROUTE:
+ stringBuilder.append(String.format("%s%s-%s%s", prefix, suffixes[0], "ROUTE", suffixes[1]));
+ suffixes = new String[0];
+ break;
+ case VNET:
+ case ACL:
+ break;
+ case LB:
+ stringBuilder.append(String.format("%s%s", prefix, objectId));
+ break;
+ default:
+ stringBuilder.append(String.format("-%s", objectName));
+ break;
+ }
+ if (ArrayUtils.isNotEmpty(suffixes)) {
+ for (String suffix : suffixes) {
+ stringBuilder.append(String.format("-%s", suffix));
+ }
+ }
+ return stringBuilder.toString();
+ }
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
new file mode 100644
index 00000000000..4261c6dc961
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
@@ -0,0 +1,100 @@
+// 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 org.apache.cloudstack.service;
+
+import com.cloud.network.vpc.StaticRoute;
+import io.netris.ApiException;
+import io.netris.model.GetSiteBody;
+import io.netris.model.VPCListing;
+import io.netris.model.response.TenantResponse;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
+import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisACLCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.ListNetrisStaticRoutesCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
+import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVpcCommand;
+
+import java.util.List;
+
+public interface NetrisApiClient {
+ boolean isSessionAlive();
+ List<GetSiteBody> listSites();
+ List<VPCListing> listVPCs();
+ List<TenantResponse> listTenants() throws ApiException;
+
+ /**
+ * Create a VPC on CloudStack creates the following Netris resources:
+ * - Create a Netris VPC with the VPC name
+ * - Create an IPAM Allocation for the created Netris VPC using the Prefix = VPC CIDR
+ */
+ boolean createVpc(CreateNetrisVpcCommand cmd);
+
+ boolean updateVpc(UpdateNetrisVpcCommand cmd);
+
+ /**
+ * Delete a VPC on CloudStack removes the following Netris resources:
+ * - Delete the IPAM Allocation for the VPC using the Prefix = VPC CIDR
+ * - Delete a Netris VPC with the VPC name
+ */
+ boolean deleteVpc(DeleteNetrisVpcCommand cmd);
+
+ /**
+ * Creation of a VPC network tier creates the following Netris resources:
+ * - Creates a Netris IPAM Subnet for the specified network tier's CIDR
+ * - Creates a Netris vNet
+ */
+ boolean createVnet(CreateNetrisVnetCommand cmd);
+
+ boolean updateVnet(UpdateNetrisVnetCommand cmd);
+
+ /**
+ * Deletion of a VPC network tier deletes the following Netris resources:
+ * - Deletes the Netris IPAM Subnet for the specified network tier's CIDR
+ * - Deletes the Netris vNet
+ */
+ boolean deleteVnet(DeleteNetrisVnetCommand cmd);
+
+ /**
+ * Check and create zone level Netris Public range in the following manner:
+ * - Check the IPAM allocation for the zone super CIDR. In case it doesn't exist, create it
+ * - Check the IPAM subnet for NAT purpose for the range start-end. In case it doesn't exist, create it
+ */
+ boolean setupZoneLevelPublicRange(SetupNetrisPublicRangeCommand cmd);
+ boolean createOrUpdateSNATRule(CreateOrUpdateNetrisNatCommand cmd);
+ boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd);
+ boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd);
+ boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
+ boolean addOrUpdateAclRule(CreateOrUpdateNetrisACLCommand cmd, boolean forLb);
+ boolean deleteAclRule(DeleteNetrisACLCommand cmd, boolean forLb);
+ boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd);
+ boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd);
+ List<StaticRoute> listStaticRoutes(ListNetrisStaticRoutesCommand cmd);
+ boolean releaseNatIp(ReleaseNatIpCommand cmd);
+ boolean createOrUpdateLbRule(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd);
+ boolean deleteLbRule(DeleteNetrisLoadBalancerRuleCommand cmd);
+}
diff --git a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
new file mode 100644
index 00000000000..d9f7678d964
--- /dev/null
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
@@ -0,0 +1,2004 @@
+// 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 org.apache.cloudstack.service;
+
+import com.cloud.domain.Domain;
+import com.cloud.network.netris.NetrisLbBackend;
+import com.cloud.network.netris.NetrisNetworkRule;
+import com.cloud.network.vpc.StaticRoute;
+import com.cloud.network.vpc.StaticRouteVO;
+import com.cloud.user.Account;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import inet.ipaddr.IPAddress;
+import inet.ipaddr.IPAddressString;
+import io.netris.ApiClient;
+import io.netris.ApiException;
+import io.netris.ApiResponse;
+import io.netris.api.v1.AclApi;
+import io.netris.api.v1.AuthenticationApi;
+import io.netris.api.v1.RoutesApi;
+import io.netris.api.v1.SitesApi;
+import io.netris.api.v1.TenantsApi;
+import io.netris.api.v2.IpamApi;
+import io.netris.api.v2.L4LoadBalancerApi;
+import io.netris.api.v2.NatApi;
+import io.netris.api.v2.VNetApi;
+import io.netris.api.v2.VpcApi;
+import io.netris.model.AclAddItem;
+import io.netris.model.AclBodyVpc;
+import io.netris.model.AclDeleteItem;
+import io.netris.model.AclEditItem;
+import io.netris.model.AclGetBody;
+import io.netris.model.AclResponseGetOk;
+import io.netris.model.AllocationBody;
+import io.netris.model.AllocationBodyVpc;
+import io.netris.model.FilterBySites;
+import io.netris.model.FilterByVpc;
+import io.netris.model.GetSiteBody;
+
+import io.netris.model.InlineResponse20015;
+import io.netris.model.InlineResponse20016;
+import io.netris.model.InlineResponse2003;
+import io.netris.model.InlineResponse2004;
+import io.netris.model.InlineResponse2004Data;
+import io.netris.model.IpTree;
+import io.netris.model.IpTreeAllocation;
+import io.netris.model.IpTreeAllocationTenant;
+import io.netris.model.IpTreeSubnet;
+import io.netris.model.IpTreeSubnetSites;
+import io.netris.model.L4LBSite;
+import io.netris.model.L4LbAddItem;
+import io.netris.model.L4LbEditItem;
+import io.netris.model.L4LbTenant;
+import io.netris.model.L4LbVpc;
+import io.netris.model.L4LoadBalancerBackendItem;
+import io.netris.model.L4LoadBalancerItem;
+import io.netris.model.L4lbAddOrUpdateItem;
+import io.netris.model.L4lbresBody;
+import io.netris.model.NatBodySiteSite;
+import io.netris.model.NatBodyVpcVpc;
+import io.netris.model.NatGetBody;
+import io.netris.model.NatPostBody;
+import io.netris.model.NatPutBody;
+import io.netris.model.NatResponseGetOk;
+import io.netris.model.ResAddEditBody;
+import io.netris.model.RoutesBody;
+import io.netris.model.RoutesBodyId;
+import io.netris.model.RoutesBodyVpcVpc;
+import io.netris.model.RoutesGetBody;
+import io.netris.model.RoutesPostBody;
+import io.netris.model.RoutesPutBody;
+import io.netris.model.RoutesResponseGetOk;
+import io.netris.model.SitesResponseOK;
+import io.netris.model.SubnetBody;
+import io.netris.model.SubnetResBody;
+import io.netris.model.VPCAdminTenant;
+import io.netris.model.VPCCreate;
+import io.netris.model.VPCListing;
+import io.netris.model.VPCResource;
+import io.netris.model.VPCResourceIpam;
+import io.netris.model.VPCResponseOK;
+import io.netris.model.VPCResponseObjectOK;
+import io.netris.model.VPCResponseResourceOK;
+import io.netris.model.VnetAddBody;
+import io.netris.model.VnetAddBodyDhcp;
+import io.netris.model.VnetAddBodyDhcpOptionSet;
+import io.netris.model.VnetAddBodyGateways;
+import io.netris.model.VnetAddBodyVpc;
+import io.netris.model.VnetEditBody;
+import io.netris.model.VnetEditBodyDhcp;
+import io.netris.model.VnetEditBodyGateways;
+import io.netris.model.VnetResAddBody;
+import io.netris.model.VnetResDeleteBody;
+import io.netris.model.VnetResListBody;
+import io.netris.model.VnetsBody;
+import io.netris.model.VpcEditResponseOK;
+import io.netris.model.VpcVpcIdBody;
+import io.netris.model.response.AuthResponse;
+import io.netris.model.response.L4LbEditResponse;
+import io.netris.model.response.TenantResponse;
+import io.netris.model.response.TenantsResponse;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
+import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisACLCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisLoadBalancerRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.ListNetrisStaticRoutesCommand;
+import org.apache.cloudstack.agent.api.NetrisCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
+import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVnetCommand;
+import org.apache.cloudstack.agent.api.UpdateNetrisVpcCommand;
+import org.apache.cloudstack.resource.NetrisResourceObjectUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+public class NetrisApiClientImpl implements NetrisApiClient {
+
+ private final Logger logger = LogManager.getLogger(getClass());
+ private static final String ANY_IP = "0.0.0.0/0";
+ private static final String[] PROTOCOL_LIST = new String[]{"TCP", "UDP", "ICMP", "ALL"};
+
+ protected ApiClient apiClient;
+
+ protected final int siteId;
+ private final String siteName;
+ protected final int tenantId;
+ private final String tenantName;
+
+ public NetrisApiClientImpl(String endpointBaseUrl, String username, String password, String siteName, String adminTenantName) {
+ try {
+ apiClient = new ApiClient(endpointBaseUrl, username, password, 1L);
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error creating the Netris API Client for %s", endpointBaseUrl), e);
+ }
+ Pair<Integer, String> sitePair = getNetrisSitePair(siteName);
+ Pair<Integer, String> tenantPair = getNetrisTenantPair(adminTenantName);
+ this.siteId = sitePair.first();
+ this.siteName = sitePair.second();
+ this.tenantId = tenantPair.first();
+ this.tenantName = tenantPair.second();
+ }
+
+ private Pair<Integer, String> getNetrisSitePair(String siteName) {
+ List<GetSiteBody> sites = listSites();
+ if (CollectionUtils.isEmpty(sites)) {
+ throw new CloudRuntimeException("There are no Netris sites, please check the Netris endpoint");
+ }
+ List<GetSiteBody> filteredSites = sites.stream().filter(x -> x.getName().equals(siteName)).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(filteredSites)) {
+ throw new CloudRuntimeException(String.format("Cannot find a site matching name %s on Netris, please check the Netris endpoint", siteName));
+ }
+ return new Pair<>(filteredSites.get(0).getId(), siteName);
+ }
+
+ private Pair<Integer, String> getNetrisTenantPair(String adminTenantName) {
+ List<TenantResponse> tenants = listTenants();
+ if (CollectionUtils.isEmpty(tenants)) {
+ throw new CloudRuntimeException("There are no Netris tenants, please check the Netris endpoint");
+ }
+ List<TenantResponse> filteredTenants = tenants.stream().filter(x -> x.getName().equals(adminTenantName)).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(filteredTenants)) {
+ throw new CloudRuntimeException(String.format("Cannot find a site matching name %s on Netris, please check the Netris endpoint", adminTenantName));
+ }
+ return new Pair<>(filteredTenants.get(0).getId().intValue(), adminTenantName);
+ }
+
+ protected void logAndThrowException(String prefix, ApiException e) throws CloudRuntimeException {
+ String msg = String.format("%s: (%s, %s, %s)", prefix, e.getCode(), e.getMessage(), e.getResponseBody());
+ logger.error(msg, e);
+ throw new CloudRuntimeException(msg);
+ }
+
+ @Override
+ public boolean isSessionAlive() {
+ ApiResponse<AuthResponse> response = null;
+ try {
+ AuthenticationApi api = apiClient.getApiStubForMethod(AuthenticationApi.class);
+ response = api.apiAuthGet();
+ } catch (ApiException e) {
+ logAndThrowException("Error checking the Netris API session is alive", e);
+ }
+ return response != null && response.getStatusCode() == 200;
+ }
+
+ @Override
+ public List<GetSiteBody> listSites() {
+ SitesResponseOK response = null;
+ try {
+ SitesApi api = apiClient.getApiStubForMethod(SitesApi.class);
+ response = api.apiSitesGet();
+ } catch (ApiException e) {
+ logAndThrowException("Error listing Netris Sites", e);
+ }
+ return response != null ? response.getData() : null;
+ }
+
+ @Override
+ public List<VPCListing> listVPCs() {
+ VPCResponseOK response = null;
+ try {
+ VpcApi api = apiClient.getApiStubForMethod(VpcApi.class);
+ response = api.apiV2VpcGet();
+ } catch (ApiException e) {
+ logAndThrowException("Error listing Netris VPCs", e);
+ }
+ return response != null ? response.getData() : null;
+ }
+
+ @Override
+ public List<TenantResponse> listTenants() {
+ ApiResponse<TenantsResponse> response = null;
+ try {
+ TenantsApi api = apiClient.getApiStubForMethod(TenantsApi.class);
+ response = api.apiTenantsGet();
+ } catch (ApiException e) {
+ logAndThrowException("Error listing Netris Tenants", e);
+ }
+ return (response != null && response.getData() != null) ? response.getData().getData() : null;
+ }
+
+ private VPCResponseObjectOK createVpcInternal(String vpcName, int adminTenantId, String adminTenantName) {
+ VPCResponseObjectOK response;
+ logger.debug(String.format("Creating Netris VPC %s", vpcName));
+ try {
+ VpcApi vpcApi = apiClient.getApiStubForMethod(VpcApi.class);
+ VPCCreate body = new VPCCreate();
+ body.setName(vpcName);
+ VPCAdminTenant vpcAdminTenant = new VPCAdminTenant();
+ vpcAdminTenant.setId(adminTenantId);
+ vpcAdminTenant.name(adminTenantName);
+ body.setAdminTenant(vpcAdminTenant);
+ response = vpcApi.apiV2VpcPost(body);
+ } catch (ApiException e) {
+ logAndThrowException("Error creating Netris VPC", e);
+ return null;
+ }
+ return response;
+ }
+
+ private VpcEditResponseOK updateVpcInternal(String vpcName, String prevVpcName, int adminTenantId, String adminTenantName) {
+ VpcEditResponseOK response;
+ logger.debug(String.format("Updating Netris VPC name from %s to %s", prevVpcName, vpcName));
+ try {
+ VPCListing vpcResource = getVpcByNameAndTenant(prevVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", prevVpcName, tenantId);
+ return null;
+ }
+ VpcApi vpcApi = apiClient.getApiStubForMethod(VpcApi.class);
+ VpcVpcIdBody body = new VpcVpcIdBody();
+ body.setName(vpcName);
+ VPCAdminTenant vpcAdminTenant = new VPCAdminTenant();
+ vpcAdminTenant.setId(adminTenantId);
+ vpcAdminTenant.name(adminTenantName);
+ body.setAdminTenant(vpcAdminTenant);
+ response = vpcApi.apiV2VpcVpcIdPut(body, vpcResource.getId());
+ } catch (ApiException e) {
+ logAndThrowException("Error updating Netris VPC", e);
+ return null;
+ }
+ return response;
+ }
+
+ private InlineResponse2004Data createIpamAllocationInternal(String ipamName, String ipamPrefix, VPCListing vpc) {
+ logger.debug(String.format("Creating Netris IPAM Allocation %s for VPC %s", ipamPrefix, vpc.getName()));
+ try {
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ AllocationBody body = new AllocationBody();
+ AllocationBodyVpc allocationBodyVpc = new AllocationBodyVpc();
+ allocationBodyVpc.setId(vpc.getId());
+ allocationBodyVpc.setName(vpc.getName());
+ body.setVpc(allocationBodyVpc);
+ body.setName(ipamName);
+ body.setPrefix(ipamPrefix);
+ IpTreeAllocationTenant allocationTenant = new IpTreeAllocationTenant();
+ allocationTenant.setId(new BigDecimal(tenantId));
+ allocationTenant.setName(tenantName);
+ body.setTenant(allocationTenant);
+ InlineResponse2004 ipamResponse = ipamApi.apiV2IpamAllocationPost(body);
+ if (ipamResponse == null || !ipamResponse.isIsSuccess()) {
+ String reason = ipamResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris Allocation {} for VPC {} creation failed: {}", ipamPrefix, vpc.getName(), reason);
+ return null;
+ }
+ logger.debug(String.format("Successfully created VPC %s and its IPAM Allocation %s on Netris", vpc.getName(), ipamPrefix));
+ return ipamResponse.getData();
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error creating Netris IPAM Allocation %s for VPC %s", ipamPrefix, vpc.getName()), e);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean createVpc(CreateNetrisVpcCommand cmd) {
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC);
+ VPCResponseObjectOK createdVpc = createVpcInternal(netrisVpcName, tenantId, tenantName);
+ if (createdVpc == null || !createdVpc.isIsSuccess()) {
+ String reason = createdVpc == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris VPC {} creation failed: {}", cmd.getName(), reason);
+ return false;
+ }
+
+ String netrisIpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, cmd.getCidr());
+ String vpcCidr = cmd.getCidr();
+ InlineResponse2004Data createdIpamAllocation = createIpamAllocationInternal(netrisIpamAllocationName, vpcCidr, createdVpc.getData());
+ return createdIpamAllocation != null;
+ }
+
+ @Override
+ public boolean updateVpc(UpdateNetrisVpcCommand cmd) {
+ Long domainId = cmd.getDomainId();
+ Long zoneId = cmd.getZoneId();
+ Long accountId = cmd.getAccountId();
+ Long vpcId = cmd.getId();
+ String prevVpcName = cmd.getPreviousVpcName();
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC);
+ String netrisPrevVpcName = String.format("D%s-A%s-Z%s-V%s-%s", domainId, accountId, zoneId, vpcId, prevVpcName);
+ VpcEditResponseOK updatedVpc = updateVpcInternal(netrisVpcName, netrisPrevVpcName, tenantId, tenantName);
+ if (updatedVpc == null || !updatedVpc.isIsSuccess()) {
+ String reason = updatedVpc == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The update of Netris VPC {} failed: {}", cmd.getPreviousVpcName(), reason);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd) {
+ try {
+ String suffix = getNetrisVpcNameSuffix(cmd.getVpcId(), cmd.getVpcName(), cmd.getId(), cmd.getName(), cmd.isVpc());
+ String vpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffix);
+ VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
+ return false;
+ }
+ String natRuleName = cmd.getNatRuleName();
+ NatGetBody existingNatRule = netrisNatRuleExists(natRuleName);
+ boolean ruleExists = Objects.nonNull(existingNatRule);
+ if (ruleExists) {
+ deleteNatRule(natRuleName, existingNatRule.getId(), vpcResource.getName());
+ if (cmd.getNatRuleType().equals("STATICNAT")) {
+ String natIp = cmd.getNatIp();
+ String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), natIp);
+ deleteNatSubnet(netrisSubnetName, vpcResource.getId(), natIp);
+ }
+ }
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Error deleting Netris NAT Rule", e);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addOrUpdateAclRule(CreateOrUpdateNetrisACLCommand cmd, boolean forLb) {
+ String aclName = cmd.getNetrisAclName();
+ try {
+ AclApi aclApi = apiClient.getApiStubForMethod(AclApi.class);
+ VPCListing vpcResource;
+ String netrisVpcName;
+ if (forLb) {
+ vpcResource = getSystemVpc();
+ netrisVpcName = vpcResource.getName();
+
+ } else {
+ netrisVpcName = getNetrisVpcName(cmd, cmd.getVpcId(), cmd.getVpcName());
+ vpcResource = getNetrisVpcResource(netrisVpcName);
+ if (Objects.isNull(vpcResource)) {
+ return false;
+ }
+ }
+ AclBodyVpc vpc = new AclBodyVpc().id(vpcResource.getId());
+ List<String> aclNames = List.of(aclName);
+ Pair<Boolean, List<BigDecimal>> resultAndMatchingAclIds = getMatchingAclIds(aclNames, netrisVpcName);
+ List<BigDecimal> aclIdList = resultAndMatchingAclIds.second();
+ if (!aclIdList.isEmpty()) {
+ logger.debug("Netris ACL rule: {} already exists, updating it...", aclName);
+ AclEditItem aclEditItem = getAclEditItem(cmd, aclName, aclIdList.get(0));
+ aclEditItem.setVpc(vpc);
+ try {
+ aclApi.apiAclPut(aclEditItem);
+ } catch (ApiException e) {
+ if (e.getResponseBody().contains("This kind of acl already exists")) {
+ logger.info("Netris ACL rule: {} already exists and doesn't need to be updated", aclName);
+ return true;
+ }
+ throw new CloudRuntimeException("Error updating Netris ACL rule", e);
+ }
+ return true;
+ }
+ AclAddItem aclAddItem = getAclAddItem(cmd, aclName);
+ aclAddItem.setVpc(vpc);
+ aclApi.apiAclPost(aclAddItem);
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to create Netris ACL: %s", cmd.getNetrisAclName()), e);
+ }
+ return true;
+ }
+
+ AclAddItem getAclAddItem(CreateOrUpdateNetrisACLCommand cmd, String aclName) throws ApiException {
+ AclAddItem aclAddItem = new AclAddItem();
+ aclAddItem.setAction(cmd.getAction());
+ aclAddItem.setComment(String.format("ACL rule: %s. %s", cmd.getNetrisAclName(), cmd.getReason()));
+ aclAddItem.setName(aclName);
+ String protocol = cmd.getProtocol();
+ if ("TCP".equals(protocol)) {
+ aclAddItem.setEstablished(new BigDecimal(1));
+ } else {
+ aclAddItem.setReverse("yes");
+ }
+ if (!Arrays.asList(PROTOCOL_LIST).contains(protocol)) {
+ aclAddItem.setProto("ip");
+ aclAddItem.setSrcPortTo(cmd.getIcmpType());
+ // TODO: set proto number: where should the protocol number be set - API sets the protocol number to Src-from & to and Dest-from & to fields
+ } else if ("ICMP".equals(protocol)) {
+ aclAddItem.setProto("icmp");
+ if (cmd.getIcmpType() != -1) {
+ aclAddItem.setIcmpType(cmd.getIcmpType());
+ }
+ } else {
+ aclAddItem.setProto(protocol.toLowerCase(Locale.ROOT));
+ }
+
+ aclAddItem.setDstPortFrom(cmd.getDestPortStart());
+ aclAddItem.setDstPortTo(cmd.getDestPortEnd());
+ aclAddItem.setDstPrefix(cmd.getDestPrefix());
+ aclAddItem.setSrcPrefix(cmd.getSourcePrefix());
+ aclAddItem.setSrcPortFrom(1);
+ aclAddItem.setSrcPortTo(65535);
+ if (NatPutBody.ProtocolEnum.ICMP.name().equalsIgnoreCase(protocol)) {
+ aclAddItem.setIcmpType(cmd.getIcmpType());
+ }
+
+ return aclAddItem;
+ }
+
+ AclEditItem getAclEditItem(CreateOrUpdateNetrisACLCommand cmd, String aclName, BigDecimal aclId) throws ApiException {
+ AclEditItem aclEditItem = new AclEditItem();
+ aclEditItem.setId(aclId);
+ aclEditItem.setAction(cmd.getAction());
+ aclEditItem.setComment(String.format("ACL rule: %s. %s", cmd.getNetrisAclName(), cmd.getReason()));
+ aclEditItem.setName(aclName);
+ String protocol = cmd.getProtocol();
+ if ("TCP".equals(protocol)) {
+ aclEditItem.setEstablished(new BigDecimal(1));
+ } else {
+ aclEditItem.setReverse("yes");
+ }
+ if (!Arrays.asList(PROTOCOL_LIST).contains(protocol)) {
+ aclEditItem.setProto("ip");
+ aclEditItem.setSrcPortTo(cmd.getIcmpType());
+ // TODO: set proto number: where should the protocol number be set - API sets the protocol number to Src-from & to and Dest-from & to fields
+ } else if ("ICMP".equals(protocol)) {
+ aclEditItem.setProto("icmp");
+ if (cmd.getIcmpType() != -1) {
+ aclEditItem.setIcmpType(cmd.getIcmpType());
+ }
+ } else {
+ aclEditItem.setProto(protocol.toLowerCase(Locale.ROOT));
+ }
+
+ aclEditItem.setDstPortFrom(cmd.getDestPortStart());
+ aclEditItem.setDstPortTo(cmd.getDestPortEnd());
+ aclEditItem.setDstPrefix(cmd.getDestPrefix());
+ aclEditItem.setSrcPrefix(cmd.getSourcePrefix());
+ aclEditItem.setSrcPortFrom(1);
+ aclEditItem.setSrcPortTo(65535);
+ if (NatPutBody.ProtocolEnum.ICMP.name().equalsIgnoreCase(protocol)) {
+ aclEditItem.setIcmpType(cmd.getIcmpType());
+ }
+
+ return aclEditItem;
+ }
+
+ @Override
+ public boolean deleteAclRule(DeleteNetrisACLCommand cmd, boolean forLb) {
+ List<String> aclNames = cmd.getAclRuleNames();
+ try {
+ AclApi aclApi = apiClient.getApiStubForMethod(AclApi.class);
+
+ String vpcName;
+ if (!forLb) {
+ String suffix = getNetrisVpcNameSuffix(cmd.getVpcId(), cmd.getVpcName(), cmd.getId(), cmd.getName(), cmd.isVpc());
+ vpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffix);
+ } else {
+ VPCListing vpcResource = getSystemVpc();
+ vpcName = vpcResource.getName();
+ }
+ Pair<Boolean, List<BigDecimal>> resultAndMatchingAclIds = getMatchingAclIds(aclNames, vpcName);
+ Boolean result = resultAndMatchingAclIds.first();
+ List<BigDecimal> matchingAclIds = resultAndMatchingAclIds.second();
+ if (!result) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
+ return false;
+ }
+ if (matchingAclIds.isEmpty()) {
+ logger.warn("There doesn't seem to be any ACLs on Netris matching {}", aclNames.size() > 1 ? String.join(",", aclNames) : aclNames);
+ return true;
+ }
+ AclDeleteItem aclDeleteItem = new AclDeleteItem();
+ aclDeleteItem.setId(matchingAclIds);
+ aclDeleteItem.setTenantsID(String.valueOf(tenantId));
+ aclApi.apiAclDelete(aclDeleteItem);
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to delete Netris ACLs: %s", String.join(",", cmd.getAclRuleNames())), e);
+ }
+ return true;
+ }
+
+ Pair<Boolean, List<BigDecimal>> getMatchingAclIds(List<String> aclNames, String vpcName) {
+ try {
+ AclApi aclApi = apiClient.getApiStubForMethod(AclApi.class);
+ VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
+ return new Pair<>(false, Collections.emptyList());
+ }
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(vpcResource.getId());
+ FilterBySites siteFilter = new FilterBySites();
+ siteFilter.add(siteId);
+ AclResponseGetOk aclGetResponse = aclApi.apiAclGet(siteFilter, vpcFilter);
+ if (aclGetResponse == null || !aclGetResponse.isIsSuccess()) {
+ logger.warn("No ACLs were found to be present for the specific Netris VPC resource {}." +
+ " Netris ACLs may have been deleted out of band.", vpcName);
+ return new Pair<>(true, Collections.emptyList());
+ }
+ List<AclGetBody> aclList = aclGetResponse.getData();
+ return new Pair<>(true, aclList.stream()
+ .filter(acl -> aclNames.contains(acl.getName()))
+ .map(acl -> BigDecimal.valueOf(acl.getId()))
+ .collect(Collectors.toList()));
+ } catch (ApiException e) {
+ logAndThrowException("Failed to retrieve Netris ACLs", e);
+ }
+ return new Pair<>(true, Collections.emptyList());
+ }
+
+ public boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd) {
+ String prefix = cmd.getPrefix();
+ String nextHop = cmd.getNextHop();
+ Long vpcId = cmd.getId();
+ String vpcName = cmd.getName();
+ boolean updateRoute = cmd.isUpdateRoute();
+ try {
+ String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, null, null, true);
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return false;
+ }
+
+ String[] suffixes = new String[2];
+ suffixes[0] = vpcId.toString();
+ suffixes[1] = cmd.getRouteId().toString();
+ String staticRouteId = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffixes);
+
+ Pair<Boolean, RoutesGetBody> existingStaticRoute = staticRouteExists(vpcResource.getId(), prefix, null, staticRouteId);
+ if (updateRoute) {
+ if (!existingStaticRoute.first()) {
+ logger.error("The Netris static route {} does not exist for VPC {}, adding it", prefix, netrisVpcName);
+ return addStaticRouteInternal(vpcResource, netrisVpcName, prefix, nextHop, staticRouteId);
+ }
+ return updateStaticRouteInternal(existingStaticRoute.second().getId(), netrisVpcName, prefix, nextHop, staticRouteId);
+ } else {
+ if (existingStaticRoute.first()) {
+ String existingNextHop = existingStaticRoute.second().getNextHop();
+ if (existingNextHop != null && existingNextHop.equals(nextHop)) {
+ logger.debug("The Netris static route {} already exists for VPC {}", prefix, netrisVpcName);
+ return true;
+ } else {
+ logger.debug("The Netris static route {} already exists but has different next hop {} for VPC {}", prefix, nextHop, netrisVpcName);
+ return false;
+ }
+ }
+ return addStaticRouteInternal(vpcResource, netrisVpcName, prefix, nextHop, staticRouteId);
+ }
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Error adding Netris static route", e);
+ }
+ }
+
+ private boolean addStaticRouteInternal(VPCListing vpcResource, String netrisVpcName, String prefix, String nextHop, String staticRouteId) {
+ try {
+ RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
+ RoutesPostBody routesPostBody = new RoutesPostBody();
+ routesPostBody.setPrefix(prefix);
+ routesPostBody.setNextHop(nextHop);
+ routesPostBody.setSiteId(new BigDecimal(siteId));
+ routesPostBody.setStateStatus(RoutesBody.StateStatusEnum.ACTIVE);
+
+ RoutesBodyVpcVpc vpcBody = new RoutesBodyVpcVpc();
+ vpcBody.setId(vpcResource.getId());
+ vpcBody.setName(vpcResource.getName());
+ vpcBody.setIsDefault(vpcResource.isIsDefault());
+ vpcBody.setIsSystem(vpcResource.isIsSystem());
+ routesPostBody.setVpc(vpcBody);
+
+ routesPostBody.setDescription(staticRouteId);
+ routesPostBody.setStateStatus(RoutesBody.StateStatusEnum.ACTIVE);
+ routesPostBody.setSwitches(Collections.emptyList());
+
+ InlineResponse2004 routeResponse = routesApi.apiRoutesPost(routesPostBody);
+ if (routeResponse == null || !routeResponse.isIsSuccess()) {
+ String reason = routeResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris static route creation failed for netris VPC - {}: {}", netrisVpcName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ } catch (ApiException e) {
+ logAndThrowException("Error adding Netris static route", e);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean updateStaticRouteInternal(Integer id, String netrisVpcName, String prefix, String nextHop, String staticRouteId) {
+ try {
+ RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
+ RoutesPutBody routesPutBody = new RoutesPutBody();
+ routesPutBody.setId(id);
+ routesPutBody.setPrefix(prefix);
+ routesPutBody.setNextHop(nextHop);
+ routesPutBody.setSiteId(new BigDecimal(siteId));
+ routesPutBody.setStateStatus(RoutesPutBody.StateStatusEnum.ACTIVE);
+
+ routesPutBody.setDescription(staticRouteId);
+ routesPutBody.setSwitches(Collections.emptyList());
+
+ InlineResponse2003 routeResponse = routesApi.apiRoutesPut(routesPutBody);
+ if (routeResponse == null || !routeResponse.isIsSuccess()) {
+ String reason = routeResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("Failed to update Netris static route for netris VPC - {}: {}", netrisVpcName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ } catch (ApiException e) {
+ logAndThrowException("Error updating Netris static route", e);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd) {
+ Long vpcId = cmd.getId();
+ String vpcName = cmd.getName();
+ String prefix = cmd.getPrefix();
+ String nextHop = cmd.getNextHop();
+ try {
+ String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, null, null, true);
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return false;
+ }
+
+ String[] suffixes = new String[2];
+ suffixes[0] = vpcId.toString();
+ suffixes[1] = cmd.getRouteId().toString();
+ String staticRouteId = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffixes);
+ Pair<Boolean, RoutesGetBody> existingStaticRoute = staticRouteExists(vpcResource.getId(), prefix, nextHop, staticRouteId);
+
+ if (Boolean.FALSE.equals(existingStaticRoute.first())) {
+ logger.debug("The Netris static route {} does not exist for VPC {}", prefix, netrisVpcName);
+ return true;
+ }
+ RoutesGetBody existingRoute = existingStaticRoute.second();
+ RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
+ RoutesBodyId id = new RoutesBodyId();
+ id.setId(existingRoute.getId());
+ InlineResponse2003 routeDeleteResponse = routesApi.apiRoutesDelete(id);
+ if (routeDeleteResponse == null || !routeDeleteResponse.isIsSuccess()) {
+ String reason = routeDeleteResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris static route deletion failed for netris VPC - {}: {}", netrisVpcName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ return true;
+ } catch (ApiException e) {
+ logAndThrowException("Error deleting Netris static route", e);
+ }
+ return false;
+ }
+
+ @Override
+ public List<StaticRoute> listStaticRoutes(ListNetrisStaticRoutesCommand cmd) {
+ Long vpcId = cmd.getId();
+ String vpcName = cmd.getName();
+ String prefix = cmd.getPrefix();
+ String nextHop = cmd.getNextHop();
+ String vpcSuffix = getNetrisVpcNameSuffix(vpcId, vpcName, null, null, true);
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, vpcSuffix);
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return new ArrayList<>();
+ }
+
+ List<RoutesGetBody> staticRoutes = listStaticRoutes(vpcResource.getId(), prefix, nextHop);
+ if (CollectionUtils.isEmpty(staticRoutes)) {
+ return new ArrayList<>();
+ }
+ List<StaticRoute> result = new ArrayList<>();
+ for (RoutesGetBody staticRoute : staticRoutes) {
+ // All static routes belong the SYSTEM account, which does not matter
+ result.add(new StaticRouteVO(null, staticRoute.getName(), vpcId, Account.ACCOUNT_ID_SYSTEM, Domain.ROOT_DOMAIN, staticRoute.getNextHop()));
+ }
+ return result;
+ }
+
+ @Override
+ public boolean releaseNatIp(ReleaseNatIpCommand cmd) {
+ String natIp = cmd.getNatIp() + "/32";
+ try {
+ VPCListing systemVpc = getSystemVpc();
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(systemVpc.getId());
+ SubnetResBody subnetResponse = ipamApi.apiV2IpamSubnetsGet(vpcFilter);
+ if (subnetResponse == null || !subnetResponse.isIsSuccess()) {
+ String reason = subnetResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("Failed to retrieve Netris Public NAT IPs due to {}", reason);
+ throw new CloudRuntimeException(reason);
+ }
+ List<IpTreeSubnet> natIps = subnetResponse.getData().stream().filter(ip -> ip.getPrefix().equals(natIp)).collect(Collectors.toList());
+ if (!natIps.isEmpty()) {
+ ipamApi.apiV2IpamTypeIdDelete("subnet", natIps.get(0).getId().intValue());
+ }
+
+ } catch (ApiException e) {
+ logAndThrowException("Failed to release Netris IP", e);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean createOrUpdateLbRule(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd) {
+ boolean isVpc = cmd.isVpc();
+ Long networkResourceId = cmd.getId();
+ String networkResourceName = cmd.getName();
+ Long domainId = cmd.getDomainId();
+ Long accountId = cmd.getAccountId();
+ Long zoneId = cmd.getZoneId();
+ Long lbId = cmd.getLbId();
+ String publicIp = cmd.getPublicIp();
+ List<NetrisLbBackend> lbBackends = cmd.getLbBackends();
+
+ try {
+ String resourcePrefix = isVpc ? "V" : "N";
+ String netrisResourceName = String.format("D%s-A%s-Z%s-%s%s-%s", domainId, accountId, zoneId, resourcePrefix, networkResourceId, networkResourceName);
+ VPCListing vpcResource = getNetrisVpcResource(netrisResourceName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisResourceName, tenantId);
+ return false;
+ }
+ createLBSubnet(cmd, publicIp + "/32", vpcResource.getId());
+
+ String suffix = String.format("LB%s", lbId);
+ String lbName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.LB, suffix);
+ Pair<Boolean, List<BigDecimal>> resultAndMatchingLbId = getMatchingLbRule(lbName, vpcResource.getName());
+ Boolean result = resultAndMatchingLbId.first();
+ List<BigDecimal> matchingLbId = resultAndMatchingLbId.second();
+ if (Boolean.FALSE.equals(result)) {
+ logger.warn("Could not find the Netris LB rule with name {}", lbName);
+ }
+ boolean updateRule = !matchingLbId.isEmpty();
+ L4lbAddOrUpdateItem l4lbAddItem = getL4LbRule(cmd, vpcResource, lbName, publicIp, lbBackends, updateRule);
+ L4LoadBalancerApi loadBalancerApi = apiClient.getApiStubForMethod(L4LoadBalancerApi.class);
+ boolean success;
+ L4LbEditResponse editResponse = null;
+ ResAddEditBody createResponse = null;
+ if (updateRule) {
+ editResponse = loadBalancerApi.apiV2L4lbIdPut((L4LbEditItem) l4lbAddItem, matchingLbId.get(0).intValue());
+ success = editResponse.isIsSuccess();
+ } else {
+ createResponse = loadBalancerApi.apiV2L4lbPost((L4LbAddItem) l4lbAddItem);
+ success = createResponse.isIsSuccess();
+ }
+ if (ObjectUtils.allNull(editResponse, createResponse) || Boolean.FALSE.equals(success)) {
+ throw new CloudRuntimeException(String.format("Failed to %s Netris LB rule", updateRule ? "update" : "create"));
+ }
+ if (Objects.nonNull(cmd.getCidrList()) && !cmd.getCidrList().isEmpty()) {
+ applyAclRulesForLb(cmd, lbName);
+ }
+ } catch (ApiException e) {
+ logAndThrowException("Failed to create Netris load balancer rule", e);
+ }
+ return true;
+ }
+
+ private void applyAclRulesForLb(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, String lbName) {
+ // Add deny all rule first
+ addOrUpdateAclRule(createNetrisACLRuleCommand(cmd, lbName, "ANY",
+ NetrisNetworkRule.NetrisRuleAction.DENY.name().toLowerCase(Locale.ROOT), 0), true);
+ AtomicInteger cidrIndex = new AtomicInteger(1);
+ for (String cidr : cmd.getCidrList().split(" ")) {
+ try {
+ addOrUpdateAclRule(createNetrisACLRuleCommand(cmd, lbName, cidr,
+ NetrisNetworkRule.NetrisRuleAction.PERMIT.name().toLowerCase(Locale.ROOT),
+ cidrIndex.getAndIncrement()), true);
+ } catch (Exception e) {
+ throw new CloudRuntimeException(String.format("Failed to add Netris ACL rule for LB CIDR %s", cidr), e);
+ }
+ }
+ }
+
+ private CreateOrUpdateNetrisACLCommand createNetrisACLRuleCommand(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, String netrisLbName, String cidr, String action, int index) {
+ Long zoneId = cmd.getZoneId();
+ Long accountId = cmd.getAccountId();
+ Long domainId = cmd.getDomainId();
+ String networkName = null;
+ Long networkId = null;
+ String vpcName = null;
+ Long vpcId = null;
+ boolean isVpc = cmd.isVpc();
+ if (isVpc) {
+ vpcId = cmd.getId();
+ vpcName = cmd.getName();
+ } else {
+ networkName = cmd.getName();
+ networkId = cmd.getId();
+ }
+ String destinationPrefix = cmd.getPublicIp() + "/32";
+ String srcPort = cmd.getPublicPort();
+ String dstPort = cmd.getPublicPort();
+ CreateOrUpdateNetrisACLCommand aclCommand = new CreateOrUpdateNetrisACLCommand(zoneId, accountId, domainId, networkName, networkId,
+ vpcName, vpcId, Objects.nonNull(vpcId), action, NetrisServiceImpl.getPrefix(cidr), NetrisServiceImpl.getPrefix(destinationPrefix),
+ Integer.parseInt(srcPort), Integer.parseInt(dstPort), cmd.getProtocol());
+ String aclName;
+ if (isVpc) {
+ aclName = String.format("V%s-LBACL%s-%s", vpcId, index, cmd.getRuleName());
+ } else {
+ aclName = String.format("N%s-LBACL%s-%s", networkId, index, cmd.getRuleName());
+ }
+ String netrisAclName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.ACL, aclName);
+ aclCommand.setNetrisAclName(netrisAclName);
+ aclCommand.setReason(String.format("ACL Rule for CIDR %s of LB %s ", aclName, netrisLbName));
+ return aclCommand;
+ }
+
+ private L4lbAddOrUpdateItem getL4LbRule(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, VPCListing vpcResource, String lbName,
+ String publicIp, List<NetrisLbBackend> lbBackends, boolean updateRule) {
+ L4lbAddOrUpdateItem l4lbAddItem = updateRule ? new L4LbEditItem() : new L4LbAddItem();
+ try {
+ l4lbAddItem.setName(lbName);
+
+ String protocol = cmd.getProtocol().toUpperCase(Locale.ROOT);
+ if (!Arrays.asList("TCP", "UDP").contains(protocol)) {
+ throw new CloudRuntimeException("Invalid protocol " + protocol);
+ }
+ l4lbAddItem.setProtocol(cmd.getProtocol().toUpperCase(Locale.ROOT));
+ L4LBSite site = new L4LBSite();
+ site.setId(siteId);
+ site.setName(siteName);
+ l4lbAddItem.setSite(site);
+ l4lbAddItem.setSiteID(new BigDecimal(siteId));
+
+ L4LbTenant tenant = new L4LbTenant();
+ tenant.setId(tenantId);
+ tenant.setName(tenantName);
+ l4lbAddItem.setTenant(tenant);
+
+ L4LbVpc vpc = new L4LbVpc();
+ vpc.setId(vpcResource.getId());
+ l4lbAddItem.setVpc(vpc);
+
+ l4lbAddItem.setAutomatic(false);
+ l4lbAddItem.setIpFamily(NetUtils.isIpv4(publicIp) ? L4lbAddOrUpdateItem.IpFamilyEnum.IPv4 : L4lbAddOrUpdateItem.IpFamilyEnum.IPv6);
+ l4lbAddItem.setIp(publicIp);
+ l4lbAddItem.setStatus("enable");
+
+ List<L4LoadBalancerBackendItem> backends = new ArrayList<>();
+ for (NetrisLbBackend backend : lbBackends) {
+ L4LoadBalancerBackendItem backendItem = new L4LoadBalancerBackendItem();
+ backendItem.setIp(backend.getVmIp());
+ backendItem.setPort(backend.getPort());
+ backends.add(backendItem);
+ }
+ l4lbAddItem.setBackend(backends);
+ l4lbAddItem.setPort(Integer.valueOf(cmd.getPublicPort()));
+ l4lbAddItem.setHealthCheck(L4lbAddOrUpdateItem.HealthCheckEnum.NONE);
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Failed to create Netris load balancer rule", e);
+ }
+ return l4lbAddItem;
+ }
+
+ @Override
+ public boolean deleteLbRule(DeleteNetrisLoadBalancerRuleCommand cmd) {
+ boolean isVpc = cmd.isVpc();
+ String vpcName = null;
+ String networkName = null;
+ Long vpcId = null;
+ Long networkId = null;
+ if (isVpc) {
+ vpcName = cmd.getName();
+ vpcId = cmd.getId();
+ } else {
+ networkName = cmd.getName();
+ networkId = cmd.getId();
+ }
+ Long lbId = cmd.getLbId();
+ String cidrList = cmd.getCidrList();
+ try {
+ String suffix = getNetrisVpcNameSuffix(vpcId, vpcName, networkId, networkName, isVpc);
+ String netrisVpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffix);
+ suffix = String.format("LB%s", lbId);
+ String lbName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.LB, suffix);
+ Pair<Boolean, List<BigDecimal>> resultAndMatchingLbId = getMatchingLbRule(lbName, netrisVpcName);
+ Boolean result = resultAndMatchingLbId.first();
+ List<BigDecimal> matchingLbId = resultAndMatchingLbId.second();
+ if (!result) {
+ logger.error("Could not find the Netris LB rule with name {}", lbName);
+ return false;
+ }
+ if (matchingLbId.isEmpty()) {
+ logger.warn("There doesn't seem to be any LB rule on Netris matching {}", lbName);
+ return true;
+ }
+
+ L4LoadBalancerApi lbApi = apiClient.getApiStubForMethod(L4LoadBalancerApi.class);
+ lbApi.apiV2L4lbIdDelete(matchingLbId.get(0).intValue());
+ if (Objects.nonNull(cidrList)) {
+ deleteAclRulesForLb(cmd);
+ }
+ } catch (ApiException e) {
+ logAndThrowException("Failed to delete Netris load balancer rule", e);
+ }
+ return true;
+ }
+
+ private void deleteAclRulesForLb(DeleteNetrisLoadBalancerRuleCommand cmd) {
+ // delete the deny rule
+ deleteAclRule(deleteNetrisACLCommand(cmd, 0), true);
+ AtomicInteger cidrIndex = new AtomicInteger(1);
+ for (String cidr : cmd.getCidrList().split(" ")) {
+ try {
+ deleteAclRule(deleteNetrisACLCommand(cmd, cidrIndex.getAndIncrement()), true);
+ } catch (Exception e) {
+ throw new CloudRuntimeException(String.format("Failed to delete Netris ACL rule for LB CIDR %s", cidr), e);
+ }
+ }
+ }
+
+ private DeleteNetrisACLCommand deleteNetrisACLCommand(DeleteNetrisLoadBalancerRuleCommand cmd, int index) {
+ Long zoneId = cmd.getZoneId();
+ Long accountId = cmd.getAccountId();
+ Long domainId = cmd.getDomainId();
+ String networkName = null;
+ Long networkId = null;
+ String vpcName = null;
+ Long vpcId = null;
+ boolean isVpc = cmd.isVpc();
+ if (isVpc) {
+ vpcId = cmd.getId();
+ vpcName = cmd.getName();
+ } else {
+ networkName = cmd.getName();
+ networkId = cmd.getId();
+ }
+ DeleteNetrisACLCommand deleteAclCommand = new DeleteNetrisACLCommand(zoneId, accountId, domainId, networkName, networkId, isVpc, vpcId, vpcName);
+ String aclName;
+ if (isVpc) {
+ aclName = String.format("V%s-LBACL%s-%s", vpcId, index, cmd.getRuleName());
+ } else {
+ aclName = String.format("N%s-LBACL%s-%s", networkId, index, cmd.getRuleName());
+ }
+ String netrisAclName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.ACL, aclName);
+ deleteAclCommand.setAclRuleNames(Collections.singletonList(netrisAclName));
+ return deleteAclCommand;
+ }
+
+ private Pair<Boolean, List<BigDecimal>> getMatchingLbRule(String lbName, String vpcName) {
+ try {
+ VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
+ return new Pair<>(false, Collections.emptyList());
+ }
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(vpcResource.getId());
+ FilterBySites siteFilter = new FilterBySites();
+ siteFilter.add(siteId);
+ L4LoadBalancerApi lbApi = apiClient.getApiStubForMethod(L4LoadBalancerApi.class);
+ L4lbresBody lbGetResponse = lbApi.apiV2L4lbGet(siteFilter, vpcFilter);
+ if (lbGetResponse == null || !lbGetResponse.isIsSuccess()) {
+ logger.warn("No LB rules were found to be present for the specific Netris VPC resource {}." +
+ " Netris LB rules may have been deleted out of band.", vpcName);
+ return new Pair<>(true, Collections.emptyList());
+ }
+ List<L4LoadBalancerItem> lbList = lbGetResponse.getData();
+ return new Pair<>(true, lbList.stream()
+ .filter(lb -> lbName.equals(lb.getName()))
+ .map(acl -> BigDecimal.valueOf(acl.getId()))
+ .collect(Collectors.toList()));
+ } catch (ApiException e) {
+ logAndThrowException("Failed to retrieve Netris LB rules", e);
+ }
+ return new Pair<>(true, Collections.emptyList());
+ }
+
+ private List<RoutesGetBody> listStaticRoutes(Integer netrisVpcId, String prefix, String nextHop) {
+ try {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(netrisVpcId);
+ FilterBySites sitesFilter = new FilterBySites();
+ sitesFilter.add(siteId);
+ RoutesApi routesApi = apiClient.getApiStubForMethod(RoutesApi.class);
+ RoutesResponseGetOk routesResponseGetOk = routesApi.apiRoutesGet(sitesFilter, vpcFilter);
+ if (Objects.isNull(routesResponseGetOk) || Boolean.FALSE.equals(routesResponseGetOk.isIsSuccess())) {
+ logger.warn("Failed to retrieve static routes");
+ return null;
+ }
+ List<RoutesGetBody> routesList = routesResponseGetOk.getData();
+ return routesList.stream()
+ .filter(x -> (Objects.isNull(prefix) || x.getName().equals(prefix)) &&
+ (Objects.isNull(nextHop) || x.getNextHop().equals(nextHop)))
+ .collect(Collectors.toList());
+ } catch (ApiException e) {
+ logAndThrowException("Error listing Netris static routes", e);
+ }
+ return null;
+ }
+
+ private Pair<Boolean, RoutesGetBody> staticRouteExists(Integer netrisVpcId, String prefix, String nextHop, String description) {
+ List<RoutesGetBody> staticRoutes = listStaticRoutes(netrisVpcId, prefix, nextHop);
+ if (staticRoutes == null) {
+ return new Pair<>(false, null);
+ }
+ return new Pair<>(!staticRoutes.isEmpty(), staticRoutes.isEmpty() ? null : staticRoutes.get(0));
+ }
+
+ public void deleteNatRule(String natRuleName, Integer snatRuleId, String netrisVpcName) {
+ logger.debug("Deleting NAT rule on Netris: {} for VPC {}", natRuleName, netrisVpcName);
+ try {
+ NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
+ natApi.apiV2NatIdDelete(snatRuleId);
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to delete NAT rule: %s for VPC: %s", natRuleName, netrisVpcName), e);
+ }
+ }
+
+ private void deleteVpcIpamAllocationInternal(VPCListing vpcResource, String allocationName) {
+ logger.debug("Deleting Netris VPC IPAM Allocation {} for VPC {}", allocationName, vpcResource.getName());
+ try {
+ VpcApi vpcApi = apiClient.getApiStubForMethod(VpcApi.class);
+ VPCResponseResourceOK vpcResourcesResponse = vpcApi.apiV2VpcVpcIdResourcesGet(vpcResource.getId());
+ VPCResourceIpam vpcAllocationResource = getVpcAllocationResource(vpcResourcesResponse, allocationName);
+ if (Objects.isNull(vpcAllocationResource)) {
+ logger.info("No VPC IPAM Allocation found for VPC {}", allocationName);
+ return;
+ }
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ logger.debug("Removing the IPAM allocation {} with ID {}", vpcAllocationResource.getName(), vpcAllocationResource.getId());
+ ipamApi.apiV2IpamTypeIdDelete("allocation", vpcAllocationResource.getId());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error removing IPAM Allocation %s for VPC %s", allocationName, vpcResource.getName()), e);
+ }
+ }
+
+ private VPCResourceIpam getVpcAllocationResource(VPCResponseResourceOK vpcResourcesResponse, String allocationName) {
+ VPCResource resource = vpcResourcesResponse.getData().get(0);
+ List<VPCResourceIpam> vpcAllocations = resource.getAllocation();
+ if (CollectionUtils.isNotEmpty(vpcAllocations)) {
+ vpcAllocations = vpcAllocations.stream().filter(x -> x.getName().equalsIgnoreCase(allocationName)).collect(Collectors.toList());
+ return CollectionUtils.isNotEmpty(vpcAllocations) ? vpcAllocations.get(0) : null;
+ }
+ return null;
+ }
+
+ private VPCListing getVpcByNameAndTenant(String vpcName) {
+ try {
+ List<VPCListing> vpcListings = listVPCs();
+ List<VPCListing> vpcs = vpcListings.stream()
+ .filter(x -> x.getName().equals(vpcName) && x.getAdminTenant().getId().equals(tenantId))
+ .collect(Collectors.toList());
+ return vpcs.isEmpty() ? null : vpcs.get(0);
+ } catch (Exception e) {
+ throw new CloudRuntimeException(String.format("Error getting VPC %s information: %s", vpcName, e.getMessage()), e);
+ }
+ }
+
+ private VPCResponseObjectOK deleteVpcInternal(VPCListing vpcResource) {
+ try {
+ VpcApi vpcApi = apiClient.getApiStubForMethod(VpcApi.class);
+ logger.debug("Removing the VPC {} with ID {}", vpcResource.getName(), vpcResource.getId());
+ return vpcApi.apiV2VpcVpcIdDelete(vpcResource.getId());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error deleting VPC %s: %s", vpcResource.getName(), e.getResponseBody()), e);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean deleteVpc(DeleteNetrisVpcCommand cmd) {
+ String suffix = String.valueOf(cmd.getId());
+ String vpcName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC);
+ VPCListing vpcResource = getVpcByNameAndTenant(vpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", vpcName, tenantId);
+ return false;
+ }
+ String snatRuleName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.SNAT, suffix);
+ NatGetBody existingNatRule = netrisNatRuleExists(snatRuleName);
+ boolean ruleExists = Objects.nonNull(existingNatRule);
+ if (ruleExists) {
+ deleteNatRule(snatRuleName, existingNatRule.getId(), vpcResource.getName());
+ }
+
+ String vpcAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, cmd.getCidr());
+ deleteVpcIpamAllocationInternal(vpcResource, vpcAllocationName);
+ VPCResponseObjectOK response = deleteVpcInternal(vpcResource);
+ return response != null && response.isIsSuccess();
+ }
+
+ @Override
+ public boolean createVnet(CreateNetrisVnetCommand cmd) {
+ String vpcName = cmd.getVpcName();
+ Long vpcId = cmd.getVpcId();
+ String networkName = cmd.getName();
+ Long networkId = cmd.getId();
+ String vnetCidr = cmd.getCidr();
+ Integer vxlanId = cmd.getVxlanId();
+ String netrisTag = cmd.getNetrisTag();
+ String netmask = vnetCidr.split("/")[1];
+ String netrisGateway = cmd.getGateway() + "/" + netmask;
+ String netrisV6Cidr = cmd.getIpv6Cidr();
+ boolean isVpc = cmd.isVpc();
+ Boolean isGlobalRouting = cmd.isGlobalRouting();
+
+ try {
+ String netrisVpcName = getNetrisVpcName(cmd, vpcId, vpcName);
+ VPCListing associatedVpc = getNetrisVpcResource(netrisVpcName);
+ if (associatedVpc == null) {
+ logger.error("Failed to find Netris VPC with name: {}, to create the corresponding vNet for network {}", netrisVpcName, networkName);
+ return false;
+ }
+
+ String vNetName;
+ if (isVpc) {
+ vNetName = String.format("V%s-N%s-%s", vpcId, networkId, networkName);
+ } else {
+ vNetName = String.format("N%s-%s", networkId, networkName);
+ }
+ String netrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, vNetName) ;
+ String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), vnetCidr) ;
+
+ createIpamSubnetInternal(netrisSubnetName, vnetCidr, SubnetBody.PurposeEnum.COMMON, associatedVpc, isGlobalRouting);
+ if (Objects.nonNull(netrisV6Cidr)) {
+ String netrisV6IpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, netrisV6Cidr);
+ String netrisV6SubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), netrisV6Cidr) ;
+ BigDecimal ipamAllocationId = getIpamAllocationIdByPrefixAndVpc(netrisV6Cidr, associatedVpc);
+ if (ipamAllocationId == null) {
+ InlineResponse2004Data createdIpamAllocation = createIpamAllocationInternal(netrisV6IpamAllocationName, netrisV6Cidr, associatedVpc);
+ if (Objects.isNull(createdIpamAllocation)) {
+ throw new CloudRuntimeException(String.format("Failed to create Netris IPAM Allocation %s for VPC %s", netrisV6IpamAllocationName, netrisVpcName));
+ }
+ }
+ createIpamSubnetInternal(netrisV6SubnetName, netrisV6Cidr, SubnetBody.PurposeEnum.COMMON, associatedVpc, isGlobalRouting);
+ }
+ logger.debug("Successfully created IPAM Subnet {} for network {} on Netris", netrisSubnetName, networkName);
+
+ VnetResAddBody vnetResponse = createVnetInternal(associatedVpc, netrisVnetName, netrisGateway, netrisV6Cidr, vxlanId, netrisTag);
+ if (vnetResponse == null || !vnetResponse.isIsSuccess()) {
+ String reason = vnetResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris vNet creation {} failed: {}", vNetName, reason);
+ return false;
+ }
+ } catch (ApiException e) {
+ throw new CloudRuntimeException(String.format("Failed to create Netris vNet %s", networkName), e);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updateVnet(UpdateNetrisVnetCommand cmd) {
+ String networkName = cmd.getName();
+ Long networkId = cmd.getId();
+ String prevNetworkName = cmd.getPrevNetworkName();
+ String vpcName = cmd.getVpcName();
+ Long vpcId = cmd.getVpcId();
+ boolean isVpc = cmd.isVpc();
+
+ String netrisVpcName = getNetrisVpcName(cmd, vpcId, vpcName);
+ VPCListing associatedVpc = getNetrisVpcResource(netrisVpcName);
+ if (associatedVpc == null) {
+ logger.error("Failed to find Netris VPC with name: {}, to create the corresponding vNet for network {}", netrisVpcName, networkName);
+ return false;
+ }
+
+ String vNetName;
+ String prevVnetName;
+ if (isVpc) {
+ vNetName = String.format("V%s-N%s-%s", vpcId, networkId, networkName);
+ prevVnetName = String.format("V%s-N%s-%s", vpcId, networkId, prevNetworkName);
+ } else {
+ vNetName = String.format("N%s-%s", networkId, networkName);
+ prevVnetName = String.format("N%s-%s", networkId, prevNetworkName);
+ }
+ String netrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, vNetName) ;
+ String prevNetrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, prevVnetName) ;
+
+ VnetResAddBody response = updateVnetInternal(associatedVpc, netrisVnetName, prevNetrisVnetName);
+ if (response == null || !response.isIsSuccess()) {
+ String reason = response == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("Netris vNet: {} update failed: {}", vNetName, reason);
+ return false;
+ }
+ return true;
+ }
+
+
+ private VnetResAddBody updateVnetInternal(VPCListing associatedVpc, String netrisVnetName, String prevVnetName) {
+ logger.debug("Updating Netris vNet name from {} to {} ", netrisVnetName, prevVnetName);
+ try {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(associatedVpc.getId());
+ FilterBySites siteFilter = new FilterBySites();
+ siteFilter.add(siteId);
+ List<VnetsBody> vnetsList = getVnets(associatedVpc, prevVnetName, siteFilter, vpcFilter);
+ if (CollectionUtils.isEmpty(vnetsList)) {
+ String errorMsg = String.format("Could not find vNet with name: %s", prevVnetName);
+ logger.error(errorMsg);
+ throw new CloudRuntimeException(errorMsg);
+ }
+ VnetsBody vnetsBody = vnetsList.get(0);
+
+ VnetEditBody vnetBody = new VnetEditBody();
+
+ vnetBody.setCustomAnycastMac(vnetBody.getCustomAnycastMac());
+
+ VnetEditBodyGateways gatewayV4 = new VnetEditBodyGateways();
+ gatewayV4.prefix(vnetsBody.getGateways().get(0).getPrefix());
+ gatewayV4.setDhcpEnabled(false);
+ VnetEditBodyDhcp dhcp = new VnetEditBodyDhcp();
+ dhcp.setEnd("");
+ dhcp.setStart("");
+ dhcp.setOptionSet(new VnetAddBodyDhcpOptionSet());
+ gatewayV4.setDhcp(dhcp);
+ List<VnetEditBodyGateways> gatewaysList = new ArrayList<>();
+ gatewaysList.add(gatewayV4);
+
+
+ if (vnetsBody.getGateways().size() > 1 && Objects.nonNull(vnetsBody.getGateways().get(1))) {
+ String netrisV6Gateway = vnetsBody.getGateways().get(1).getPrefix();
+ VnetEditBodyGateways gatewayV6 = new VnetEditBodyGateways();
+ gatewayV6.prefix(netrisV6Gateway);
+ gatewayV6.setDhcpEnabled(false);
+ gatewayV6.setDhcp(dhcp);
+ gatewaysList.add(gatewayV6);
+ }
+
+ vnetBody.setGateways(gatewaysList);
+ vnetBody.setGuestTenants(new ArrayList<>());
+ vnetBody.setL3vpn(false);
+ vnetBody.setName(netrisVnetName);
+ vnetBody.setNativeVlan(0);
+ vnetBody.setVxlanID(vnetsBody.getVxlanID());
+ vnetBody.setPorts(new ArrayList<>());
+
+ IpTreeSubnetSites subnetSites = new IpTreeSubnetSites();
+ subnetSites.setId(new BigDecimal(siteId));
+ subnetSites.setName(siteName);
+ List<IpTreeSubnetSites> subnetSitesList = new ArrayList<>();
+ subnetSitesList.add(subnetSites);
+ vnetBody.setSites(subnetSitesList);
+
+ vnetBody.setState(VnetEditBody.StateEnum.ACTIVE);
+
+ vnetBody.setTags(new ArrayList<>());
+
+ IpTreeAllocationTenant allocationTenant = new IpTreeAllocationTenant();
+ allocationTenant.setId(new BigDecimal(tenantId));
+ allocationTenant.setName(tenantName);
+ vnetBody.setTenant(allocationTenant);
+
+ vnetBody.setVlan(0);
+ vnetBody.setVlanAware(false);
+ vnetBody.setVlans("");
+
+ VnetAddBodyVpc vpc = new VnetAddBodyVpc();
+ vpc.setName(associatedVpc.getName());
+ vpc.setId(associatedVpc.getId());
+ vnetBody.setVpc(vpc);
+
+ vnetBody.setTags(vnetsBody.getTags());
+
+ VNetApi vnetApi = apiClient.getApiStubForMethod(VNetApi.class);
+ return vnetApi.apiV2VnetIdPut(vnetBody, vnetsBody.getId().intValue());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error creating Netris vNet %s for VPC %s", netrisVnetName, associatedVpc.getName()), e);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean deleteVnet(DeleteNetrisVnetCommand cmd) {
+ String vpcName = cmd.getVpcName();
+ Long vpcId = cmd.getVpcId();
+ String networkName = cmd.getName();
+ Long networkId = cmd.getId();
+ boolean isVpc = cmd.isVpc();
+ String vnetCidr = cmd.getVNetCidr();
+ String vnetV6Cidr = cmd.getvNetV6Cidr();
+ try {
+ String netrisVpcName = getNetrisVpcName(cmd, vpcId, vpcName);
+ VPCListing associatedVpc = getNetrisVpcResource(netrisVpcName);
+ if (associatedVpc == null) {
+ logger.error("Failed to find Netris VPC with name: {}, to create the corresponding vNet for network {}", netrisVpcName, networkName);
+ return false;
+ }
+
+ String vNetName;
+ if (isVpc) {
+ vNetName = String.format("V%s-N%s-%s", vpcId, networkId, networkName);
+ } else {
+ vNetName = String.format("N%s-%s", networkId, networkName);
+ }
+
+ String netrisVnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VNET, vNetName) ;
+ String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), vnetCidr);
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(associatedVpc.getId());
+ FilterBySites siteFilter = new FilterBySites();
+ siteFilter.add(siteId);
+ deleteVnetInternal(associatedVpc, siteFilter, vpcFilter, netrisVnetName, vNetName);
+
+ logger.debug("Successfully deleted vNet {}", vNetName);
+ deleteSubnetInternal(vpcFilter, netrisVnetName, netrisSubnetName);
+ if (Objects.nonNull(vnetV6Cidr)) {
+ String netrisV6IpamAllocationName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, vnetV6Cidr);
+ String netrisV6SubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(cmd.getVpcId()), vnetV6Cidr);
+ deleteSubnetInternal(vpcFilter, netrisVnetName, netrisV6SubnetName);
+ deleteVpcIpamAllocationInternal(associatedVpc, netrisV6IpamAllocationName);
+ }
+
+ } catch (Exception e) {
+ throw new CloudRuntimeException(String.format("Failed to delete Netris vNet %s", networkName), e);
+ }
+ return true;
+ }
+
+ protected VPCListing getSystemVpc() throws ApiException {
+ List<VPCListing> systemVpcList = listVPCs().stream().filter(VPCListing::isIsSystem).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(systemVpcList)) {
+ String msg = "Cannot find any system VPC";
+ logger.error(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ return systemVpcList.get(0);
+ }
+
+ private BigDecimal getIpamAllocationIdByPrefixAndVpc(String superCidrPrefix, VPCListing vpc) throws ApiException {
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ FilterBySites filterBySites = new FilterBySites();
+ filterBySites.add(siteId);
+ FilterByVpc filterByVpc = new FilterByVpc();
+ filterByVpc.add(vpc.getId());
+ IpTree ipamTree = ipamApi.apiV2IpamGet(filterBySites, filterByVpc);
+ List<IpTreeAllocation> superCidrList = ipamTree.getData().stream()
+ .filter(x -> x.getPrefix().equals(superCidrPrefix) || isAllocationPartOfBiggerAllocation(x.getPrefix(), superCidrPrefix))
+ .collect(Collectors.toList());
+ return CollectionUtils.isEmpty(superCidrList) ? null : superCidrList.get(0).getId();
+ }
+
+ private boolean isAllocationPartOfBiggerAllocation(String netrisAllocation, String providedAllocation) {
+ IPAddress biggerAllocation = new IPAddressString(netrisAllocation).getAddress();
+ IPAddress smallerAllocation = new IPAddressString(providedAllocation).getAddress();
+
+ return biggerAllocation.contains(smallerAllocation);
+
+ }
+
+ private IpTreeSubnet getIpamSubnetByAllocationAndPrefixAndPurposeAndVpc(BigDecimal ipamAllocationId, String exactCidr, IpTreeSubnet.PurposeEnum purpose, VPCListing vpc) throws ApiException {
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ FilterByVpc filterByVpc = new FilterByVpc();
+ filterByVpc.add(vpc.getId());
+ SubnetResBody subnetResBody = ipamApi.apiV2IpamSubnetsGet(filterByVpc);
+ List<IpTreeSubnet> exactSubnetList = subnetResBody.getData().stream()
+ .filter(x -> ipamAllocationId != null ?
+ x.getAllocationID().equals(ipamAllocationId) && x.getPrefix().equals(exactCidr) && x.getPurpose() == purpose :
+ x.getPrefix().equals(exactCidr) && x.getPurpose() == purpose)
+ .collect(Collectors.toList());
+ return CollectionUtils.isEmpty(exactSubnetList) ? null : exactSubnetList.get(0);
+ }
+
+ @Override
+ public boolean setupZoneLevelPublicRange(SetupNetrisPublicRangeCommand cmd) {
+ String superCidr = cmd.getSuperCidr();
+ String exactCidr = cmd.getExactCidr();
+ try {
+ VPCListing systemVpc = getSystemVpc();
+ logger.debug("Checking if the Netris Public Super CIDR {} exists", superCidr);
+ BigDecimal ipamAllocationId = getIpamAllocationIdByPrefixAndVpc(superCidr, systemVpc);
+ if (ipamAllocationId == null) {
+ String ipamName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_ALLOCATION, superCidr);
+ InlineResponse2004Data ipamAllocation = createIpamAllocationInternal(ipamName, superCidr, systemVpc);
+ if (ipamAllocation == null) {
+ String msg = String.format("Could not create the zone level super CIDR %s for the system VPC", superCidr);
+ logger.error(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ ipamAllocationId = new BigDecimal(ipamAllocation.getId());
+ }
+ IpTreeSubnet exactSubnet = getIpamSubnetByAllocationAndPrefixAndPurposeAndVpc(ipamAllocationId, exactCidr, IpTreeSubnet.PurposeEnum.COMMON, systemVpc);
+ if (exactSubnet == null) {
+ String ipamSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, exactCidr);
+ createIpamSubnetInternal(ipamSubnetName, exactCidr, SubnetBody.PurposeEnum.COMMON, systemVpc, null);
+ }
+ } catch (ApiException e) {
+ String msg = String.format("Error setting up the Netris Public Range %s on super CIDR %s", exactCidr, superCidr);
+ logAndThrowException(msg, e);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean createOrUpdateNatRuleInternal(CreateOrUpdateNetrisNatCommand cmd) {
+ String ruleName = cmd.getNatRuleName();
+ long vpcId = cmd.getVpcId();
+ Long networkId = cmd.getId();
+ String networkName = cmd.getName();
+ String vpcName = cmd.getVpcName();
+ String vpcCidr = cmd.getVpcCidr();
+ boolean isVpc = cmd.isVpc();
+ NatPostBody.ActionEnum action = getNatActionFromRuleType(cmd.getNatRuleType());
+ NatPostBody.ProtocolEnum protocol = getProtocolFromString(cmd.getProtocol());
+ NatPostBody.StateEnum state = getStateFromString(cmd.getState());
+
+ String vNetName = isVpc ?
+ String.format("V%s-N%s-%s", vpcId, networkId, networkName) :
+ String.format("N%s-%s", networkId, networkName);
+ String netrisVpcName = getNetrisVpcName(cmd, vpcId, vpcName);
+ VPCListing vpcResource = getNetrisVpcResource(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return false;
+ }
+
+ String targetIpSubnet = null;
+ if (NatPostBody.ActionEnum.SNAT == action) {
+ targetIpSubnet = cmd.getNatIp() + "/32";
+ } else if (NatPostBody.ActionEnum.DNAT == action) {
+ targetIpSubnet = cmd.getDestinationAddress() + "/32";
+ }
+
+ if (StringUtils.isNotBlank(targetIpSubnet) && existsDestinationSubnet(targetIpSubnet)) {
+ logger.debug("Creating subnet with NAT purpose for {}}", targetIpSubnet);
+ createNatSubnet(cmd, targetIpSubnet, vpcResource.getId());
+ }
+
+ NatGetBody existingNatRule = netrisNatRuleExists(ruleName);
+ boolean ruleExists = Objects.nonNull(existingNatRule);
+ if (!ruleExists) {
+ String destinationAddress = action == NatPostBody.ActionEnum.SNAT ? ANY_IP : cmd.getDestinationAddress() + "/32";
+ String destinationPort = cmd.getDestinationPort();
+ String sourceAddress = action == NatPostBody.ActionEnum.SNAT ? vpcCidr : ANY_IP;
+ String sourcePort = "1-65535";
+ String snatToIp = action == NatPostBody.ActionEnum.SNAT ? targetIpSubnet : null;
+ String dnatToIp = action == NatPostBody.ActionEnum.DNAT ? cmd.getSourceAddress() + "/32" : null;
+ String dnatToPort = action == NatPostBody.ActionEnum.DNAT ? cmd.getSourcePort() : null;
+ return createNatRuleInternal(ruleName, action, protocol, state, destinationAddress, destinationPort,
+ sourceAddress, sourcePort, snatToIp, dnatToIp, dnatToPort, netrisVpcName, networkName, vNetName);
+ } else if (NatPostBody.ActionEnum.SNAT == action) {
+ return updateSnatRuleInternal(ruleName, targetIpSubnet, netrisVpcName, networkName, vNetName, existingNatRule.getId(), vpcCidr);
+ }
+ return true;
+ }
+
+ private NatPostBody.StateEnum getStateFromString(String state) {
+ return NatPostBody.StateEnum.fromValue(state);
+ }
+
+ private NatPostBody.ActionEnum getNatActionFromRuleType(String natRuleType) {
+ return NatPostBody.ActionEnum.fromValue(natRuleType);
+ }
+
+ @Override
+ public boolean createOrUpdateSNATRule(CreateOrUpdateNetrisNatCommand cmd) {
+ return createOrUpdateNatRuleInternal(cmd);
+ }
+
+ private boolean existsDestinationSubnet(String destinationSubnet) {
+ try {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(getSystemVpc().getId());
+ List<IpTreeSubnet> targetSubnetList = getSubnet(vpcFilter, destinationSubnet);
+ return targetSubnetList != null;
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error checking if subnet %s exists: %s", destinationSubnet, e.getMessage()), e);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd) {
+ String staticNatRuleName = cmd.getNatRuleName();
+ String natIP = cmd.getNatIp() + "/32";
+ String vmIp = cmd.getVmIp() + "/32";
+ String vpcName = cmd.getVpcName();
+ String vpcCidr = cmd.getVpcCidr();
+ Long vpcId = cmd.getVpcId();
+ Long networkId = cmd.getId();
+ String networkName = cmd.getName();
+ boolean isVpc = cmd.isVpc();
+
+ try {
+ String netrisVpcName = getNetrisVpcName(cmd, vpcId, vpcName);
+ VPCListing vpcResource = getNetrisVpcResource(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return false;
+ }
+ // Create a /32 subnet for the DNAT IP
+ createNatSubnet(cmd, natIP, vpcResource.getId());
+ NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
+ NatPostBody natBody = new NatPostBody();
+ natBody.setAction(NatPostBody.ActionEnum.DNAT);
+ natBody.setDestinationAddress(natIP);
+ natBody.setName(staticNatRuleName);
+ natBody.setProtocol(NatPostBody.ProtocolEnum.ALL);
+ natBody.setState(NatPostBody.StateEnum.ENABLED);
+ natBody.setComment(String.format("Static NAT rule for %s", netrisVpcName));
+
+ NatBodySiteSite site = new NatBodySiteSite();
+ site.setId(siteId);
+ site.setName(siteName);
+ natBody.setSite(site);
+ natBody.setSourceAddress(ANY_IP);
+ natBody.setDnatToIP(vmIp);
+
+ NatBodyVpcVpc vpc = new NatBodyVpcVpc();
+ vpc.setId(vpcResource.getId());
+ vpc.setName(vpcResource.getName());
+ natBody.setVpc(vpc);
+
+ InlineResponse20015 natResponse = natApi.apiV2NatPost(natBody);
+ if (natResponse == null || !natResponse.isIsSuccess()) {
+ String reason = natResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris static NAT (DNAT) rule creation failed for netris VPC - {}: {}", netrisVpcName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to create Static NAT (DNAT) rule for network : %s", Objects.nonNull(vpcName) ? vpcName : networkName), e);
+ }
+ return true;
+ }
+
+ private void createNatSubnet(NetrisCommand cmd, String natIp, Integer netrisVpcId) {
+ try {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(netrisVpcId);
+ String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET, String.valueOf(((CreateOrUpdateNetrisNatCommand)cmd).getVpcId()), natIp);
+ List<IpTreeSubnet> matchedSubnets = getSubnet(vpcFilter, netrisSubnetName);
+ if (matchedSubnets.isEmpty()) {
+ VPCListing systemVpc = getSystemVpc();
+ createIpamSubnetInternal(netrisSubnetName, natIp, SubnetBody.PurposeEnum.NAT, systemVpc, null);
+ } else {
+ IpTreeSubnet existingSubnet = matchedSubnets.stream().filter(x -> x.getPrefix().equals(natIp)).collect(Collectors.toList()).get(0);
+ if (existingSubnet.getPurpose() != IpTreeSubnet.PurposeEnum.NAT) {
+ VPCListing systemVpc = getSystemVpc();
+ logger.debug("Subnet: {} already exists, but purpose is not NAT, updating its purpose to 'nat'", natIp);
+ updateIpamSubnetInternal(existingSubnet.getId().intValue(), netrisSubnetName, natIp, SubnetBody.PurposeEnum.NAT, systemVpc, null);
+ }
+ }
+ } catch (ApiException e) {
+ throw new CloudRuntimeException(String.format("Failed to create subnet for %s with NAT purpose", natIp));
+ }
+ }
+
+ private void createLBSubnet(NetrisCommand cmd, String lbIp, Integer netrisVpcId) {
+ try {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(netrisVpcId);
+ String netrisSubnetName = NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd,
+ NetrisResourceObjectUtils.NetrisObjectType.IPAM_SUBNET,
+ String.valueOf(cmd.getId()), lbIp);
+ List<IpTreeSubnet> matchedSubnets = getSubnet(vpcFilter, netrisSubnetName);
+ VPCListing systemVpc = getSystemVpc();
+ if (matchedSubnets.isEmpty()) {
+ createIpamSubnetInternal(netrisSubnetName, lbIp, SubnetBody.PurposeEnum.LOAD_BALANCER, systemVpc, null);
+ } else if (IpTreeSubnet.PurposeEnum.LOAD_BALANCER != matchedSubnets.get(0).getPurpose()){
+ logger.debug("Updating existing NAT subnet {} to have load balancer purpose", netrisSubnetName);
+ updateIpamSubnetInternal(matchedSubnets.get(0).getId().intValue(), netrisSubnetName, lbIp, SubnetBody.PurposeEnum.LOAD_BALANCER, systemVpc, null);
+ }
+ logger.debug("LB subnet: {} already exists", netrisSubnetName);
+ } catch (ApiException e) {
+ throw new CloudRuntimeException(String.format("Failed to create subnet for %s with LB purpose", lbIp));
+ }
+ }
+
+ private NatPostBody.ProtocolEnum getProtocolFromString(String protocol) {
+ return NatPostBody.ProtocolEnum.fromValue(protocol);
+ }
+
+ private NatPostBody createNatRulePostBody(String ruleName, NatPostBody.ActionEnum action, NatPostBody.ProtocolEnum protocol, NatPostBody.StateEnum state,
+ String destinationAddress, String destinationPort,
+ String sourceAddress, String sourcePort,
+ String dnatToIp, String dnatToPort,
+ String netrisVpcName, String snatIP, String comment) {
+ NatPostBody natBody = new NatPostBody();
+ natBody.setAction(action);
+ natBody.setName(ruleName);
+ natBody.setProtocol(protocol);
+ natBody.setState(state);
+ if (StringUtils.isNotBlank(comment)) {
+ natBody.setComment(comment);
+ }
+
+ natBody.setDestinationAddress(destinationAddress);
+ if (StringUtils.isNotBlank(destinationPort)) {
+ natBody.setDestinationPort(destinationPort);
+ }
+
+ if (StringUtils.isNotBlank(sourceAddress)) {
+ natBody.setSourceAddress(sourceAddress);
+ }
+ if (StringUtils.isNotBlank(sourcePort)) {
+ natBody.setSourcePort(sourcePort);
+ }
+
+ NatBodySiteSite site = new NatBodySiteSite();
+ site.setId(siteId);
+ site.setName(siteName);
+ natBody.setSite(site);
+
+ if (StringUtils.isNotBlank(snatIP)) {
+ natBody.setSnatToIP(snatIP);
+ }
+
+ if (StringUtils.isNotBlank(dnatToIp)) {
+ natBody.setDnatToIP(dnatToIp);
+ }
+ if (StringUtils.isNotBlank(dnatToPort)) {
+ natBody.setDnatToPort(Integer.valueOf(dnatToPort));
+ }
+
+ NatBodyVpcVpc vpc = new NatBodyVpcVpc();
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return null;
+ }
+ vpc.setId(vpcResource.getId());
+ vpc.setName(vpcResource.getName());
+ natBody.setVpc(vpc);
+ return natBody;
+ }
+
+ @Override
+ public boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd) {
+ return createOrUpdateNatRuleInternal(cmd);
+ }
+
+ private boolean createNatRuleInternal(String ruleName, NatPostBody.ActionEnum action, NatPostBody.ProtocolEnum protocol, NatPostBody.StateEnum state,
+ String destinationAddress, String destinationPort, String sourceAddress, String sourcePort,
+ String sNatToIp, String dNatToIp, String dNatToPort,
+ String netrisVpcName, String networkName, String vNetName) {
+ try {
+ NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
+ String comment = String.format("NAT rule for %s with action %s", netrisVpcName, action.name());
+ NatPostBody natBody = createNatRulePostBody(ruleName, action, protocol, state,
+ destinationAddress, destinationPort, sourceAddress, sourcePort,
+ dNatToIp, dNatToPort, netrisVpcName, sNatToIp, comment);
+ if (natBody == null) {
+ return false;
+ }
+ InlineResponse20015 natResponse = natApi.apiV2NatPost(natBody);
+ if (natResponse == null || !natResponse.isIsSuccess()) {
+ String reason = natResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris NAT rule {} creation failed for network(vNet) - {}({}): {}", action.name(), networkName, vNetName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to create NAT rule %s for network(vNet): %s(%s)", action.name(), networkName, vNetName), e);
+ }
+ return true;
+ }
+
+ private boolean updateSnatRuleInternal(String snatRuleName, String snatIP, String netrisVpcName, String networkName,
+ String vNetName, Integer netisSnatId, String vpcCidr) {
+ try {
+ NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
+ NatPutBody natBody = new NatPutBody();
+ natBody.setAction(NatPutBody.ActionEnum.SNAT);
+ natBody.setDestinationAddress(ANY_IP);
+ natBody.setName(snatRuleName);
+ natBody.setProtocol(NatPutBody.ProtocolEnum.ALL);
+
+ NatBodySiteSite site = new NatBodySiteSite();
+ site.setId(siteId);
+ site.setName(siteName);
+ natBody.setSite(site);
+ natBody.setSourceAddress(vpcCidr);
+ natBody.setSnatToIP(snatIP);
+
+ NatBodyVpcVpc vpc = new NatBodyVpcVpc();
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ return false;
+ }
+ vpc.setId(vpcResource.getId());
+ vpc.setName(vpcResource.getName());
+ natBody.setVpc(vpc);
+
+ InlineResponse20016 natUpdateResponse = natApi.apiV2NatIdPut(natBody, netisSnatId);
+ if (natUpdateResponse == null || !natUpdateResponse.isIsSuccess()) {
+ String reason = natUpdateResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("Update of Netris SNAT rule failed for network(vNet) - {}({}): {}", networkName, vNetName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to create SNAT rule for network(vNet): %s(%s)", networkName, vNetName), e);
+ }
+ return true;
+ }
+
+ private List<VnetsBody> getVnets(VPCListing associatedVpc, String netrisVnetName, FilterBySites siteFilter, FilterByVpc vpcFilter) {
+ try {
+ VNetApi vNetApi = apiClient.getApiStubForMethod(VNetApi.class);
+ VnetResListBody vnetList = vNetApi.apiV2VnetGet(siteFilter, vpcFilter);
+ if (vnetList == null || !vnetList.isIsSuccess()) {
+ throw new CloudRuntimeException(String.format("Failed to list vNets for the given VPC: %s and site: %s", associatedVpc.getName(), siteName));
+ }
+ return vnetList.getData().stream().filter(vnet -> vnet.getName().equals(netrisVnetName)).collect(Collectors.toList());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to get vNets: %s", netrisVnetName), e);
+ }
+ return Collections.emptyList();
+ }
+
+ private void deleteVnetInternal(VPCListing associatedVpc, FilterBySites siteFilter, FilterByVpc vpcFilter, String netrisVnetName, String vNetName) {
+ try {
+ VNetApi vNetApi = apiClient.getApiStubForMethod(VNetApi.class);
+ List<VnetsBody> vnetsList = getVnets(associatedVpc, netrisVnetName, siteFilter, vpcFilter);
+ if (CollectionUtils.isEmpty(vnetsList)) {
+ logger.debug("vNet: {} for the given VPC: {} appears to already be deleted on Netris", vNetName, associatedVpc.getName());
+ return;
+ }
+ VnetsBody vnetsBody = vnetsList.get(0);
+
+ VnetResDeleteBody deleteVnetResponse = vNetApi.apiV2VnetIdDelete(vnetsBody.getId().intValue());
+ if (deleteVnetResponse == null || !deleteVnetResponse.isIsSuccess()) {
+ throw new CloudRuntimeException(String.format("Failed to delete vNet: %s", vNetName));
+ }
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to delete vNet: %s", netrisVnetName), e);
+ }
+ }
+
+ private List<IpTreeSubnet> getSubnet(FilterByVpc vpcFilter, String netrisSubnetName) {
+ try {
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ SubnetResBody subnetsResponse = ipamApi.apiV2IpamSubnetsGet(vpcFilter);
+ List<IpTreeSubnet> subnets = subnetsResponse.getData();
+ return subnets.stream().filter(subnet -> subnet.getName().equals(netrisSubnetName)).collect(Collectors.toList());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to get IPAM subnet: %s", netrisSubnetName), e);
+ }
+ return new ArrayList<>();
+ }
+
+ private void deleteSubnetInternal(FilterByVpc vpcFilter, String netrisVnetName, String netrisSubnetName) {
+ try {
+ String logString = "";
+ if (Objects.nonNull(netrisVnetName)) {
+ logString = String.format("for vNet: %s ", netrisVnetName);
+ }
+ logger.debug("Deleting Netris VPC IPAM Subnet {} {}", netrisSubnetName, logString);
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ List<IpTreeSubnet> matchedSubnets = getSubnet(vpcFilter, netrisSubnetName);
+ if (CollectionUtils.isEmpty(matchedSubnets)) {
+ logger.debug("IPAM subnet: {} {} appears to already be deleted on Netris", netrisSubnetName, logString);
+ return;
+ }
+
+ ipamApi.apiV2IpamTypeIdDelete("subnet", matchedSubnets.get(0).getId().intValue());
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Failed to delete subnet: %s", netrisSubnetName), e);
+ }
+ }
+
+ private SubnetBody getIpamSubnetBody(VPCListing vpc, SubnetBody.PurposeEnum purpose, String subnetName, String subnetPrefix, Boolean isGlobalRouting) {
+ SubnetBody subnetBody = new SubnetBody();
+ subnetBody.setName(subnetName);
+
+ AllocationBodyVpc vpcAllocationBody = new AllocationBodyVpc();
+ vpcAllocationBody.setName(vpc.getName());
+ vpcAllocationBody.setId(vpc.getId());
+ subnetBody.setVpc(vpcAllocationBody);
+
+ IpTreeAllocationTenant allocationTenant = new IpTreeAllocationTenant();
+ allocationTenant.setId(new BigDecimal(tenantId));
+ allocationTenant.setName(tenantName);
+ subnetBody.setTenant(allocationTenant);
+
+ IpTreeSubnetSites subnetSites = new IpTreeSubnetSites();
+ subnetSites.setId(new BigDecimal(siteId));
+ subnetSites.setName(siteName);
+ subnetBody.setSites(List.of(subnetSites));
+
+ subnetBody.setPurpose(purpose);
+ subnetBody.setPrefix(subnetPrefix);
+ if (isGlobalRouting != null) {
+ subnetBody.setGlobalRouting(isGlobalRouting);
+ }
+ return subnetBody;
+ }
+
+ private InlineResponse2004Data createIpamSubnetInternal(String subnetName, String subnetPrefix, SubnetBody.PurposeEnum purpose, VPCListing vpc, Boolean isGlobalRouting) {
+ logger.debug("Creating Netris IPAM Subnet {} for VPC {}", subnetPrefix, vpc.getName());
+ try {
+
+ SubnetBody subnetBody = getIpamSubnetBody(vpc, purpose, subnetName, subnetPrefix, isGlobalRouting);
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ InlineResponse2004 subnetResponse = ipamApi.apiV2IpamSubnetPost(subnetBody);
+ if (subnetResponse == null || !subnetResponse.isIsSuccess()) {
+ String reason = subnetResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris IPAM Subnet {} creation failed: {}", subnetName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ return subnetResponse.getData();
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error creating Netris IPAM Subnet %s for VPC %s", subnetPrefix, vpc.getName()), e);
+ return null;
+ }
+ }
+
+ private InlineResponse2004Data updateIpamSubnetInternal(Integer netrisSubnetId, String subnetName, String subnetPrefix,
+ SubnetBody.PurposeEnum purpose, VPCListing vpc, Boolean isGlobalRouting) {
+ logger.debug("Updating Netris IPAM Subnet {} for VPC {}", subnetPrefix, vpc.getName());
+ try {
+
+ SubnetBody subnetBody = getIpamSubnetBody(vpc, purpose, subnetName, subnetPrefix, isGlobalRouting);
+ IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+ InlineResponse2004 subnetResponse = ipamApi.apiV2IpamSubnetIdPut(subnetBody, netrisSubnetId);
+ if (subnetResponse == null || !subnetResponse.isIsSuccess()) {
+ String reason = subnetResponse == null ? "Empty response" : "Operation failed on Netris";
+ logger.debug("The Netris IPAM Subnet {} update failed: {}", subnetName, reason);
+ throw new CloudRuntimeException(reason);
+ }
+ return subnetResponse.getData();
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error Updating Netris IPAM Subnet %s for VPC %s", subnetPrefix, vpc.getName()), e);
+ return null;
+ }
+ }
+
+ VnetResAddBody createVnetInternal(VPCListing associatedVpc, String netrisVnetName, String netrisGateway, String netrisV6Cidr, Integer vxlanId, String netrisTag) {
+ logger.debug("Creating Netris VPC vNet {} for CIDR {}", netrisVnetName, netrisGateway);
+ try {
+ VnetAddBody vnetBody = new VnetAddBody();
+
+ vnetBody.setCustomAnycastMac("");
+
+ VnetAddBodyGateways gatewayV4 = new VnetAddBodyGateways();
+ gatewayV4.prefix(netrisGateway);
+ gatewayV4.setDhcpEnabled(false);
+ VnetAddBodyDhcp dhcp = new VnetAddBodyDhcp();
+ dhcp.setEnd("");
+ dhcp.setStart("");
+ dhcp.setOptionSet(new VnetAddBodyDhcpOptionSet());
+ gatewayV4.setDhcp(dhcp);
+ List<VnetAddBodyGateways> gatewaysList = new ArrayList<>();
+ gatewaysList.add(gatewayV4);
+
+ if (Objects.nonNull(netrisV6Cidr)) {
+ VnetAddBodyGateways gatewayV6 = new VnetAddBodyGateways();
+ gatewayV6.prefix(NetUtils.getIpv6Gateway(netrisV6Cidr));
+ gatewayV6.setDhcpEnabled(false);
+ gatewayV6.setDhcp(dhcp);
+ gatewaysList.add(gatewayV6);
+ }
+
+ vnetBody.setGateways(gatewaysList);
+ vnetBody.setGuestTenants(new ArrayList<>());
+ vnetBody.setL3vpn(false);
+ vnetBody.setName(netrisVnetName);
+ vnetBody.setNativeVlan(0);
+ vnetBody.setVxlanID(vxlanId);
+ vnetBody.setPorts(new ArrayList<>());
+
+ IpTreeSubnetSites subnetSites = new IpTreeSubnetSites();
+ subnetSites.setId(new BigDecimal(siteId));
+ subnetSites.setName(siteName);
+ List<IpTreeSubnetSites> subnetSitesList = new ArrayList<>();
+ subnetSitesList.add(subnetSites);
+ vnetBody.setSites(subnetSitesList);
+
+ vnetBody.setState(VnetAddBody.StateEnum.ACTIVE);
+
+ vnetBody.setTags(new ArrayList<>());
+
+ IpTreeAllocationTenant allocationTenant = new IpTreeAllocationTenant();
+ allocationTenant.setId(new BigDecimal(tenantId));
+ allocationTenant.setName(tenantName);
+ vnetBody.setTenant(allocationTenant);
+
+ vnetBody.setVlan(0);
+ vnetBody.setVlanAware(false);
+ vnetBody.setVlans("");
+
+ VnetAddBodyVpc vpc = new VnetAddBodyVpc();
+ vpc.setName(associatedVpc.getName());
+ vpc.setId(associatedVpc.getId());
+ vnetBody.setVpc(vpc);
+
+ vnetBody.setTags(Collections.singletonList(netrisTag));
+
+ VNetApi vnetApi = apiClient.getApiStubForMethod(VNetApi.class);
+ return vnetApi.apiV2VnetPost(vnetBody);
+ } catch (ApiException e) {
+ logAndThrowException(String.format("Error creating Netris vNet %s for VPC %s", netrisVnetName, associatedVpc.getName()), e);
+ return null;
+ }
+ }
+
+
+
+ private String getNetrisVpcNameSuffix(Long vpcId, String vpcName, Long networkId, String networkName, boolean isVpc) {
+ String suffix = null;
+ if (isVpc) {
+ suffix = String.format("%s-%s", vpcId, vpcName);
+ } else {
+ suffix = String.format("%s-%s", networkId, networkName);
+ }
+ return suffix;
+ }
+
+ private NatGetBody netrisNatRuleExists(String netrisNatRule) {
+ try {
+ NatApi natApi = apiClient.getApiStubForMethod(NatApi.class);
+ //NatResponseGetOk response = natApi.apiV2NatGet(null, Arrays.asList(new BigDecimal(vpcId)));
+ NatResponseGetOk response = natApi.apiV2NatGet(null, null);
+ if (Objects.isNull(response) || !response.isIsSuccess()) {
+ throw new CloudRuntimeException("Failed to list Netris NAT rules");
+ }
+ List<NatGetBody> data = response.getData().stream().filter(natData -> natData.getName().equals(netrisNatRule)).collect(Collectors.toList());
+ if (data.isEmpty()) {
+ return null;
+ }
+ return data.get(0);
+
+ } catch (ApiException e) {
+ throw new CloudRuntimeException("Failed to list Netris NAT rules");
+ }
+ }
+
+ private VPCListing getNetrisVpcResource(String netrisVpcName) {
+ VPCListing vpcResource = getVpcByNameAndTenant(netrisVpcName);
+ if (vpcResource == null) {
+ logger.error("Could not find the Netris VPC resource with name {} and tenant ID {}", netrisVpcName, tenantId);
+ }
+ return vpcResource;
+ }
+
+ private String getNetrisVpcName(NetrisCommand cmd, Long vpcId, String vpcName) {
+ String suffix = getNetrisVpcNameSuffix(vpcId, vpcName, cmd.getId(), cmd.getName(), cmd.isVpc());
+ return NetrisResourceObjectUtils.retrieveNetrisResourceObjectName(cmd, NetrisResourceObjectUtils.NetrisObjectType.VPC, suffix);
+ }
+
+ private void deleteNatSubnet(String netrisSubnetName, Integer netrisVpcId, String natIp) {
+ FilterByVpc vpcFilter = new FilterByVpc();
+ vpcFilter.add(netrisVpcId);
+ deleteSubnetInternal(vpcFilter, null, netrisSubnetName);
+ }
+}
diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
similarity index 55%
copy from plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
copy to plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
index 7673e5a6038..0e798ebb6be 100644
--- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
+++ b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
@@ -34,7 +34,6 @@ import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ConnectionException;
import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
@@ -42,41 +41,38 @@ import com.cloud.host.Status;
import com.cloud.network.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PublicIpAddress;
-import com.cloud.network.VirtualRouterProvider;
+import com.cloud.network.SDNProviderNetworkRule;
+import com.cloud.network.SDNProviderOpObject;
+import com.cloud.network.as.AutoScaleCounter;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVMMapVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
-import com.cloud.network.dao.PhysicalNetworkVO;
-import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.element.DhcpServiceProvider;
import com.cloud.network.element.DnsServiceProvider;
-import com.cloud.network.element.FirewallServiceProvider;
import com.cloud.network.element.IpDeployer;
import com.cloud.network.element.LoadBalancingServiceProvider;
import com.cloud.network.element.NetworkACLServiceProvider;
import com.cloud.network.element.PortForwardingServiceProvider;
import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.VirtualRouterElement;
-import com.cloud.network.element.VirtualRouterProviderVO;
import com.cloud.network.element.VpcProvider;
import com.cloud.network.lb.LoadBalancingRule;
+import com.cloud.network.netris.NetrisLbBackend;
+import com.cloud.network.netris.NetrisService;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.LoadBalancerContainer;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.StaticNat;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
-import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
@@ -89,8 +85,6 @@ import com.cloud.user.AccountManager;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -99,21 +93,14 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.VMInstanceDao;
-import net.sf.ehcache.config.InvalidConfigurationException;
-import org.apache.cloudstack.NsxAnswer;
-import org.apache.cloudstack.StartupNsxCommand;
+import com.google.gson.Gson;
+import org.apache.cloudstack.StartupNetrisCommand;
import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
-import org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
-import org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
-import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
-import org.apache.cloudstack.resource.NsxLoadBalancerMember;
-import org.apache.cloudstack.resource.NsxNetworkRule;
-import org.apache.cloudstack.resource.NsxOpObject;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
+import com.cloud.network.netris.NetrisNetworkRule;
import org.apache.cloudstack.resourcedetail.FirewallRuleDetailVO;
import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
@@ -126,56 +113,54 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.LongFunction;
-import java.util.stream.Collectors;
@Component
-public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
+public class NetrisElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
- LoadBalancingServiceProvider, FirewallServiceProvider, InternalLoadBalancerElementService, ResourceStateAdapter, Listener {
+ LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
-
- @Inject
- AccountManager accountMgr;
- @Inject
- NsxServiceImpl nsxService;
@Inject
- DataCenterDao dataCenterDao;
- @Inject
- NetworkDao networkDao;
+ NetworkModel networkModel;
@Inject
AgentManager agentManager;
@Inject
ResourceManager resourceManager;
@Inject
- PhysicalNetworkDao physicalNetworkDao;
+ private NetrisService netrisService;
@Inject
- NetworkModel networkModel;
+ private AccountManager accountManager;
@Inject
- DomainDao domainDao;
+ private DataCenterDao dataCenterDao;
@Inject
- protected VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
+ private NetworkDao networkDao;
@Inject
- IPAddressDao ipAddressDao;
+ private DomainDao domainDao;
@Inject
- VMInstanceDao vmInstanceDao;
+ private VpcDao vpcDao;
@Inject
- VpcDao vpcDao;
+ private FirewallRuleDetailsDao firewallRuleDetailsDao;
@Inject
- LoadBalancerVMMapDao lbVmMapDao;
+ private IPAddressDao ipAddressDao;
@Inject
- VirtualRouterProviderDao vrProviderDao;
+ private VMInstanceDao vmInstanceDao;
@Inject
- PhysicalNetworkServiceProviderDao pNtwkSvcProviderDao;
- @Inject
- FirewallRuleDetailsDao firewallRuleDetailsDao;
+ LoadBalancerVMMapDao lbVmMapDao;
protected Logger logger = LogManager.getLogger(getClass());
private final Map<Network.Service, Map<Network.Capability, String>> capabilities = initCapabilities();
+ protected static List<AutoScaleCounter> getNetrisAutoScaleCounters() {
+ AutoScaleCounter counter;
+ final List<AutoScaleCounter> counterList = new ArrayList<>();
+ counter = new AutoScaleCounter(AutoScaleCounter.AutoScaleCounterType.Cpu);
+ counterList.add(counter);
+ counter = new AutoScaleCounter(AutoScaleCounter.AutoScaleCounterType.Memory);
+ counterList.add(counter);
+ return counterList;
+ }
- private static Map<Network.Service, Map<Network.Capability, String>> initCapabilities() {
+ protected static Map<Network.Service, Map<Network.Capability, String>> initCapabilities() {
Map<Network.Service, Map<Network.Capability, String>> capabilities = new HashMap<>();
Map<Network.Capability, String> dhcpCapabilities = Map.of(Network.Capability.DhcpAccrossMultipleSubnets, "true");
@@ -194,6 +179,10 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
lbCapabilities.put(Network.Capability.SupportedProtocols, "tcp, udp");
lbCapabilities.put(Network.Capability.SupportedStickinessMethods, VirtualRouterElement.getHAProxyStickinessCapability());
lbCapabilities.put(Network.Capability.LbSchemes, String.join(",", LoadBalancerContainer.Scheme.Internal.name(), LoadBalancerContainer.Scheme.Public.name()));
+ final Gson gson = new Gson();
+ final String autoScaleCounterList = gson.toJson(getNetrisAutoScaleCounters());
+ lbCapabilities.put(Network.Capability.AutoScaleCounters, autoScaleCounterList);
+ lbCapabilities.put(Network.Capability.VmAutoScaling, "true");
capabilities.put(Network.Service.Lb, lbCapabilities);
capabilities.put(Network.Service.PortForwarding, null);
@@ -210,9 +199,78 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
+ capabilities.put(Network.Service.Gateway, null);
capabilities.put(Network.Service.SourceNat, sourceNatCapabilities);
return capabilities;
}
+
+ @Override
+ public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+ return false;
+ }
+
+ @Override
+ public boolean processCommands(long agentId, long seq, Command[] commands) {
+ return false;
+ }
+
+ @Override
+ public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
+ return null;
+ }
+
+ @Override
+ public void processHostAdded(long hostId) {
+ // Do nothing
+ }
+
+ @Override
+ public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
+ // Do nothing
+ }
+
+ @Override
+ public boolean processDisconnect(long agentId, Status state) {
+ return false;
+ }
+
+ @Override
+ public void processHostAboutToBeRemoved(long hostId) {
+ // Do nothing
+ }
+
+ @Override
+ public void processHostRemoved(long hostId, long clusterId) {
+ // Do nothing
+ }
+
+ @Override
+ public boolean isRecurring() {
+ return false;
+ }
+
+ @Override
+ public int getTimeout() {
+ return 0;
+ }
+
+ @Override
+ public boolean processTimeout(long agentId, long seq) {
+ return false;
+ }
+
+ protected boolean canHandle(Network network, Network.Service service) {
+ logger.debug("Checking if Netris Element can handle service " + service.getName() + " on network "
+ + network.getDisplayText());
+
+ if (!networkModel.isProviderForNetwork(getProvider(), network.getId())) {
+ logger.debug("Netris Element is not a provider for network " + network.getDisplayText());
+ return false;
+ }
+
+ return true;
+ }
+
@Override
public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
return true;
@@ -265,12 +323,18 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
@Override
public Network.Provider getProvider() {
- return Network.Provider.Nsx;
+ return Network.Provider.Netris;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ agentManager.registerForHostEvents(this, true, true, true);
+ resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return true;
}
@Override
public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- // TODO: Check if the network is NSX based (was already implemented as part of the guru.setup()
return true;
}
@@ -284,6 +348,11 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
return false;
}
+ @Override
+ public boolean releaseIp(IpAddress ipAddress) {
+ return netrisService.releaseNatIp(ipAddress.getDataCenterId(), ipAddress.getAddress().addr());
+ }
+
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return canHandle(network, Network.Service.Connectivity);
@@ -291,7 +360,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
@Override
public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
- Account account = accountMgr.getAccount(network.getAccountId());
+ Account account = accountManager.getAccount(network.getAccountId());
NetworkVO networkVO = networkDao.findById(network.getId());
DataCenterVO zone = dataCenterDao.findById(network.getDataCenterId());
DomainVO domain = domainDao.findById(account.getDomainId());
@@ -300,7 +369,16 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
logger.error(msg);
throw new CloudRuntimeException(msg);
}
- return nsxService.deleteNetwork(zone.getId(), account.getId(), domain.getId(), networkVO);
+ String vpcName = null;
+ Long vpcId = network.getVpcId();
+ if (Objects.nonNull(vpcId)) {
+ VpcVO vpc = vpcDao.findById(vpcId);
+ if (Objects.nonNull(vpc)) {
+ vpcName = vpc.getName();
+ }
+ }
+ netrisService.deleteVnetResource(zone.getId(), account.getId(), domain.getId(), vpcName, vpcId, networkVO.getName(), network.getId(), network.getCidr());
+ return true;
}
@Override
@@ -323,23 +401,6 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
return true;
}
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- agentManager.registerForHostEvents(this, true, true, true);
- resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
- return true;
- }
-
- @Override
- public boolean start() {
- return false;
- }
-
- @Override
- public boolean stop() {
- return false;
- }
-
@Override
public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
return null;
@@ -347,7 +408,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
@Override
public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
- if (!(startup[0] instanceof StartupNsxCommand)) {
+ if (!(startup[0] instanceof StartupNetrisCommand)) {
return null;
}
host.setType(Host.Type.L2Networking);
@@ -359,164 +420,263 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
return null;
}
- private DomainVO getDomainFromAccount(Account account) {
- DomainVO domain = domainDao.findById(account.getDomainId());
- if (Objects.isNull(domain)) {
- String msg = String.format("Unable to find domain with id: %s", account.getDomainId());
- logger.error(msg);
- throw new CloudRuntimeException(msg);
- }
- return domain;
- }
-
@Override
public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- DataCenterVO zone = zoneFunction.apply(vpc.getZoneId());
- Pair<Boolean, Account> isNsxAndAccount = validateVpcConfigurationAndGetAccount(zone, vpc);
- if (Boolean.FALSE.equals(isNsxAndAccount.first())) {
- return true;
- }
- if (Boolean.TRUE.equals(isNsxAndAccount.first()) && Objects.isNull(isNsxAndAccount.second())) {
- throw new InvalidParameterValueException(String.format("Failed to find account with id %s", vpc.getAccountId()));
- }
return true;
}
@Override
- public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException {
- DataCenterVO zone = zoneFunction.apply(vpc.getZoneId());
- Pair<Boolean, Account> isNsxAndAccount = validateVpcConfigurationAndGetAccount(zone, vpc);
- if (Boolean.FALSE.equals(isNsxAndAccount.first())) {
- return true;
- }
- if (Boolean.TRUE.equals(isNsxAndAccount.first()) && Objects.isNull(isNsxAndAccount.second())) {
- throw new InvalidParameterValueException(String.format("Failed to find account with id %s", vpc.getAccountId()));
- }
- Account account = isNsxAndAccount.second();
- DomainVO domain = getDomainFromAccount(account);
- return nsxService.deleteVpcNetwork(vpc.getZoneId(), account.getId(), domain.getId(), vpc.getId(), vpc.getName());
- }
-
- private Pair<Boolean, Account> validateVpcConfigurationAndGetAccount(DataCenterVO zone, Vpc vpc) {
- if (Objects.isNull(zone)) {
- throw new InvalidParameterValueException(String.format("Failed to find zone with id %s", vpc.getZoneId()));
- }
- Account account = null;
- boolean forNsx = false;
- List<PhysicalNetworkVO> physicalNetworks = physicalNetworkDao.listByZoneAndTrafficType(zone.getId(), Networks.TrafficType.Guest);
- if (CollectionUtils.isNullOrEmpty(physicalNetworks)) {
- String err = String.format("Desired physical network is not present in the zone %s for traffic type %s. ", zone.getName(), Networks.TrafficType.Guest.name());
- logger.error(err);
- throw new InvalidConfigurationException(err);
- }
- List<PhysicalNetworkVO> filteredPhysicalNetworks = physicalNetworks.stream().filter(x -> x.getIsolationMethods().contains("NSX")).collect(Collectors.toList());
- if (CollectionUtils.isNullOrEmpty(filteredPhysicalNetworks)) {
- String err = String.format("No physical network with NSX isolation type for traffic type %s is present in the zone %s.", Networks.TrafficType.Guest.name(), zone.getName());
- logger.error(err);
- throw new InvalidConfigurationException(err);
- }
- if (filteredPhysicalNetworks.get(0).getIsolationMethods().contains("NSX")) {
- account = accountMgr.getAccount(vpc.getAccountId());
- forNsx = true;
- }
- return new Pair<>(forNsx, account);
+ public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+ long zoneId = vpc.getZoneId();
+ long accountId = vpc.getAccountId();
+ long domainId = vpc.getDomainId();
+ return netrisService.deleteVpcResource(zoneId, accountId, domainId, vpc);
}
@Override
public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException {
- return false;
+ return true;
}
@Override
public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException {
- return false;
+ return true;
}
@Override
public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
- return false;
+ List<StaticRoute> existingStaticRoutes = netrisService.listStaticRoutes(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, null, null, null);
+ List<String> staticRouteCidrs = new ArrayList<>();
+ for(StaticRouteProfile staticRoute : routes) {
+ if (StaticRoute.State.Add == staticRoute.getState()) {
+ netrisService.addOrUpdateStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId(), false);
+ } else if (StaticRoute.State.Revoke == staticRoute.getState()) {
+ netrisService.deleteStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId());
+ } else if (StaticRoute.State.Update == staticRoute.getState()) {
+ netrisService.addOrUpdateStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), staticRoute.getGateway(), staticRoute.getId(), true);
+ }
+ staticRouteCidrs.add(staticRoute.getCidr());
+ }
+ for (StaticRoute staticRoute : existingStaticRoutes) {
+ if (!staticRouteCidrs.contains(staticRoute.getCidr())) {
+ logger.info("Revoking static route with cidr {} which are not used by VPC {}", staticRoute.getCidr(), vpc);
+ netrisService.deleteStaticRoute(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getName(), vpc.getId(), true, staticRoute.getCidr(), null, staticRoute.getId());
+ }
+ }
+ return true;
}
@Override
public boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
- return false;
+ return true;
}
@Override
- public boolean processAnswers(long agentId, long seq, Answer[] answers) {
- return false;
+ public boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address) {
+ return netrisService.updateVpcSourceNatIp(vpc, address);
}
@Override
- public boolean processCommands(long agentId, long seq, Command[] commands) {
- return false;
+ public boolean updateVpc(Vpc vpc, String previousVpcName) {
+ return netrisService.updateVpcResource(vpc.getZoneId(), vpc.getAccountId(), vpc.getDomainId(), vpc.getId(), vpc.getName(), previousVpcName);
}
@Override
- public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
- return null;
- }
+ public boolean applyNetworkACLs(Network network, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
+ if (!canHandle(network, Network.Service.NetworkACL)) {
+ return false;
+ }
- @Override
- public void processHostAdded(long hostId) {
- // Do nothing
+ List<NetrisNetworkRule> nsxDelNetworkRules = new ArrayList<>();
+ boolean success = true;
+ for (NetworkACLItem rule : rules) {
+ String privatePort = PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule);
+ NetrisNetworkRule networkRule = getNetrisNetworkRuleForAcl(rule, privatePort);
+ if (Arrays.asList(NetworkACLItem.State.Active, NetworkACLItem.State.Add).contains(rule.getState())) {
+ success = success && netrisService.addFirewallRules(network, List.of(networkRule));
+ } else if (NetworkACLItem.State.Revoke == rule.getState()) {
+ nsxDelNetworkRules.add(networkRule);
+ }
+ }
+
+ if (!nsxDelNetworkRules.isEmpty()) {
+ success = netrisService.deleteFirewallRules(network, nsxDelNetworkRules);
+ if (!success) {
+ logger.warn("Not all firewall rules were successfully deleted");
+ }
+ }
+ return success;
}
- @Override
- public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
- // Do nothing
+ private NetrisNetworkRule getNetrisNetworkRuleForAcl(NetworkACLItem rule, String privatePort) {
+ SDNProviderNetworkRule baseNetworkRule = new SDNProviderNetworkRule.Builder()
+ .setRuleId(rule.getId())
+ .setSourceCidrList(!CollectionUtils.isNullOrEmpty(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
+ .setTrafficType(rule.getTrafficType().toString())
+ .setProtocol(rule.getProtocol().toUpperCase())
+ .setPublicPort(String.valueOf(rule.getSourcePortStart()))
+ .setPrivatePort(String.valueOf(privatePort))
+ .setIcmpCode(rule.getIcmpCode())
+ .setIcmpType(rule.getIcmpType())
+ .setService(Network.Service.NetworkACL)
+ .build();
+ return new NetrisNetworkRule.Builder()
+ .baseRule(baseNetworkRule)
+ .aclAction(transformActionValue(rule.getAction()))
+ .reason(rule.getReason())
+ .build();
}
- @Override
- public boolean processDisconnect(long agentId, Status state) {
- return false;
+ protected List<String> transformCidrListValues(List<String> sourceCidrList) {
+ List<String> list = new ArrayList<>();
+ if (org.apache.commons.collections.CollectionUtils.isNotEmpty(sourceCidrList)) {
+ for (String cidr : sourceCidrList) {
+ if (cidr.equals("0.0.0.0/0")) {
+ list.add("ANY");
+ } else {
+ list.add(cidr);
+ }
+ }
+ }
+ return list;
}
- @Override
- public void processHostAboutToBeRemoved(long hostId) {
- // Do nothing
+ protected NetrisNetworkRule.NetrisRuleAction transformActionValue(NetworkACLItem.Action action) {
+ if (action == NetworkACLItem.Action.Allow) {
+ return NetrisNetworkRule.NetrisRuleAction.PERMIT;
+ } else if (action == NetworkACLItem.Action.Deny) {
+ return NetrisNetworkRule.NetrisRuleAction.DENY;
+ }
+ String err = String.format("Unsupported action %s", action.toString());
+ logger.error(err);
+ throw new CloudRuntimeException(err);
}
@Override
- public void processHostRemoved(long hostId, long clusterId) {
- // Do nothing
+ public boolean reorderAclRules(Vpc vpc, List<? extends Network> networks, List<? extends NetworkACLItem> networkACLItems) {
+ List<NetrisNetworkRule> aclRulesList = new ArrayList<>();
+ for (NetworkACLItem rule : networkACLItems) {
+ String privatePort = PortForwardingServiceProvider.getPrivatePortRangeForACLRule(rule);
+ aclRulesList.add(getNetrisNetworkRuleForAcl(rule, privatePort));
+ }
+ for (Network network: networks) {
+ netrisService.deleteFirewallRules(network, aclRulesList);
+ }
+ boolean success = true;
+ for (Network network : networks) {
+ for (NetrisNetworkRule aclRule : aclRulesList) {
+ success = success && netrisService.addFirewallRules(network, List.of(aclRule));
+ }
+ }
+ return success;
}
@Override
- public boolean isRecurring() {
- return false;
+ public IpDeployer getIpDeployer(Network network) {
+ return this;
}
@Override
- public int getTimeout() {
- return 0;
+ public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException {
+ if (!canHandle(network, Network.Service.PortForwarding)) {
+ return false;
+ }
+ return applyPFRulesInternal(network, rules);
}
- @Override
- public boolean processTimeout(long agentId, long seq) {
- return false;
+ private boolean addOrRemovePFRuleOnNetris(UserVm vm, PortForwardingRule rule, NetrisNetworkRule networkRule, SDNProviderOpObject netrisObject, boolean create) {
+ logger.debug("{} port forwarding rule on Netris for VM {} to ports {} - {}",
+ create ? "Creating" : "Deleting", vm.getUuid(), rule.getDestinationPortStart(), rule.getDestinationPortEnd());
+ Long vpcId = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getId() : null;
+ String vpcName = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getName() : null;
+ Long networkId = netrisObject.getNetworkVO() != null ? netrisObject.getNetworkVO().getId() : null;
+ String networkName = netrisObject.getNetworkVO() != null ? netrisObject.getNetworkVO().getName() : null;
+ String vpcCidr = netrisObject.getVpcVO() != null ? netrisObject.getVpcVO().getCidr() : null;
+ SDNProviderNetworkRule baseNetRule = networkRule.getBaseRule();
+ return create ?
+ netrisService.createPortForwardingRule(baseNetRule.getZoneId(), baseNetRule.getAccountId(), baseNetRule.getDomainId(),
+ vpcName, vpcId, networkName, networkId, netrisObject.isVpcResource(), vpcCidr, baseNetRule) :
+ netrisService.deletePortForwardingRule(baseNetRule.getZoneId(), baseNetRule.getAccountId(), baseNetRule.getDomainId(),
+ vpcName, vpcId, networkName, networkId, netrisObject.isVpcResource(), vpcCidr, baseNetRule);
}
- protected boolean canHandle(Network network, Network.Service service) {
- logger.debug("Checking if Nsx Element can handle service " + service.getName() + " on network "
- + network.getDisplayText());
+ private boolean applyPFRulesInternal(Network network, List<PortForwardingRule> rules) {
+ return Transaction.execute((TransactionCallback<Boolean>) status -> {
+ boolean result = true;
+ for (PortForwardingRule rule : rules) {
+ IPAddressVO publicIp = ApiDBUtils.findIpAddressById(rule.getSourceIpAddressId());
+ UserVm vm = ApiDBUtils.findUserVmById(rule.getVirtualMachineId());
+ if (vm == null && rule.getState() != FirewallRule.State.Revoke) {
+ continue;
+ }
+ SDNProviderOpObject netrisObject = getNetrisOpObject(network);
+ String publicPort = PortForwardingServiceProvider.getPublicPortRange(rule);
+ String privatePort = PortForwardingServiceProvider.getPrivatePFPortRange(rule);
+ FirewallRuleDetailVO ruleDetail = firewallRuleDetailsDao.findDetail(rule.getId(), ApiConstants.NETRIS_DETAIL_KEY);
+
+ SDNProviderNetworkRule baseNetworkRule = new SDNProviderNetworkRule.Builder()
+ .setDomainId(netrisObject.getDomainId())
+ .setAccountId(netrisObject.getAccountId())
+ .setZoneId(netrisObject.getZoneId())
+ .setNetworkResourceId(netrisObject.getNetworkResourceId())
+ .setNetworkResourceName(netrisObject.getNetworkResourceName())
+ .setVpcResource(netrisObject.isVpcResource())
+ .setVmId(Objects.nonNull(vm) ? vm.getId() : 0)
+ .setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null)
+ .setPublicIp(publicIp.getAddress().addr())
+ .setPrivatePort(privatePort)
+ .setPublicPort(publicPort)
+ .setRuleId(rule.getId())
+ .setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
+ .build();
- if (!networkModel.isProviderForNetwork(getProvider(), network.getId())) {
- logger.debug("Nsx Element is not a provider for network " + network.getDisplayText());
- return false;
- }
+ NetrisNetworkRule networkRule = new NetrisNetworkRule.Builder().baseRule(baseNetworkRule).build();
- return true;
+ if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) {
+ boolean pfRuleResult = addOrRemovePFRuleOnNetris(vm, rule, networkRule, netrisObject, true);
+ if (pfRuleResult) {
+ logger.debug("Port forwarding rule {} created on Netris, adding detail on firewall rules details", rule.getId());
+ if (ruleDetail == null && FirewallRule.State.Add == rule.getState()) {
+ logger.debug("Adding new firewall detail for rule {}", rule.getId());
+ firewallRuleDetailsDao.addDetail(rule.getId(), ApiConstants.NETRIS_DETAIL_KEY, "true", false);
+ } else if (ruleDetail != null) {
+ logger.debug("Updating firewall detail for rule {}", rule.getId());
+ ruleDetail.setValue("true");
+ firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
+ }
+ }
+ result &= pfRuleResult;
+ } else if (rule.getState() == FirewallRule.State.Revoke) {
+ boolean pfRuleResult = addOrRemovePFRuleOnNetris(vm, rule, networkRule, netrisObject, false);
+ if (pfRuleResult && ruleDetail != null) {
+ logger.debug("Updating firewall rule detail {} for rule {}, set to false", ruleDetail.getId(), rule.getId());
+ ruleDetail.setValue("false");
+ firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
+ }
+ result &= pfRuleResult;
+ }
+ }
+ return result;
+ });
}
- private final LongFunction<DataCenterVO> zoneFunction = zoneId -> dataCenterDao.findById(zoneId);
+ private SDNProviderOpObject getNetrisOpObject(Network network) {
+ Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(network.getVpcId(), network.getId());
+ VpcVO vpc = vpcOrNetwork.first();
+ NetworkVO networkVO = vpcOrNetwork.second();
+ long domainId = getResourceId("domain", vpc, networkVO);
+ long accountId = getResourceId("account", vpc, networkVO);
+ long zoneId = getResourceId("zone", vpc, networkVO);
- @Override
- public IpDeployer getIpDeployer(Network network) {
- return this;
+ return new SDNProviderOpObject.Builder()
+ .vpcVO(vpc)
+ .networkVO(networkVO)
+ .domainId(domainId)
+ .accountId(accountId)
+ .zoneId(zoneId)
+ .build();
}
- @Override
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
for(StaticNat staticNat : rules) {
long sourceIpAddressId = staticNat.getSourceIpAddressId();
@@ -526,6 +686,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
if (vm == null || networkModel.getNicInNetworkIncludingRemoved(vm.getId(), config.getId()) == null) {
continue;
}
+ long vmId = vm.getId();
Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(config.getVpcId(), config.getId());
VpcVO vpc = vpcOrNetwork.first();
NetworkVO network = vpcOrNetwork.second();
@@ -533,90 +694,17 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
String networkResourceName = Objects.nonNull(vpc) ? vpc.getName() : network.getName();
boolean isVpcResource = Objects.nonNull(vpc);
if (!staticNat.isForRevoke()) {
- return nsxService.createStaticNatRule(config.getDataCenterId(), config.getDomainId(), config.getAccountId(),
- networkResourceId, networkResourceName, isVpcResource, vm.getId(),
- ipAddressVO.getAddress().addr(), staticNat.getDestIpAddress());
+ return netrisService.createStaticNatRule(config.getDataCenterId(), config.getAccountId(), config.getDomainId(),
+ networkResourceName, networkResourceId, isVpcResource, vpc.getCidr(),
+ ipAddressVO.getAddress().addr(), staticNat.getDestIpAddress(), vmId);
} else {
- return nsxService.deleteStaticNatRule(config.getDataCenterId(), config.getDomainId(), config.getAccountId(),
- networkResourceId, networkResourceName, isVpcResource);
+ return netrisService.deleteStaticNatRule(config.getDataCenterId(), config.getAccountId(), config.getDomainId(),
+ networkResourceName, networkResourceId, isVpcResource, ipAddressVO.getAddress().addr(), vmId);
}
}
return false;
}
- protected synchronized boolean applyPFRulesInternal(Network network, List<PortForwardingRule> rules) {
- return Transaction.execute((TransactionCallback<Boolean>) status -> {
- boolean result = true;
- for (PortForwardingRule rule : rules) {
- IPAddressVO publicIp = ApiDBUtils.findIpAddressById(rule.getSourceIpAddressId());
- UserVm vm = ApiDBUtils.findUserVmById(rule.getVirtualMachineId());
- if (vm == null && rule.getState() != FirewallRule.State.Revoke) {
- continue;
- }
- NsxOpObject nsxObject = getNsxOpObject(network);
- String publicPort = getPublicPortRange(rule);
-
- String privatePort = getPrivatePFPortRange(rule);
-
- NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
- .setDomainId(nsxObject.getDomainId())
- .setAccountId(nsxObject.getAccountId())
- .setZoneId(nsxObject.getZoneId())
- .setNetworkResourceId(nsxObject.getNetworkResourceId())
- .setNetworkResourceName(nsxObject.getNetworkResourceName())
- .setVpcResource(nsxObject.isVpcResource())
- .setVmId(Objects.nonNull(vm) ? vm.getId() : 0)
- .setVmIp(Objects.nonNull(vm) ? vm.getPrivateIpAddress() : null)
- .setPublicIp(publicIp.getAddress().addr())
- .setPrivatePort(privatePort)
- .setPublicPort(publicPort)
- .setRuleId(rule.getId())
- .setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
- .build();
- FirewallRuleDetailVO ruleDetail = firewallRuleDetailsDao.findDetail(rule.getId(), ApiConstants.FOR_NSX);
- if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(rule.getState())) {
- if ((ruleDetail == null && FirewallRule.State.Add == rule.getState()) || (ruleDetail != null && !ruleDetail.getValue().equalsIgnoreCase("true"))) {
- logger.debug("Creating port forwarding rule on NSX for VM {} to ports {} - {}",
- vm.getUuid(), rule.getDestinationPortStart(), rule.getDestinationPortEnd());
- NsxAnswer answer = nsxService.createPortForwardRule(networkRule);
- boolean pfRuleResult = answer.getResult();
- if (pfRuleResult && !answer.isObjectExistent()) {
- logger.debug("Port forwarding rule {} created on NSX, adding detail on firewall rules details", rule.getId());
- if (ruleDetail == null && FirewallRule.State.Add == rule.getState()) {
- logger.debug("Adding new firewall detail for rule {}", rule.getId());
- firewallRuleDetailsDao.addDetail(rule.getId(), ApiConstants.FOR_NSX, "true", false);
- } else {
- logger.debug("Updating firewall detail for rule {}", rule.getId());
- ruleDetail.setValue("true");
- firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
- }
- }
- result &= pfRuleResult;
- }
- } else if (rule.getState() == FirewallRule.State.Revoke) {
- if (ruleDetail == null || (ruleDetail != null && ruleDetail.getValue().equalsIgnoreCase("true"))) {
- boolean pfRuleResult = nsxService.deletePortForwardRule(networkRule);
- if (pfRuleResult && ruleDetail != null) {
- logger.debug("Updating firewall rule detail {} for rule {}, set to false", ruleDetail.getId(), rule.getId());
- ruleDetail.setValue("false");
- firewallRuleDetailsDao.update(ruleDetail.getId(), ruleDetail);
- }
- result &= pfRuleResult;
- }
- }
- }
- return result;
- });
- }
-
- @Override
- public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException {
- if (!canHandle(network, Network.Service.PortForwarding)) {
- return false;
- }
- return applyPFRulesInternal(network, rules);
- }
-
public Pair<VpcVO, NetworkVO> getVpcOrNetwork(Long vpcId, long networkId) {
VpcVO vpc = null;
NetworkVO network = null;
@@ -634,30 +722,6 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
return new Pair<>(vpc, network);
}
- private static String getPublicPortRange(PortForwardingRule rule) {
- return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
- String.valueOf(rule.getSourcePortStart()) :
- String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
- }
-
- private static String getPrivatePFPortRange(PortForwardingRule rule) {
- return rule.getDestinationPortStart() == rule.getDestinationPortEnd() ?
- String.valueOf(rule.getDestinationPortStart()) :
- String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
- }
... 10598 lines suppressed ...