FR03: NSX Integration (#1)

* NSX integration - skeletal code

* Fix module not loading on startup

* add upgrade path and daos
\n add nsx controller command

* add support for adding and listing nsx provider to a zone

* add license

* add default VPC offering and update upgrade path

* add global setting to enable nsx plugin

* add delete nsx controller operation

* add nsxresource

* add NSX resource , api client, create tier1 gw

* update db

* update response and add license

* Add support to create and delete nsx tier-1 gateway

* add license

* cleanup and add skeletal code for network creation

* add create/delete segment and UI integration

* add license

* address code smells - part 1

* fix test / build failure

* NSX integration - skeletal code

* Fix module not loading on startup

* add upgrade path and daos
\n add nsx controller command

* add support for adding and listing nsx provider to a zone

* add license

* add default VPC offering and update upgrade path

* add global setting to enable nsx plugin

* add delete nsx controller operation

* add nsxresource

* add NSX resource , api client, create tier1 gw

* update db

* update response and add license

* Add support to create and delete nsx tier-1 gateway

* add license

* cleanup and add skeletal code for network creation

* add create/delete segment and UI integration

* add license

* address code smells - part 1

* fix test / build failure

* add ui changes + update nsx_provider table transport zones + use NSX broadcast domain for add nics to router

* ui: fix password field, and backend changes

* add route advertisement

* update offering

* update offering

* add sleep before deletion of vpc / tier g/w for ports to be removed

* move creation of segments to design phase

* change provider to VPC router for Dhcp & dns service in an nsx offering

* Add public nic for NSX

* reserve first IP (after g/w) of subnet for router nic - NSX

* revert reserving 1st IP in vpc segments

* [NSX] Create a DHCP relay and add it to a VPC tier segment (#107)

* Create DHCP relay command and execute request

* In progress integrate with networking

* Create DHCP relay config on the network VR allocation

* Revert domain router dao changes

* Create DHCP relay con VR nic plug to NSX network

* Link DHCP relay config to segment after creation

* [NSX] Cleanup DHCP Relay config on segment deletion (#108)

* Cleanup DHCP Relay config on segment deletion

* update segment & relay name generators and call delete dhcprelay after deletion of segment

* address comment

* [NSX] Fix DHCP relay config deletion was missing zone name (#8068)

* [NSX] Refactor API wrapper operations (#8059)

* [NSX] Refactor API wrapper operations

* Big refactor

* Address review comment

* change network cidr to cidr to prevent NPE

* add domain and zone names to the various networks - vpc & tier

---------

Co-authored-by: Pearl Dsilva <pearl1594@gmail.com>

* Nsx unit tests (#8090)

* Add tests

* add test for NsxGuestNetworkGuru

* add unit tests for NsxResource

* add unti tests for NsxElement

* cleanup

* [NSX] Refactor API wrapper operations

* update tests

* update tests - add nsxProviderServiceImpl test

* add unit test - NsxServiceImpl

* add license

* Big refactor

* Address review comment

* change network cidr to cidr to prevent NPE

* add domain and zone names to the various networks - vpc & tier

* fix tests

---------

Co-authored-by: nvazquez <nicovazquez90@gmail.com>

* modify NSX resource naming convention (#8095)

* modify NSX resource naming convention

* remove unused imports

* add a setup phase between desgin and implementation of a network for intermediary steps

* add method to all classes

* NSX: Refactor Network & VPC offering (#8110)

* [NSX] Refactor API wrapper operations

* Network offering changes for NSX

* fix services and provider combination

* address comments: rename param

* update nsx_mode parameter

---------

Co-authored-by: nvazquez <nicovazquez90@gmail.com>

* fix test

* [NSX] Allow NSX isolated networks (#8132)

* Add network offerings for NSX on isolated networks

* Fix offerings creation

* In progress NSX isolated network

* Fixes

* Fix NIC allocation to router

* NSX: Add Step for Adding Public traffic network for NSX During zone creation (#8126)

* NSX: Add Step for Adding Public traffic network for NSX

* address comments and cleanup

* address comment

* remove indent

* NSX: Create and Delete static NAT & Port forward  rules (#8131)

* NSX: Create and delete NSX Static Nat rules

* fix issues with static nat

* add static nat

* Support to add and delete Port forward rules

* add license

* fix adding multiple pf rules

* cleanup

* fix lint check

* fix smoke tests

* fix smoke tests

* Nsx add lb rule (#8161)

* NSX: Create and delete NSX Static Nat rules

* fix issues with static nat

* add static nat

* Support to add and delete Port forward rules

* add license

* fix adding multiple pf rules

* cleanup

* NSX: Add support to create and delete Load balancer rules

* fix deletion of lb rules

* add header file and update protocol detail

* build failure fix

* [NSX] Add SNAT support (#8100)

* In progress add source NAT

* Fix after merge

* Fix tests

* Fix NPE on isolated network deletion

* Reserve source NAT IP when its not passed for NSX VPC

* Create source NAT rule on VR NIC allocation

* Fix update VPC and remove VPC to update and remove SNAT rule

* Fix packaging

* Address review comment

* Fix build

* fix build - unused import

* Add defensive checks

* Add missing design to NSX public guru

---------

Co-authored-by: Pearl Dsilva <pearl1594@gmail.com>

* NSX: Fix VR public NIC allocation (#8166)

* NSX: fix LB member addition and deletion and add defensive checks (#8167)

* Fix public NIC NPE on broadcast URI

* NSX: Router Public nic to get IP from systemVM Ip range (#8172)

* NSX: Router Public nic to get IP from systemVM Ip range

* Fix VR IP address and setSourceNatIp command

* NSX: hide systemVM reserved IP range SourceNAT

* fix test

---------

Co-authored-by: nvazquez <nicovazquez90@gmail.com>

* fix test failure

* test failure fix

* [NSX] Fix update source NAT IP (#8176)

* [NSX] Fix update source NAT IP

* Fix startup

* Fix API result

* NSX - add LB route Advertizement (#8192)

* [NSX] Add ACL types support (#8224)

* NSX: Create segment group on segment creation

* Add unit tests

* Remove group for segment before removing segment

* Create Distributed Firewall rules

* Remove distributed firewall policy on segment deletion

* Fix policy rule ID and add more unit tests

* Fix DROP action rules and transform tests

* Add new ACL rules

* Fixes

* associate security policies with groups and not to DFW and add deletion of rules

* Fix name convention

---------

Co-authored-by: Pearl Dsilva <pearl1594@gmail.com>

* NSX: Fix creation of VPCs (#8320)

* Fix ACL rules creation (#8323)

* [NSX] Fix database views (#8325)

* NSX: Add CKS Support & Firewall rules for Isolated Networks (#8189)

* NSX: Add ALL LB IP to the list of route advertisements in tier1

* NSX: Support Source NAT on NSX Isolated networks

* NSX: Cks Support

* NSX: Create segment group on segment creation

* Add unit tests

* Remove group for segment before removing segment

* Create Distributed Firewall rules

* Remove distributed firewall policy on segment deletion

* Fix policy rule ID and add more unit tests

* Add support for routed NSX Isolated networks \n and non RFC 1918 compliant IPs

* Add support for routed NSX Isolated networks \n and non RFC 1918 compliant IPs

* Add Firewall rules

* build failure - fix unit test

* fix npes

* Add support to delete firewall rules

* update nsx cks offering

* add license

* update order of ports in PF & FW rules

* fix filter for getting transport zones

* CKS support changed - MTU updated, etc

* add LB for CKS on VPC

* address comments

* adapt upstream cks logic for vpc

* rever mtu hack

* update UI changes as per upstream fix

* change display test for CKS n/w offerings for isolated and VPC tiers

* add extra line for linter

* address comment

* revert list change

---------

Co-authored-by: nvazquez <nicovazquez90@gmail.com>

* fix ui build failure

* [NSX] Address SonarCloud Bugs (#8341)

* [NSX] Address SonarCloud Bugs

* Fix NSX API connection issues

* NSX: Add unit tests to increase coverage (#8355)

* NSX: Add unit tests

* cleanup unused imports

* add more unit tests

* add tests for publicnsxnetworkguru

* add license

* fix build failures

* address sonar comment

* fix security hotspots

* NSX: Add more unit tests (#8381)

* NSX : Unit tests

* remove unused imports

* remove unused import causing build failure

* fix build failures due to unused imports

* fix build failure

* fix test assertion

* remove unused imports

* remove unused import

* Nsx UI zone bug (#8398)

* NSX: Attempt to fix NSX Zone creation bug for public networks

* fix zone wizard public traffic issue

* add proper filtering of offerings based on VPC nsx mode

* clean up console logs

* NSX: Fix code smells and reported bugs (#8409)

* NSX: Fix code smells and reported bugs

* fox override issue

* remove unused imports

* fix test

* refactor code to reduce complexity

* add lisence

* cleanup

* fix build failure

* fix build failure

* address comments

* test - add config to ignore certain files from test coverage

* test exclusion of classes from test cov

* rever pom changes

* [NSX] Add more unit tests (#8431)

* [NSX] Add more unit tests

* More tests

* Fix build errors

* NSX: Prevent creation of L2 and Shared networks for NSX (#8463)

* NSX: Prevent creation of L2 and Shared networks for NSX

* add checks to backend to prevent creation of l2 and shared networks in nsx zones and filter only nsx offerings when creating isolated networks

* cleanup

* NSX: Fix code smells (#8436)

* NSX: Fix code smells

* Add changes to service creation logic

* CKS: Add action to during firewall rule creation (#8498)

* NSX,UI: Deduplicate network list when creating kubernetes clusters (#8513)

* NSX: Make LB service selectable in network offering (#8512)

* NSX: Make LB service selectable in network offering

* fix label

* address comments

* address comments

* NSX: Add appropriate error message when icmp type is set to -1 for NSX (#8504)

* NSX: Add appropriate error message when icmp type is set to -1 for NSX

* address comments

* update text

* fix test

* fix test - build failure

* fix test - build failure

* NSX: Cleanup NSX resources during k8s cluster cleanup (#8528)

* fix test failure

* NSX: Improve segment deletion process (#8538)

* NSX: Add passive monitor for NSX LB to test whether a server is available (#8533)

* NSX: Add passive monitor for NSX LB to test whether a server is available

* Add active monitors too

* fix build failure

* NSX: Add check for ICMP code / type for NSX zones (#8542)

* NSX: Fix Routed Mode for Isolated and VPC networks (#8534)

* NSX: Fix Routed Mode for Isolated and VPC networks

* NSX: Fix Routed mode - add checks for ports added for FW rules

* clean up code

* fix build failure

* NSX: Add retry logic with sleep to delete segments (#8554)

* NSX: Add retry logic with sleep to delete segments

* add logs

* Update pom XML for the NSX project

---------

Co-authored-by: Pearl Dsilva <pearl1594@gmail.com>
This commit is contained in:
Nicolas Vazquez 2024-01-24 12:24:15 -03:00 committed by GitHub
parent 43066e4020
commit 35357dc8f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
183 changed files with 10880 additions and 444 deletions

View File

@ -32,6 +32,9 @@ public class NicTO extends NetworkTO {
Map<NetworkOffering.Detail, String> details;
boolean dpdkEnabled;
Integer mtu;
Long networkId;
String networkSegmentName;
public NicTO() {
super();
@ -127,4 +130,20 @@ public class NicTO extends NetworkTO {
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
public Long getNetworkId() {
return networkId;
}
public void setNetworkId(Long networkId) {
this.networkId = networkId;
}
public String getNetworkSegmentName() {
return networkSegmentName;
}
public void setNetworkSegmentName(String networkSegmentName) {
this.networkSegmentName = networkSegmentName;
}
}

View File

@ -82,6 +82,7 @@ public class VirtualMachineTO {
Map<String, String> guestOsDetails = new HashMap<String, String>();
Map<String, String> extraConfig = new HashMap<>();
Map<Long, String> networkIdToNetworkNameMap = new HashMap<>();
DeployAsIsInfoTO deployAsIsInfo;
public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
@ -392,6 +393,14 @@ public class VirtualMachineTO {
return extraConfig;
}
public Map<Long, String> getNetworkIdToNetworkNameMap() {
return networkIdToNetworkNameMap;
}
public void setNetworkIdToNetworkNameMap(Map<Long, String> networkIdToNetworkNameMap) {
this.networkIdToNetworkNameMap = networkIdToNetworkNameMap;
}
public String getBootType() {
return bootType;
}

View File

@ -22,4 +22,5 @@ import org.apache.cloudstack.acl.ControlledEntity;
public interface KubernetesClusterHelper extends Adapter {
ControlledEntity findByUuid(String uuid);
ControlledEntity findByVmId(long vmId);
}

View File

@ -97,4 +97,6 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity,
void setRuleState(State ruleState);
boolean isForSystemVms();
}

View File

@ -205,6 +205,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
//Add Tungsten Fabric provider
public static final Provider Tungsten = new Provider("Tungsten", false);
public static final Provider Nsx = new Provider("Nsx", false);
private final String name;
private final boolean isExternal;
@ -427,6 +429,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
long getDataCenterId();
long getAccountId();
long getNetworkOfferingId();
@Override

View File

@ -19,6 +19,7 @@ package com.cloud.network;
import java.util.List;
import java.util.Map;
import com.cloud.dc.DataCenter;
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
@ -87,6 +88,8 @@ public interface NetworkService {
IpAddress reserveIpAddress(Account account, Boolean displayIp, Long ipAddressId) throws ResourceAllocationException;
IpAddress reserveIpAddressWithVlanDetail(Account account, DataCenter zone, Boolean displayIp, String vlanDetailKey) throws ResourceAllocationException;
boolean releaseReservedIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;
boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException;

View File

@ -128,7 +128,8 @@ public class Networks {
},
UnDecided(null, null),
OpenDaylight("opendaylight", String.class),
TUNGSTEN("tf", String.class);
TUNGSTEN("tf", String.class),
NSX("nsx", String.class);
private final String scheme;
private final Class<?> type;

View File

@ -79,20 +79,24 @@ public interface NetworkGuru extends Adapter {
* be used to make determination can be isolation methods, services
* provided on the guest network and the service provider that's on the
* guest network.
*
* <p>
* If a network is already fully substantiated with the necessary resources
* during this design phase, then the state should be set to Setup. If
* the resources are not allocated at this point, the state should be set
* to Allocated.
*
* @param offering network offering that contains the package of services
* the end user intends to use on that network.
* @param plan where is this network being deployed.
* @param offering network offering that contains the package of services
* the end user intends to use on that network.
* @param plan where is this network being deployed.
* @param userSpecified user specified parameters for this network.
* @param owner owner of this network.
* @param name
* @param vpcId
* @param owner owner of this network.
* @return Network
*/
Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner);
Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner);
void setup(Network network, long networkId);
/**
* For guest networks that are in Allocated state after the design stage,

View File

@ -0,0 +1,34 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.nsx;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface NsxProvider extends InternalIdentity, Identity {
String getHostname();
String getPort();
String getProviderName();
String getUsername();
long getZoneId();
String getTier0Gateway();
String getEdgeCluster();
String getTransportZone();
}

View File

@ -0,0 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.nsx;
import com.cloud.network.IpAddress;
import com.cloud.network.vpc.Vpc;
public interface NsxService {
boolean createVpcNetwork(Long zoneId, long accountId, long domainId, Long vpcId, String vpcName, boolean sourceNatEnabled);
boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address);
}

View File

@ -29,6 +29,8 @@ public interface VpcOffering extends InternalIdentity, Identity {
public static final String defaultVPCOfferingName = "Default VPC offering";
public static final String defaultVPCNSOfferingName = "Default VPC offering with Netscaler";
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";
/**
*
@ -53,6 +55,10 @@ public interface VpcOffering extends InternalIdentity, Identity {
*/
boolean isDefault();
boolean isForNsx();
String getNsxMode();
/**
* @return service offering id used by VPC virtual router
*/

View File

@ -36,7 +36,8 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
Map<String, List<String>> serviceProviders,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
Long serviceOfferingId, List<Long> domainIds, List<Long> zoneIds, VpcOffering.State state);
Long serviceOfferingId, Boolean forNsx, String mode,
List<Long> domainIds, List<Long> zoneIds, VpcOffering.State state);
Pair<List<? extends VpcOffering>,Integer> listVpcOfferings(ListVPCOfferingsCmd cmd);

View File

@ -43,6 +43,11 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RelatedNetworkOffering, domainid, zoneid, pvlanType, internetProtocol
}
public enum NsxMode {
NATTED,
ROUTED
}
public final static String SystemPublicNetwork = "System-Public-Network";
public final static String SystemControlNetwork = "System-Control-Network";
public final static String SystemManagementNetwork = "System-Management-Network";
@ -52,6 +57,10 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
public static final String DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE = "DefaultTungstenSharedNetworkOfferingWithSGService";
public static final String DEFAULT_NAT_NSX_OFFERING_FOR_VPC = "DefaultNATNSXNetworkOfferingForVpc";
public static final String DEFAULT_ROUTED_NSX_OFFERING_FOR_VPC = "DefaultRoutedNSXNetworkOfferingForVpc";
public static final String DEFAULT_NAT_NSX_OFFERING = "DefaultNATNSXNetworkOffering";
public static final String DEFAULT_ROUTED_NSX_OFFERING = "DefaultRoutedNSXNetworkOffering";
public final static String QuickCloudNoServices = "QuickCloudNoServices";
public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
@ -90,6 +99,10 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
boolean isForTungsten();
boolean isForNsx();
String getNsxMode();
TrafficType getTrafficType();
boolean isSpecifyVlan();

View File

@ -302,6 +302,8 @@ public class ApiConstants {
public static final String MIGRATIONS = "migrations";
public static final String MEMORY = "memory";
public static final String MODE = "mode";
public static final String NSX_MODE = "nsxmode";
public static final String NSX_ENABLED = "isnsxenabled";
public static final String NAME = "name";
public static final String METHOD_NAME = "methodname";
public static final String NETWORK_DOMAIN = "networkdomain";
@ -695,6 +697,12 @@ public class ApiConstants {
public static final String VSWITCH_TYPE_PUBLIC_TRAFFIC = "publicvswitchtype";
public static final String VSWITCH_NAME_GUEST_TRAFFIC = "guestvswitchname";
public static final String VSWITCH_NAME_PUBLIC_TRAFFIC = "publicvswitchname";
// NSX
public static final String EDGE_CLUSTER = "edgecluster";
public static final String TIER0_GATEWAY = "tier0gateway";
public static final String TRANSPORT_ZONE = "transportzone";
// Tungsten-Fabric
public static final String TUNGSTEN_VIRTUAL_ROUTER_UUID = "tungstenvirtualrouteruuid";
public static final String TUNGSTEN_PROVIDER_HOSTNAME = "tungstenproviderhostname";
@ -815,6 +823,8 @@ public class ApiConstants {
public static final String FORCE_ENCAP = "forceencap";
public static final String SPLIT_CONNECTIONS = "splitconnections";
public static final String FOR_VPC = "forvpc";
public static final String FOR_NSX = "fornsx";
public static final String NSX_SUPPORT_LB = "nsxsupportlb";
public static final String FOR_TUNGSTEN = "fortungsten";
public static final String SHRINK_OK = "shrinkok";
public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
@ -824,6 +834,11 @@ public class ApiConstants {
public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
public static final String NSX_LOGICAL_SWITCH = "nsxlogicalswitch";
public static final String NSX_LOGICAL_SWITCH_PORT = "nsxlogicalswitchport";
public static final String NSX_PROVIDER_UUID = "nsxprovideruuid";
public static final String NSX_PROVIDER_HOSTNAME = "nsxproviderhostname";
public static final String NSX_PROVIDER_PORT = "nsxproviderport";
public static final String NSX_CONTROLLER_ID = "nsxcontrollerid";
public static final String S3_ACCESS_KEY = "accesskey";
public static final String S3_SECRET_KEY = "secretkey";
public static final String S3_END_POINT = "endpoint";
@ -1066,14 +1081,13 @@ public class ApiConstants {
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
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 DISK_PATH = "diskpath";
public static final String IMPORT_SOURCE = "importsource";
public static final String TEMP_PATH = "temppath";
public static final String OBJECT_STORAGE = "objectstore";
public static final String HEURISTIC_RULE = "heuristicrule";
public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, TEMPLATE and VOLUME.";
public static final String MANAGEMENT = "management";
public static final String IS_VNF = "isvnf";
public static final String VNF_NICS = "vnfnics";

View File

@ -24,10 +24,14 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.cloud.network.Network;
import com.cloud.network.VirtualRouterProvider;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -47,6 +51,16 @@ import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.user.Account;
import static com.cloud.network.Network.Service.Dhcp;
import static com.cloud.network.Network.Service.Dns;
import static com.cloud.network.Network.Service.Lb;
import static com.cloud.network.Network.Service.StaticNat;
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.Firewall;
@APICommand(name = "createNetworkOffering", description = "Creates a network offering.", responseObject = NetworkOfferingResponse.class, since = "3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateNetworkOfferingCmd extends BaseCmd {
@ -128,6 +142,24 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
description = "true if network offering is meant to be used for VPC, false otherwise.")
private Boolean forVpc;
@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.NSX_MODE,
type = CommandType.STRING,
description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
since = "4.20.0")
private String nsxMode;
@Parameter(name = ApiConstants.NSX_SUPPORT_LB,
type = CommandType.BOOLEAN,
description = "true if network offering for NSX network offering supports Load balancer service.",
since = "4.20.0")
private Boolean nsxSupportsLbService;
@Parameter(name = ApiConstants.FOR_TUNGSTEN,
type = CommandType.BOOLEAN,
description = "true if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
@ -212,7 +244,27 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
}
public List<String> getSupportedServices() {
return supportedServices == null ? new ArrayList<String>() : supportedServices;
if (!isForNsx()) {
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 (getNsxSupportsLbService()) {
services.add(Lb.getName());
}
if (Boolean.TRUE.equals(forVpc)) {
services.add(NetworkACL.getName());
} else {
services.add(Firewall.getName());
}
return services;
}
}
public String getGuestIpType() {
@ -242,6 +294,18 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return forVpc;
}
public boolean isForNsx() {
return BooleanUtils.isTrue(forNsx);
}
public String getNsxMode() {
return nsxMode;
}
public boolean getNsxSupportsLbService() {
return BooleanUtils.isTrue(nsxSupportsLbService);
}
public Boolean getForTungsten() {
return forTungsten;
}
@ -262,9 +326,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
}
public Map<String, List<String>> getServiceProviders() {
Map<String, List<String>> serviceProviderMap = null;
if (serviceProviderList != null && !serviceProviderList.isEmpty()) {
serviceProviderMap = new HashMap<String, List<String>>();
Map<String, List<String>> serviceProviderMap = new HashMap<>();
if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) {
Collection servicesCollection = serviceProviderList.values();
Iterator iter = servicesCollection.iterator();
while (iter.hasNext()) {
@ -280,11 +343,37 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
providerList.add(provider);
serviceProviderMap.put(service, providerList);
}
} else if (Boolean.TRUE.equals(forNsx)) {
getServiceProviderMapForNsx(serviceProviderMap);
}
return serviceProviderMap;
}
private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) {
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> 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())) {
unsupportedServices.add("Firewall");
} else {
unsupportedServices.add("NetworkACL");
}
for (String service : allServices) {
if (unsupportedServices.contains(service))
continue;
if (routerSupported.contains(service))
serviceProviderMap.put(service, List.of(routerProvider));
else
serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName()));
if (!getNsxSupportsLbService()) {
serviceProviderMap.remove(Lb.getName());
}
}
}
public Map<Capability, String> getServiceCapabilities(Service service) {
Map<Capability, String> capabilityMap = null;

View File

@ -40,6 +40,8 @@ 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)
public class CreateVlanIpRangeCmd extends BaseCmd {
@ -114,6 +116,9 @@ 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;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -154,8 +159,12 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
return startIp;
}
public boolean isForNsx() {
return !Objects.isNull(forNsx) && forNsx;
}
public String getVlan() {
if (vlan == null || vlan.isEmpty()) {
if ((vlan == null || vlan.isEmpty()) && !isForNsx()) {
vlan = "untagged";
}
return vlan;

View File

@ -24,10 +24,15 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Network;
import com.cloud.network.VirtualRouterProvider;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -45,6 +50,15 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.user.Account;
import static com.cloud.network.Network.Service.Dhcp;
import static com.cloud.network.Network.Service.Dns;
import static com.cloud.network.Network.Service.Lb;
import static com.cloud.network.Network.Service.StaticNat;
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;
@APICommand(name = "createVPCOffering", description = "Creates VPC offering", responseObject = VpcOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
@ -62,7 +76,6 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.SUPPORTED_SERVICES,
type = CommandType.LIST,
required = true,
collectionType = CommandType.STRING,
description = "services supported by the vpc offering")
private List<String> supportedServices;
@ -101,6 +114,24 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
since = "4.13")
private List<Long> zoneIds;
@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.NSX_MODE,
type = CommandType.STRING,
description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
since = "4.20.0")
private String nsxMode;
@Parameter(name = ApiConstants.NSX_SUPPORT_LB,
type = CommandType.BOOLEAN,
description = "true if network offering for NSX VPC offering supports Load balancer service.",
since = "4.20.0")
private Boolean nsxSupportsLbService;
@Parameter(name = ApiConstants.ENABLE,
type = CommandType.BOOLEAN,
description = "set to true if the offering is to be enabled during creation. Default is false",
@ -120,13 +151,41 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
}
public List<String> getSupportedServices() {
if (!isForNsx() && CollectionUtils.isEmpty(supportedServices)) {
throw new InvalidParameterValueException("Supported services needs to be provided");
}
if (isForNsx()) {
supportedServices = new ArrayList<>(List.of(
Dhcp.getName(),
Dns.getName(),
StaticNat.getName(),
SourceNat.getName(),
NetworkACL.getName(),
PortForwarding.getName(),
UserData.getName()
));
if (getNsxSupportsLbService()) {
supportedServices.add(Lb.getName());
}
}
return supportedServices;
}
public boolean isForNsx() {
return BooleanUtils.isTrue(forNsx);
}
public String getNsxMode() {
return nsxMode;
}
public boolean getNsxSupportsLbService() {
return org.apache.commons.lang3.BooleanUtils.isTrue(nsxSupportsLbService);
}
public Map<String, List<String>> getServiceProviders() {
Map<String, List<String>> serviceProviderMap = null;
if (serviceProviderList != null && !serviceProviderList.isEmpty()) {
serviceProviderMap = new HashMap<String, List<String>>();
Map<String, List<String>> serviceProviderMap = new HashMap<>();
if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) {
Collection<? extends Map<String, String>> servicesCollection = serviceProviderList.values();
Iterator<? extends Map<String, String>> iter = servicesCollection.iterator();
while (iter.hasNext()) {
@ -134,7 +193,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
if (s_logger.isTraceEnabled()) {
s_logger.trace("service provider entry specified: " + obj);
}
HashMap<String, String> services = (HashMap<String, String>)obj;
HashMap<String, String> services = (HashMap<String, String>) obj;
String service = services.get("service");
String provider = services.get("provider");
List<String> providerList = null;
@ -146,11 +205,31 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
providerList.add(provider);
serviceProviderMap.put(service, providerList);
}
} else if (Boolean.TRUE.equals(forNsx)) {
getServiceProviderMapForNsx(serviceProviderMap);
}
return serviceProviderMap;
}
private void getServiceProviderMapForNsx(Map<String, List<String>> serviceProviderMap) {
List<String> unsupportedServices = List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity",
"Gateway", "Firewall");
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) {
if (unsupportedServices.contains(service))
continue;
if (routerSupported.contains(service))
serviceProviderMap.put(service, List.of(VirtualRouterProvider.Type.VPCVirtualRouter.name()));
else
serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName()));
}
if (!getNsxSupportsLbService()) {
serviceProviderMap.remove(Lb.getName());
}
}
public Map<String, List<String>> getServiceCapabilityList() {
return serviceCapabilityList;
}

View File

@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.address;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.BooleanUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.RoleType;
@ -106,6 +107,9 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", authorized = {RoleType.Admin})
private Boolean display;
@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;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -177,6 +181,10 @@ public class ListPublicIpAddressesCmd extends BaseListRetrieveOnlyResourceCountC
return state;
}
public boolean getForSystemVMs() {
return BooleanUtils.isTrue(forSystemVMs);
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -167,6 +167,10 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
@Param(description="whether the ip address has Firewall/PortForwarding/LoadBalancing rules defined")
private boolean hasRules;
@SerializedName(ApiConstants.FOR_SYSTEM_VMS)
@Param(description="true if range is dedicated for System VMs")
private boolean forSystemVms;
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
@ -316,4 +320,8 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
public void setHasRules(final boolean hasRules) {
this.hasRules = hasRules;
}
public void setForSystemVms(boolean forSystemVms) {
this.forSystemVms = forSystemVms;
}
}

View File

@ -99,10 +99,18 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations {
@Param(description = "true if network offering can be used by VPC networks only")
private Boolean forVpc;
@SerializedName(ApiConstants.FOR_NSX)
@Param(description = "true if network offering can be used by NSX networks only")
private Boolean forNsx;
@SerializedName(ApiConstants.FOR_TUNGSTEN)
@Param(description = "true if network offering can be used by Tungsten-Fabric networks only")
private Boolean forTungsten;
@SerializedName(ApiConstants.NSX_MODE)
@Param(description = "Mode in which the network will operate. This parameter is only relevant for NSX offerings")
private String nsxMode;
@SerializedName(ApiConstants.IS_PERSISTENT)
@Param(description = "true if network offering supports persistent networks, false otherwise")
private Boolean isPersistent;
@ -215,10 +223,18 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations {
this.forVpc = forVpc;
}
public void setForNsx(Boolean forNsx) {
this.forNsx = forNsx;
}
public void setForTungsten(Boolean forTungsten) {
this.forTungsten = forTungsten;
}
public void setNsxMode(String nsxMode) {
this.nsxMode = nsxMode;
}
public void setIsPersistent(Boolean isPersistent) {
this.isPersistent = isPersistent;
}

View File

@ -123,6 +123,10 @@ 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;
public void setId(String id) {
this.id = id;
}
@ -235,4 +239,8 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
public void setIp6Cidr(String ip6Cidr) {
this.ip6Cidr = ip6Cidr;
}
public void setForNsx(Boolean forNsx) {
this.forNsx = forNsx;
}
}

View File

@ -63,9 +63,17 @@ public class VpcOfferingResponse extends BaseResponse {
private Boolean supportsDistributedRouter;
@SerializedName((ApiConstants.SUPPORTS_REGION_LEVEL_VPC))
@Param(description = " indicated if the offering can support region level vpc", since = "4.4")
@Param(description = "indicated if the offering can support region level vpc", since = "4.4")
private Boolean supportsRegionLevelVpc;
@SerializedName(ApiConstants.FOR_NSX)
@Param(description = "true if vpc offering can be used by NSX networks only")
private Boolean forNsx;
@SerializedName(ApiConstants.NSX_MODE)
@Param(description = "Mode in which the network will operate. This parameter is only relevant for NSX offerings")
private String nsxMode;
@SerializedName(ApiConstants.DOMAIN_ID)
@Param(description = "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.")
private String domainId;
@ -138,6 +146,14 @@ public class VpcOfferingResponse extends BaseResponse {
this.domain = domain;
}
public void setForNsx(Boolean forNsx) {
this.forNsx = forNsx;
}
public void setNsxMode(String nsxMode) {
this.nsxMode = nsxMode;
}
public String getZoneId() {
return zoneId;
}

View File

@ -145,6 +145,10 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
@Param(description = "the type of the zone - core or edge", since = "4.18.0")
String type;
@SerializedName(ApiConstants.NSX_ENABLED)
@Param(description = "true, if zone is NSX enabled", since = "4.20.0")
private boolean nsxEnabled = false;
public ZoneResponse() {
tags = new LinkedHashSet<ResourceTagResponse>();
}
@ -368,4 +372,8 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
public String getType() {
return type;
}
public void setNsxEnabled(boolean nsxEnabled) {
this.nsxEnabled = nsxEnabled;
}
}

View File

@ -23,14 +23,16 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.springframework.test.util.ReflectionTestUtils;
public class CreateNetworkOfferingCmdTest {
@InjectMocks
private CreateNetworkOfferingCmd createNetworkOfferingCmd = new CreateNetworkOfferingCmd();
String netName = "network";
@Test
public void createVpcNtwkOffWithEmptyDisplayText() {
String netName = "network";
ReflectionTestUtils.setField(createNetworkOfferingCmd, "networkOfferingName", netName);
Assert.assertEquals(createNetworkOfferingCmd.getDisplayText(), netName);
}

View File

@ -52,15 +52,15 @@ public class CreateVPCOfferingCmdTest {
IllegalAccessException {
CreateVPCOfferingCmd cmd = new CreateVPCOfferingCmd();
ApiCmdTestUtil.set(cmd, ApiConstants.SERVICE_PROVIDER_LIST, new HashMap<String, Map<String, String>>());
Assert.assertNull(cmd.getServiceProviders());
Assert.assertTrue(cmd.getServiceProviders().isEmpty());
}
@Test
public void getDetailsNull() throws IllegalArgumentException,
public void getDetailsEmpty() throws IllegalArgumentException,
IllegalAccessException {
CreateVPCOfferingCmd cmd = new CreateVPCOfferingCmd();
ApiCmdTestUtil.set(cmd, ApiConstants.SERVICE_PROVIDER_LIST, null);
Assert.assertNull(cmd.getServiceProviders());
Assert.assertTrue(cmd.getServiceProviders().isEmpty());
}
@Test

View File

@ -296,6 +296,11 @@
<artifactId>cloud-plugin-network-tungsten</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-nsx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-elb</artifactId>

View File

@ -105,6 +105,9 @@ public interface NetworkOrchestrationService {
static final ConfigKey<Boolean> TUNGSTEN_ENABLED = new ConfigKey<>(Boolean.class, "tungsten.plugin.enable", "Advanced", "false",
"Indicates whether to enable the Tungsten plugin", false, ConfigKey.Scope.Zone, null);
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);
List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
throws ConcurrentOperationException;

View File

@ -63,6 +63,9 @@ public interface ConfigurationManager {
static final String VM_USERDATA_MAX_LENGTH_STRING = "vm.userdata.max.length";
static final ConfigKey<Integer> VM_USERDATA_MAX_LENGTH = new ConfigKey<>("Advanced", Integer.class, VM_USERDATA_MAX_LENGTH_STRING, "32768",
"Max length of vm userdata after base64 decoding. Default is 32768 and maximum is 1048576", true);
public static final ConfigKey<Boolean> AllowNonRFC1918CompliantIPs = new ConfigKey<>(Boolean.class,
"allow.non.rfc1918.compliant.ips", "Advanced", "false",
"Allows non-compliant RFC 1918 IPs for Shared, Isolated networks and VPCs", true, null);
/**
* @param offering
@ -97,7 +100,6 @@ public interface ConfigurationManager {
// * @param volatileVm
// * @param hostTag
// * @param networkRate
// * TODO
// * @param id
// * @param useVirtualNetwork
// * @param deploymentPlanner
@ -167,11 +169,9 @@ public interface ConfigurationManager {
* @param zoneType
* @param allocationState
* @param networkDomain
* TODO
* @param isSecurityGroupEnabled
* TODO
* @param ip6Dns1 TODO
* @param ip6Dns2 TODO
* @param ip6Dns1
* @param ip6Dns2
* @return
* @throws
* @throws
@ -186,7 +186,7 @@ public interface ConfigurationManager {
*
* @param userId
* @param vlanDbId
* @param caller TODO
* @param caller
* @return success/failure
*/
boolean deleteVlanAndPublicIpRange(long userId, long vlanDbId, Account caller);
@ -197,30 +197,25 @@ public interface ConfigurationManager {
/**
* Creates a new network offering
*
* @param name
* @param displayText
* @param trafficType
* @param tags
* @param specifyVlan
* @param networkRate
* TODO
* @param serviceProviderMap
* TODO
* @param isDefault
* TODO
* @param type
* TODO
* @param systemOnly
* TODO
* @param serviceOfferingId
* @param conserveMode
* ;
* @param conserveMode ;
* @param specifyIpRanges
* TODO
* @param isPersistent
* ;
* @param details TODO
* @param isPersistent ;
* @param details
* @param forVpc
* @param forTungsten
* @param forNsx
* @param domainIds
* @param zoneIds
* @return network offering object
@ -230,10 +225,10 @@ 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, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol);
Boolean forTungsten, boolean forNsx, String mode, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol);
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)
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr, boolean forNsx)
throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException;

View File

@ -269,4 +269,11 @@ public class PublicIp implements PublicIpAddress {
public void setRuleState(State ruleState) {
_addr.setRuleState(ruleState);
}
@Override
public boolean isForSystemVms() {
return false;
}
}

View File

@ -35,6 +35,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
@ -47,6 +48,11 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.persistence.EntityExistsException;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.user.dao.AccountDao;
import com.cloud.event.ActionEventUtils;
import com.google.gson.Gson;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@ -385,6 +391,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
private DomainRouterJoinDao domainRouterJoinDao;
@Inject
private AnnotationDao annotationDao;
@Inject
private AccountDao accountDao;
@Inject
private VpcDao vpcDao;
@Inject
private DomainDao domainDao;
VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
@ -599,11 +611,18 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
VirtualMachine.Type.ConsoleProxy.equals(vm.getType());
}
protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
private boolean isVmDestroyed(VMInstanceVO vm) {
if (vm == null || vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is expunged: " + vm);
}
return true;
}
return false;
}
protected void advanceExpunge(VMInstanceVO vm) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
if (isVmDestroyed(vm)) {
return;
}
@ -630,7 +649,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
List<NicProfile> vmNics = profile.getNics();
s_logger.debug(String.format("Cleaning up NICS [%s] of %s.", vmNics.stream().map(nic -> nic.toString()).collect(Collectors.joining(", ")),vm.toString()));
s_logger.debug(String.format("Cleaning up NICS [%s] of %s.", vmNics.stream().map(NicProfile::toString).collect(Collectors.joining(", ")),vm.toString()));
final List<Command> nicExpungeCommands = hvGuru.finalizeExpungeNics(vm, profile.getNics());
_networkMgr.cleanupNics(profile);
@ -674,28 +693,31 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
// send hypervisor-dependent commands before removing
final List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm);
if (CollectionUtils.isNotEmpty(finalizeExpungeCommands) || CollectionUtils.isNotEmpty(nicExpungeCommands)) {
if (hostId != null) {
final Commands cmds = new Commands(Command.OnError.Stop);
addAllExpungeCommandsFromList(finalizeExpungeCommands, cmds, vm);
addAllExpungeCommandsFromList(nicExpungeCommands, cmds, vm);
_agentMgr.send(hostId, cmds);
if (!cmds.isSuccessful()) {
for (final Answer answer : cmds.getAnswers()) {
if (!answer.getResult()) {
s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
throw new CloudRuntimeException("Unable to expunge " + vm + " due to " + answer.getDetails());
}
}
}
}
}
handleUnsuccessfulExpungeOperation(finalizeExpungeCommands, nicExpungeCommands, vm, hostId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Expunged " + vm);
}
}
private void handleUnsuccessfulExpungeOperation(List<Command> finalizeExpungeCommands, List<Command> nicExpungeCommands,
VMInstanceVO vm, Long hostId) throws OperationTimedoutException, AgentUnavailableException {
if (CollectionUtils.isNotEmpty(finalizeExpungeCommands) || CollectionUtils.isNotEmpty(nicExpungeCommands) && (hostId != null)) {
final Commands cmds = new Commands(Command.OnError.Stop);
addAllExpungeCommandsFromList(finalizeExpungeCommands, cmds, vm);
addAllExpungeCommandsFromList(nicExpungeCommands, cmds, vm);
_agentMgr.send(hostId, cmds);
if (!cmds.isSuccessful()) {
for (final Answer answer : cmds.getAnswers()) {
if (!answer.getResult()) {
s_logger.warn("Failed to expunge vm due to: " + answer.getDetails());
throw new CloudRuntimeException(String.format("Unable to expunge %s due to %s", vm, answer.getDetails()));
}
}
}
}
}
protected void handleUnsuccessfulCommands(Commands cmds, VMInstanceVO vm) throws CloudRuntimeException {
String cmdsStr = cmds.toString();
String vmToString = vm.toString();
@ -1279,6 +1301,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
checkAndSetEnterSetupMode(vmTO, params);
handlePath(vmTO.getDisks(), vm.getHypervisorType());
setVmNetworkDetails(vm, vmTO);
Commands cmds = new Commands(Command.OnError.Stop);
final Map<String, String> sshAccessDetails = _networkMgr.getSystemVMAccessDetails(vm);
@ -1462,6 +1486,55 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
}
public void setVmNetworkDetails(VMInstanceVO vm, VirtualMachineTO vmTO) {
Map<Long, String> networkToNetworkNameMap = new HashMap<>();
if (VirtualMachine.Type.User.equals(vm.getType())) {
List<UserVmJoinVO> userVmJoinVOs = userVmJoinDao.searchByIds(vm.getId());
if (userVmJoinVOs != null && !userVmJoinVOs.isEmpty()) {
for (UserVmJoinVO userVmJoinVO : userVmJoinVOs) {
addToNetworkNameMap(userVmJoinVO.getNetworkId(), vm.getDataCenterId(), networkToNetworkNameMap);
}
vmTO.setNetworkIdToNetworkNameMap(networkToNetworkNameMap);
}
} else if (VirtualMachine.Type.DomainRouter.equals(vm.getType())) {
List<DomainRouterJoinVO> routerJoinVO = domainRouterJoinDao.getRouterByIdAndTrafficType(vm.getId(), Networks.TrafficType.Guest);
for (DomainRouterJoinVO router : routerJoinVO) {
NetworkVO guestNetwork = _networkDao.findById(router.getNetworkId());
if (guestNetwork.getVpcId() == null && guestNetwork.getBroadcastDomainType() == Networks.BroadcastDomainType.NSX) {
addToNetworkNameMap(router.getNetworkId(), vm.getDataCenterId(), networkToNetworkNameMap);
}
}
vmTO.setNetworkIdToNetworkNameMap(networkToNetworkNameMap);
}
}
private void addToNetworkNameMap(long networkId, long dataCenterId, Map<Long, String> networkToNetworkNameMap) {
NetworkVO networkVO = _networkDao.findById(networkId);
Account acc = accountDao.findById(networkVO.getAccountId());
Domain domain = domainDao.findById(networkVO.getDomainId());
DataCenter zone = _dcDao.findById(dataCenterId);
if (Objects.isNull(zone)) {
throw new CloudRuntimeException(String.format("Failed to find zone with ID: %s", dataCenterId));
}
if (Objects.isNull(acc)) {
throw new CloudRuntimeException(String.format("Failed to find account with ID: %s", networkVO.getAccountId()));
}
if (Objects.isNull(domain)) {
throw new CloudRuntimeException(String.format("Failed to find domain with ID: %s", networkVO.getDomainId()));
}
String networkName = String.format("D%s-A%s-Z%s", domain.getId(), acc.getId(), zone.getId());
if (Objects.isNull(networkVO.getVpcId())) {
networkName += "-S" + networkVO.getId();
} else {
VpcVO vpc = vpcDao.findById(networkVO.getVpcId());
if (Objects.isNull(vpc)) {
throw new CloudRuntimeException(String.format("Failed to find VPC with ID: %s", networkVO.getVpcId()));
}
networkName = String.format("%s-V%s-S%s", networkName, vpc.getId(), networkVO.getId());
}
networkToNetworkNameMap.put(networkVO.getId(), networkName);
}
/**
* Setting pod id to null can result in migration of Volumes across pods. This is not desirable for VMs which
* have a volume in Ready state (happens when a VM is shutdown and started again).
@ -2733,6 +2806,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
final VirtualMachineTO to = toVmTO(profile);
final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
setVmNetworkDetails(vm, to);
ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Migrating, vm.getType(), vm.getId());
work.setStep(Step.Prepare);

View File

@ -38,6 +38,9 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.network.dao.NsxProviderDao;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
@ -56,6 +59,7 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -254,6 +258,7 @@ import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.googlecode.ipv6.IPv6Address;
import org.jetbrains.annotations.NotNull;
/**
* NetworkManagerImpl implements NetworkManager.
@ -339,8 +344,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
Ipv6Service ipv6Service;
@Inject
RouterNetworkDao routerNetworkDao;
@Inject
private VlanDetailsDao vlanDetailsDao;
List<NetworkGuru> networkGurus;
@Inject
private NsxProviderDao nsxProviderDao;
@Override
public List<NetworkGuru> getNetworkGurus() {
@ -502,6 +511,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
defaultTungstenSharedSGEnabledNetworkOfferingProviders.put(Service.UserData, tungstenProvider);
defaultTungstenSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, tungstenProvider);
final Map<Network.Service, Set<Network.Provider>> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap<Network.Service, Set<Network.Provider>>();
defaultProviders.clear();
defaultProviders.add(Network.Provider.VirtualRouter);
@ -538,27 +548,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, null, null, true, null);
false, null, false, null, true, false, false, false, null, null, null, true, null);
}
//#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, null, null, true, null);
null, true, false, null, false, null, true, false, false, false, null, null, null, true, null);
}
//#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, null, null, true, null);
null, true, false, false, false, null,null, null, true, null);
}
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,null, null, true, null);
null, true, false, null, false, null, true, false, true, false, null, null,null, true, null);
offering.setState(NetworkOffering.State.Enabled);
_networkOfferingDao.update(offering.getId(), offering);
}
@ -568,14 +578,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, null, null, true, null);
true, false, false, false, null, null,null, true, null);
}
//#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, null, null, true, null);
defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null);
}
//#6 - default vpc offering with no LB service
@ -584,14 +594,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, null, null, true, null);
null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null);
}
//#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, null, null, true, null);
true, null, true, false, null, false, null, true, false, false, false, null, null, null, true, null);
}
//#8 - network offering with internal lb service
@ -613,7 +623,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, null, null, true, null);
true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, true, null);
offering.setInternalLb(true);
offering.setPublicLb(false);
_networkOfferingDao.update(offering.getId(), offering);
@ -644,7 +654,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, null, null, true, null);
netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false, null, null, null, true, null);
offering.setDedicatedLB(false);
_networkOfferingDao.update(offering.getId(), offering);
}
@ -740,20 +750,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
.getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch || predefined
.getBroadcastDomainType() == BroadcastDomainType.Vxlan)) {
final List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (configs.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
}
if (errorIfAlreadySetup) {
final InvalidParameterValueException ex = new InvalidParameterValueException(
"Found existing network configuration (with specified id) for offering (with specified id)");
ex.addProxyObject(offering.getUuid(), "offeringId");
ex.addProxyObject(configs.get(0).getUuid(), "networkConfigId");
throw ex;
} else {
return configs;
}
if (!configs.isEmpty()) {
return existingConfiguration(offering, configs, errorIfAlreadySetup);
}
}
@ -762,7 +760,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
long related = -1;
for (final NetworkGuru guru : networkGurus) {
final Network network = guru.design(offering, plan, predefined, owner);
final Network network = guru.design(offering, plan, predefined, name, vpcId, owner);
if (network == null) {
continue;
}
@ -785,11 +783,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(final TransactionStatus status) {
final NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, predefined
.getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.isSpecifyIpRanges(),
vpcId, offering.isRedundantRouter(), predefined.getExternalId());
vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
vo.setStrechedL2Network(offering.isSupportingStrechedL2());
final NetworkVO vo = getNetworkVO(id, offering, plan, predefined,
network, guru, owner, name, displayText,relatedFile, aclType,vpcId, isDisplayNetworkEnabled);
final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()));
networks.add(networkPersisted);
@ -806,13 +801,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
if (domainId != null && aclType == ACLType.Domain) {
_networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
_networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null || subdomainAccess);
}
}
});
guru.setup(network, relatedFile);
}
if (networks.size() < 1) {
if (networks.isEmpty()) {
// see networkOfferingVO.java
final CloudRuntimeException ex = new CloudRuntimeException("Unable to convert network offering with specified id to network profile");
ex.addProxyObject(offering.getUuid(), "offeringId");
@ -826,6 +822,37 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
}
@NotNull
private static NetworkVO getNetworkVO(long id, final NetworkOffering offering, final DeploymentPlan plan, final Network predefined,
Network network, final NetworkGuru guru, final Account owner,
final String name, final String displayText, long relatedFile, final ACLType aclType,
final Long vpcId, final Boolean isDisplayNetworkEnabled) {
final NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(),
relatedFile, name, displayText, predefined.getNetworkDomain(), offering.getGuestType(),
plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.isSpecifyIpRanges(),
vpcId, offering.isRedundantRouter(), predefined.getExternalId());
vo.setDisplayNetwork(isDisplayNetworkEnabled == null || isDisplayNetworkEnabled);
vo.setStrechedL2Network(offering.isSupportingStrechedL2());
return vo;
}
private List<? extends Network> existingConfiguration(final NetworkOffering offering, List<NetworkVO> configs,
final boolean errorIfAlreadySetup) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
}
if (errorIfAlreadySetup) {
final InvalidParameterValueException ex = new InvalidParameterValueException(
"Found existing network configuration (with specified id) for offering (with specified id)");
ex.addProxyObject(offering.getUuid(), "offeringId");
ex.addProxyObject(configs.get(0).getUuid(), "networkConfigId");
throw ex;
} else {
return configs;
}
}
@Override
@DB
public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
@ -1027,6 +1054,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return null;
}
if (isNicAllocatedForNsxPublicNetworkOnVR(network, profile, vm)) {
String guruName = "NsxPublicNetworkGuru";
NetworkGuru nsxGuru = AdapterBase.getAdapterByName(networkGurus, guruName);
nsxGuru.allocate(network, profile, vm);
}
if (isDefaultNic != null) {
profile.setDefaultNic(isDefaultNic);
}
@ -1059,6 +1092,36 @@ 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) {
if (ObjectUtils.anyNull(network, requested, vm)) {
return false;
}
boolean isVirtualRouter = vm.getType() == Type.DomainRouter;
boolean isPublicTraffic = network.getTrafficType() == TrafficType.Public;
if (!isVirtualRouter || !isPublicTraffic || requested.getIPv4Address() == null) {
return false;
}
long dataCenterId = vm.getVirtualMachine().getDataCenterId();
if (nsxProviderDao.findByZoneId(dataCenterId) == null) {
return false;
}
Long vpcId = _ipAddressDao.findByIp(requested.getIPv4Address()).getVpcId();
List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpcId, true);
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);
if (vlanDetail == null) {
return false;
}
boolean isForNsx = vlanDetail.getValue().equalsIgnoreCase("true");
return isForNsx && !ip.isForSystemVms();
}
private void setMtuDetailsInVRNic(final Pair<NetworkVO, VpcVO> networks, Network network, NicVO vo) {
if (TrafficType.Public == network.getTrafficType()) {
if (networks == null) {
@ -2813,10 +2876,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
// Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
if (cidr != null && ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) {
if (!NetUtils.validateGuestCidr(cidr)) {
if (cidr != null && (ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) &&
!NetUtils.validateGuestCidr(cidr, !ConfigurationManager.AllowNonRFC1918CompliantIPs.value())) {
throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
}
}
final String networkDomainFinal = networkDomain;
@ -3798,8 +3860,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
for (final NicVO nic : result) {
if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) {
//For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result
s_logger.info("Listing NSX logical switch and logical switch por for each nic");
//For Nsx Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result
s_logger.info("Listing Nsx logical switch and logical switch por for each nic");
final NetworkVO network = _networksDao.findById(nic.getNetworkId());
final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
final NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru;
@ -3843,7 +3905,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
private boolean cleanupNetworkResources(final long networkId, final Account caller, final long callerUserId) {
boolean success = true;
final Network network = _networksDao.findById(networkId);
final NetworkVO network = _networksDao.findById(networkId);
final NetworkOfferingVO networkOffering= _networkOfferingDao.findById(network.getNetworkOfferingId());
//remove all PF/Static Nat rules for the network
try {
@ -4723,6 +4786,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
return new ConfigKey<?>[]{NetworkGcWait, NetworkGcInterval, NetworkLockTimeout,
GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RollingRestartEnabled,
TUNGSTEN_ENABLED };
TUNGSTEN_ENABLED, NSX_ENABLED };
}
}

View File

@ -38,6 +38,18 @@ import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.Pod;
@ -178,6 +190,16 @@ public class VirtualMachineManagerImplTest {
@Mock
private UserVmVO userVmMock;
@Mock
private NetworkDao networkDao;
@Mock
private AccountDao accountDao;
@Mock
private DomainDao domainDao;
@Mock
private DataCenterDao dcDao;
@Mock
private VpcDao vpcDao;
@Mock
private EntityManager _entityMgr;
@Mock
private DeploymentPlanningManager _dpMgr;
@ -932,6 +954,48 @@ public class VirtualMachineManagerImplTest {
virtualMachineManagerImpl.checkAndAttemptMigrateVmAcrossCluster(vm, destinationClusterId, map);
}
@Test
public void checkIfVmNetworkDetailsReturnedIsCorrect() {
VMInstanceVO vm = new VMInstanceVO(1L, 1L, "VM1", "i-2-2-VM",
VirtualMachine.Type.User, 1L, HypervisorType.KVM, 1L, 1L, 1L,
1L, false, false);
VirtualMachineTO vmTO = new VirtualMachineTO() {
};
UserVmJoinVO userVm = new UserVmJoinVO();
NetworkVO networkVO = mock(NetworkVO.class);
AccountVO accountVO = mock(AccountVO.class);
DomainVO domainVO = mock(DomainVO.class);
domainVO.setName("testDomain");
DataCenterVO dataCenterVO = mock(DataCenterVO.class);
VpcVO vpcVO = mock(VpcVO.class);
networkVO.setAccountId(1L);
networkVO.setName("testNet");
networkVO.setVpcId(1L);
accountVO.setAccountName("testAcc");
vpcVO.setName("VPC1");
List<UserVmJoinVO> userVms = List.of(userVm);
Mockito.when(userVmJoinDaoMock.searchByIds(anyLong())).thenReturn(userVms);
Mockito.when(networkDao.findById(anyLong())).thenReturn(networkVO);
Mockito.when(accountDao.findById(anyLong())).thenReturn(accountVO);
Mockito.when(domainDao.findById(anyLong())).thenReturn(domainVO);
Mockito.when(dcDao.findById(anyLong())).thenReturn(dataCenterVO);
Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpcVO);
Mockito.when(dataCenterVO.getId()).thenReturn(1L);
when(accountVO.getId()).thenReturn(2L);
Mockito.when(domainVO.getId()).thenReturn(3L);
Mockito.when(vpcVO.getId()).thenReturn(4L);
Mockito.when(networkVO.getId()).thenReturn(5L);
virtualMachineManagerImpl.setVmNetworkDetails(vm, vmTO);
assertEquals(1, vmTO.getNetworkIdToNetworkNameMap().size());
assertEquals("D3-A2-Z1-V4-S5", vmTO.getNetworkIdToNetworkNameMap().get(5L));
}
@Test
public void testOrchestrateStartNonNullPodId() throws Exception {
VMInstanceVO vmInstance = new VMInstanceVO();

View File

@ -369,6 +369,10 @@ public class NetworkVO implements Network {
return mode;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
@Override
public long getAccountId() {
return accountId;

View File

@ -0,0 +1,30 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.dao;
import com.cloud.network.element.NsxProviderVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface NsxProviderDao extends GenericDao<NsxProviderVO, Long> {
NsxProviderVO findByZoneId(long zoneId);
NsxProviderVO findByUuid(String uuid);
List<NsxProviderVO> findAll();
}

View File

@ -0,0 +1,65 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.network.dao;
import com.cloud.network.element.NsxProviderVO;
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;
import java.util.List;
@Component
@DB()
public class NsxProviderDaoImpl extends GenericDaoBase<NsxProviderVO, Long>
implements NsxProviderDao {
final SearchBuilder<NsxProviderVO> allFieldsSearch;
public NsxProviderDaoImpl() {
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().getHostname(),
SearchCriteria.Op.EQ);
allFieldsSearch.and("provider_name", allFieldsSearch.entity().getProviderName(),
SearchCriteria.Op.EQ);
allFieldsSearch.and("tier0_gateway", allFieldsSearch.entity().getTier0Gateway(),
SearchCriteria.Op.EQ);
allFieldsSearch.and("zone_id", allFieldsSearch.entity().getZoneId(),
SearchCriteria.Op.EQ);
allFieldsSearch.and("edge_cluster", allFieldsSearch.entity().getEdgeCluster(),
SearchCriteria.Op.EQ);
allFieldsSearch.done();
}
@Override
public NsxProviderVO findByZoneId(long zoneId) {
SearchCriteria<NsxProviderVO> sc = allFieldsSearch.create();
sc.setParameters("zone_id", zoneId);
return findOneBy(sc);
}
@Override
public List<NsxProviderVO> findAll() {
return listAll();
}
}

View File

@ -0,0 +1,285 @@
// 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.nsx.NsxProvider;
import com.cloud.utils.db.Encrypt;
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 = "nsx_providers")
public class NsxProviderVO implements NsxProvider {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
long id;
@Column(name = "zone_id")
private long zoneId;
@Column(name = "host_id")
private long hostId;
@Column(name = "uuid")
private String uuid;
@Column(name = "provider_name")
private String providerName;
@Column(name = "hostname")
private String hostname;
@Column(name = "port")
private String port = "443";
@Column(name = "username")
private String username;
@Encrypt
@Column(name = "password")
private String password;
@Column(name = "tier0_gateway")
private String tier0Gateway;
@Column(name = "edge_cluster")
private String edgeCluster;
@Column(name = "transport_zone")
private String transportZone;
@Column(name = "created")
private Date created;
@Column(name = "removed")
private Date removed;
public NsxProviderVO() {
this.uuid = UUID.randomUUID().toString();
}
@Override
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@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 getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
@Override
public String getHostname() {
return hostname;
}
public void setPort(String port) {
this.port = port;
}
@Override
public String getPort() {
return port;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
@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 getTier0Gateway() {
return tier0Gateway;
}
public void setTier0Gateway(String tier0Gateway) {
this.tier0Gateway = tier0Gateway;
}
public String getEdgeCluster() {
return edgeCluster;
}
public void setEdgeCluster(String edgeCluster) {
this.edgeCluster = edgeCluster;
}
public String getTransportZone() {
return transportZone;
}
public void setTransportZone(String transportZone) {
this.transportZone = transportZone;
}
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 providerName;
private String hostname;
private String port;
private String username;
private String password;
private String tier0Gateway;
private String edgeCluster;
private String transportZone;
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 setProviderName(String providerName) {
this.providerName = providerName;
return this;
}
public Builder setHostname(String hostname) {
this.hostname = hostname;
return this;
}
public Builder setPort(String port) {
this.port = port;
return this;
}
public Builder setUsername(String username) {
this.username = username;
return this;
}
public Builder setPassword(String password) {
this.password = password;
return this;
}
public Builder setTier0Gateway(String tier0Gateway) {
this.tier0Gateway = tier0Gateway;
return this;
}
public Builder setEdgeCluster(String edgeCluster) {
this.edgeCluster = edgeCluster;
return this;
}
public Builder setTransportZone(String transportZone) {
this.transportZone = transportZone;
return this;
}
public NsxProviderVO build() {
NsxProviderVO provider = new NsxProviderVO();
provider.setZoneId(this.zoneId);
provider.setHostId(this.hostId);
provider.setUuid(UUID.randomUUID().toString());
provider.setProviderName(this.providerName);
provider.setHostname(this.hostname);
provider.setPort(this.port);
provider.setUsername(this.username);
provider.setPassword(this.password);
provider.setTier0Gateway(this.tier0Gateway);
provider.setEdgeCluster(this.edgeCluster);
provider.setTransportZone(this.transportZone);
provider.setCreated(new Date());
return provider;
}
}
}

View File

@ -58,6 +58,12 @@ public class VpcOfferingVO implements VpcOffering {
@Column(name = "default")
boolean isDefault = false;
@Column(name = "for_nsx")
boolean forNsx = false;
@Column(name = "nsx_mode")
String nsxMode;
@Column(name = GenericDao.REMOVED_COLUMN)
Date removed;
@ -144,6 +150,22 @@ public class VpcOfferingVO implements VpcOffering {
return isDefault;
}
public boolean isForNsx() {
return forNsx;
}
public void setForNsx(boolean forNsx) {
this.forNsx = forNsx;
}
public String getNsxMode() {
return nsxMode;
}
public void setNsxMode(String nsxMode) {
this.nsxMode = nsxMode;
}
public void setUniqueName(String uniqueName) {
this.uniqueName = uniqueName;
}

View File

@ -136,6 +136,12 @@ public class NetworkOfferingVO implements NetworkOffering {
@Column(name = "for_tungsten")
boolean forTungsten = false;
@Column(name = "for_nsx")
boolean forNsx = false;
@Column(name = "nsx_mode")
String nsxMode;
@Column(name = "egress_default_policy")
boolean egressdefaultpolicy;
@ -195,6 +201,24 @@ public class NetworkOfferingVO implements NetworkOffering {
this.forTungsten = forTungsten;
}
@Override
public boolean isForNsx() {
return forNsx;
}
public void setForNsx(boolean forNsx) {
this.forNsx = forNsx;
}
@Override
public String getNsxMode() {
return nsxMode;
}
public void setNsxMode(String nsxMode) {
this.nsxMode = nsxMode;
}
@Override
public long getId() {
return id;

View File

@ -136,6 +136,7 @@
<bean id="nicIpAliasDaoImpl" class="com.cloud.vm.dao.NicIpAliasDaoImpl" />
<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="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" />

View File

@ -103,6 +103,43 @@ CREATE TABLE `cloud`.`vm_scheduled_job` (
ALTER TABLE `cloud`.`kubernetes_cluster` ADD COLUMN `cluster_type` varchar(64) DEFAULT 'CloudManaged' COMMENT 'type of cluster';
ALTER TABLE `cloud`.`kubernetes_cluster` MODIFY COLUMN `kubernetes_version_id` bigint unsigned NULL COMMENT 'the ID of the Kubernetes version of this Kubernetes cluster';
CREATE TABLE `cloud`.`nsx_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',
`provider_name` varchar(40),
`hostname` varchar(255) NOT NULL,
`port` varchar(255),
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`tier0_gateway` varchar(255),
`edge_cluster` varchar(255),
`transport_zone` varchar(255),
`created` datetime NOT NULL COMMENT 'date created',
`removed` datetime COMMENT 'date removed if not null',
PRIMARY KEY (`id`),
CONSTRAINT `fk_nsx_providers__zone_id` FOREIGN KEY `fk_nsx_providers__zone_id` (`zone_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE,
INDEX `i_nsx_providers__zone_id`(`zone_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Idempotent ADD COLUMN
DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_ADD_COLUMN`;
CREATE PROCEDURE `cloud`.`IDEMPOTENT_ADD_COLUMN` (
IN in_table_name VARCHAR(200)
, IN in_column_name VARCHAR(200)
, IN in_column_definition VARCHAR(1000)
)
BEGIN
DECLARE CONTINUE HANDLER FOR 1060 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', 'ADD COLUMN') ; SET @ddl = CONCAT(@ddl, ' ', in_column_name); SET @ddl = CONCAT(@ddl, ' ', in_column_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
-- NSX Plugin --
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','for_nsx', 'int(1) unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"');
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','nsx_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"');
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','for_nsx', 'int(1) unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"');
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','nsx_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"');
-- Add indexes for data store browser
ALTER TABLE `cloud`.`template_spool_ref` ADD INDEX `i_template_spool_ref__install_path`(`install_path`);
ALTER TABLE `cloud`.`volumes` ADD INDEX `i_volumes__path`(`path`);

View File

@ -60,6 +60,8 @@ SELECT
`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`.`nsx_mode` AS `nsx_mode`,
`network_offerings`.`service_package_id` AS `service_package_id`,
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,

View File

@ -0,0 +1,61 @@
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
-- VIEW `cloud`.`vpc_offering_view`;
DROP VIEW IF EXISTS `cloud`.`vpc_offering_view`;
CREATE VIEW `cloud`.`vpc_offering_view` AS
SELECT
`vpc_offerings`.`id` AS `id`,
`vpc_offerings`.`uuid` AS `uuid`,
`vpc_offerings`.`name` AS `name`,
`vpc_offerings`.`unique_name` AS `unique_name`,
`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`.`nsx_mode` AS `nsx_mode`,
`vpc_offerings`.`created` AS `created`,
`vpc_offerings`.`removed` AS `removed`,
`vpc_offerings`.`service_offering_id` AS `service_offering_id`,
`vpc_offerings`.`supports_distributed_router` AS `supports_distributed_router`,
`vpc_offerings`.`supports_region_level_vpc` AS `supports_region_level_vpc`,
`vpc_offerings`.`redundant_router_service` AS `redundant_router_service`,
`vpc_offerings`.`sort_key` AS `sort_key`,
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name,
`offering_details`.value AS internet_protocol
FROM
`cloud`.`vpc_offerings`
LEFT JOIN
`cloud`.`vpc_offering_details` AS `domain_details` ON `domain_details`.`offering_id` = `vpc_offerings`.`id` AND `domain_details`.`name`='domainid'
LEFT JOIN
`cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
LEFT JOIN
`cloud`.`vpc_offering_details` AS `zone_details` ON `zone_details`.`offering_id` = `vpc_offerings`.`id` AND `zone_details`.`name`='zoneid'
LEFT JOIN
`cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
LEFT JOIN
`cloud`.`vpc_offering_details` AS `offering_details` ON `offering_details`.`offering_id` = `vpc_offerings`.`id` AND `offering_details`.`name`='internetprotocol'
GROUP BY
`vpc_offerings`.`id`;

View File

@ -464,7 +464,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
}
}
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, null, 180000,
vsType, portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null);
vsType, portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, null, null, null);
}
}

View File

@ -729,7 +729,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
HostMO hostMO = new HostMO(context, host.getMor());
try {
prepareNetworkFromNicInfo(hostMO, cmd.getNic(), false, null);
prepareNetworkFromNicInfo(hostMO, cmd.getNic(), false, null, null);
hostname = host.getHyperHostName();
} catch (Exception e) {
return new SetupPersistentNetworkAnswer(cmd, false, "failed to setup port-group due to: "+ e.getLocalizedMessage());
@ -1471,7 +1471,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
deviceNumber++;
VirtualDevice nic;
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, vmType);
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, nicTo.getNetworkSegmentName(), vmType);
String dvSwitchUuid = null;
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
@ -1533,7 +1533,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
return new ReplugNicAnswer(cmd, false, "Nic to replug not found");
}
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, cmd.getVMType());
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, false, null, cmd.getVMType());
String dvSwitchUuid = null;
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
@ -1615,7 +1615,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
} else {
networkInfo =
HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, ipAddressTO.getNetworkRate(), null,
_opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null);
_opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan, _vsmCredentials, null, null);
}
int nicIndex = allocPublicNicIndex(vmMo);
@ -2524,7 +2524,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus,
vmSpec.getNetworkIdToNetworkNameMap().getOrDefault(nicTo.getNetworkId(), null), vmType);
if ((nicTo.getBroadcastType() != BroadcastDomainType.Lswitch)
|| (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch && NiciraNvpApiVersion.isApiVersionLowerThan("4.2"))) {
if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
@ -3980,7 +3981,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
return defaultVlan;
}
private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType)
private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, String networkName, VirtualMachine.Type vmType)
throws Exception {
Ternary<String, String, String> switchDetails = getTargetSwitch(nicTo);
@ -4010,7 +4011,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId,
nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType,
_portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails());
_portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials, nicTo.getDetails(), networkName);
}
return networkInfo;
@ -4601,7 +4602,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
NicTO[] nics = vm.getNics();
for (NicTO nic : nics) {
// prepare network on the host
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType());
prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false,
vm.getNetworkIdToNetworkNameMap().getOrDefault(nic.getNetworkId(), null), cmd.getVirtualMachine().getType());
}
List<Pair<String, Long>> secStoreUrlAndIdList = mgr.getSecondaryStorageStoresUrlAndIdList(Long.parseLong(_dcId));
@ -5669,7 +5671,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
protected Answer execute(MaintainCommand cmd) {
return new MaintainAnswer(cmd, "Put host in maintaince");
return new MaintainAnswer(cmd, "Put host in maintenance");
}
protected Answer execute(PingTestCommand cmd) {
@ -7315,7 +7317,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
NicTO[] nics = vmTo.getNics();
for (NicTO nic : nics) {
// prepare network on the host
prepareNetworkFromNicInfo((HostMO)targetHyperHost, nic, false, vmTo.getType());
prepareNetworkFromNicInfo((HostMO)targetHyperHost, nic, false,
vmTo.getNetworkIdToNetworkNameMap().get(nic.getNetworkId()), vmTo.getType());
}
if (targetHyperHost == null) {

View File

@ -17,6 +17,7 @@
package com.cloud.kubernetes.cluster;
import com.cloud.kubernetes.cluster.dao.KubernetesClusterDao;
import com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDao;
import com.cloud.utils.component.AdapterBase;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.framework.config.ConfigKey;
@ -24,18 +25,30 @@ import org.apache.cloudstack.framework.config.Configurable;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import java.util.Objects;
@Component
public class KubernetesClusterHelperImpl extends AdapterBase implements KubernetesClusterHelper, Configurable {
@Inject
private KubernetesClusterDao kubernetesClusterDao;
@Inject
private KubernetesClusterVmMapDao kubernetesClusterVmMapDao;
@Override
public ControlledEntity findByUuid(String uuid) {
return kubernetesClusterDao.findByUuid(uuid);
}
@Override
public ControlledEntity findByVmId(long vmId) {
KubernetesClusterVmMapVO clusterVmMapVO = kubernetesClusterVmMapDao.getClusterMapFromVmId(vmId);
if (Objects.isNull(clusterVmMapVO)) {
return null;
}
return kubernetesClusterDao.findById(clusterVmMapVO.getClusterId());
}
@Override
public String getConfigComponentName() {
return KubernetesClusterHelper.class.getSimpleName();

View File

@ -184,6 +184,11 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
private static final Logger LOGGER = Logger.getLogger(KubernetesClusterManagerImpl.class);
private static final String DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNetworkOfferingforKubernetesService";
private static final String DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering used for CloudStack Kubernetes service";
private static final String DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNSXNetworkOfferingforKubernetesService";
private static final String DEFAULT_NSX_VPC_TIER_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME = "DefaultNSXVPCNetworkOfferingforKubernetesService";
private static final String DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering for NSX CloudStack Kubernetes Service";
private static final String DEFAULT_NSX_VPC_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT = "Network Offering for NSX CloudStack Kubernetes service on VPC";
protected StateMachine2<KubernetesCluster.State, KubernetesCluster.Event, KubernetesCluster> _stateMachine = KubernetesCluster.State.getStateMachine();
@ -1895,26 +1900,54 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
@Override
public boolean start() {
createNetworkOfferingForKubernetes(DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT, false, false);
createNetworkOfferingForKubernetes(DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NSX_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT, true, false);
createNetworkOfferingForKubernetes(DEFAULT_NSX_VPC_TIER_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
DEFAULT_NSX_VPC_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_DISPLAY_TEXT , true, true);
_gcExecutor.scheduleWithFixedDelay(new KubernetesClusterGarbageCollector(), 300, 300, TimeUnit.SECONDS);
_stateScanner.scheduleWithFixedDelay(new KubernetesClusterStatusScanner(), 300, 30, TimeUnit.SECONDS);
return true;
}
private void createNetworkOfferingForKubernetes(String offeringName, String offeringDesc, boolean forNsx, boolean forVpc) {
final Map<Network.Service, Network.Provider> defaultKubernetesServiceNetworkOfferingProviders = new HashMap<Service, Network.Provider>();
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dhcp, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dns, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.UserData, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Firewall, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Lb, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.SourceNat, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.PortForwarding, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
Network.Provider provider = forVpc ? Network.Provider.VPCVirtualRouter : Network.Provider.VirtualRouter;
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dhcp, provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Dns, provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.UserData, provider);
if (forVpc) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.NetworkACL, forNsx ? Network.Provider.Nsx : provider);
} else {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Firewall, forNsx ? Network.Provider.Nsx : provider);
}
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Lb, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.SourceNat, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.StaticNat, forNsx ? Network.Provider.Nsx : provider);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.PortForwarding, forNsx ? Network.Provider.Nsx : provider);
if (!forNsx) {
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Gateway, Network.Provider.VirtualRouter);
defaultKubernetesServiceNetworkOfferingProviders.put(Service.Vpn, Network.Provider.VirtualRouter);
}
NetworkOfferingVO defaultKubernetesServiceNetworkOffering =
new NetworkOfferingVO(DEFAULT_NETWORK_OFFERING_FOR_KUBERNETES_SERVICE_NAME,
"Network Offering used for CloudStack Kubernetes service", Networks.TrafficType.Guest,
new NetworkOfferingVO(offeringName,
offeringDesc, Networks.TrafficType.Guest,
false, false, null, null, true,
NetworkOffering.Availability.Required, null, Network.GuestType.Isolated, true,
true, false, false, false, false,
false, false, false, true, true, false,
false, true, false, false);
forVpc, true, false, false);
if (forNsx) {
defaultKubernetesServiceNetworkOffering.setNsxMode(NetworkOffering.NsxMode.NATTED.name());
defaultKubernetesServiceNetworkOffering.setForNsx(true);
}
defaultKubernetesServiceNetworkOffering.setSupportsVmAutoScaling(true);
defaultKubernetesServiceNetworkOffering.setState(NetworkOffering.State.Enabled);
defaultKubernetesServiceNetworkOffering = networkOfferingDao.persistDefaultNetworkOffering(defaultKubernetesServiceNetworkOffering);
@ -1926,11 +1959,6 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
networkOfferingServiceMapDao.persist(offService);
LOGGER.trace("Added service for the network offering: " + offService);
}
_gcExecutor.scheduleWithFixedDelay(new KubernetesClusterGarbageCollector(), 300, 300, TimeUnit.SECONDS);
_stateScanner.scheduleWithFixedDelay(new KubernetesClusterStatusScanner(), 300, 30, TimeUnit.SECONDS);
return true;
}
@Override

View File

@ -31,6 +31,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.user.firewall.CreateFirewallRuleCmd;
@ -149,6 +151,8 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected VolumeApiService volumeService;
@Inject
protected VolumeDao volumeDao;
@Inject
protected NetworkOfferingDao networkOfferingDao;
protected String kubernetesClusterNodeNamePrefix;
@ -738,12 +742,24 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
protected void setupKubernetesClusterVpcTierRules(IpAddress publicIp, Network network, List<Long> clusterVMIds) throws ManagementServerException {
// Create ACL rules
createVpcTierAclRules(network);
// Add port forwarding for API access
try {
provisionPublicIpPortForwardingRule(publicIp, network, owner, clusterVMIds.get(0), CLUSTER_API_PORT, CLUSTER_API_PORT);
} catch (ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to activate API port forwarding rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
NetworkOffering offering = networkOfferingDao.findById(network.getNetworkOfferingId());
if (offering.isConserveMode()) {
// Add load balancing for API access
try {
provisionLoadBalancerRule(publicIp, network, owner, clusterVMIds, CLUSTER_API_PORT);
} catch (InsufficientAddressCapacityException e) {
throw new ManagementServerException(String.format("Failed to activate API load balancing rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
}
} else {
// Add port forwarding for API access
try {
provisionPublicIpPortForwardingRule(publicIp, network, owner, clusterVMIds.get(0), CLUSTER_API_PORT, CLUSTER_API_PORT);
} catch (ResourceUnavailableException | NetworkRuleConflictException e) {
throw new ManagementServerException(String.format("Failed to activate API port forwarding rules for the Kubernetes cluster : %s", kubernetesCluster.getName()), e);
}
}
// Add port forwarding rule for SSH access on each node VM
try {
provisionSshPortForwardingRules(publicIp, network, owner, clusterVMIds);

View File

@ -23,6 +23,8 @@ import java.util.List;
public interface KubernetesClusterVmMapDao extends GenericDao<KubernetesClusterVmMapVO, Long> {
public List<KubernetesClusterVmMapVO> listByClusterId(long clusterId);
public KubernetesClusterVmMapVO getClusterMapFromVmId(long vmId);
public List<KubernetesClusterVmMapVO> listByClusterIdAndVmIdsIn(long clusterId, List<Long> vmIds);
int removeByClusterIdAndVmIdsIn(long clusterId, List<Long> vmIds);

View File

@ -31,12 +31,17 @@ import com.cloud.utils.db.SearchCriteria;
public class KubernetesClusterVmMapDaoImpl extends GenericDaoBase<KubernetesClusterVmMapVO, Long> implements KubernetesClusterVmMapDao {
private final SearchBuilder<KubernetesClusterVmMapVO> clusterIdSearch;
private final SearchBuilder<KubernetesClusterVmMapVO> vmIdSearch;
public KubernetesClusterVmMapDaoImpl() {
clusterIdSearch = createSearchBuilder();
clusterIdSearch.and("clusterId", clusterIdSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
clusterIdSearch.and("vmIdsIN", clusterIdSearch.entity().getVmId(), SearchCriteria.Op.IN);
clusterIdSearch.done();
vmIdSearch = createSearchBuilder();
vmIdSearch.and("vmId", vmIdSearch.entity().getVmId(), SearchCriteria.Op.EQ);
vmIdSearch.done();
}
@Override
@ -47,6 +52,13 @@ public class KubernetesClusterVmMapDaoImpl extends GenericDaoBase<KubernetesClus
return listBy(sc, filter);
}
@Override
public KubernetesClusterVmMapVO getClusterMapFromVmId(long vmId) {
SearchCriteria<KubernetesClusterVmMapVO> sc = vmIdSearch.create();
sc.setParameters("vmId", vmId);
return findOneBy(sc);
}
@Override
public List<KubernetesClusterVmMapVO> listByClusterIdAndVmIdsIn(long clusterId, List<Long> vmIds) {
SearchCriteria<KubernetesClusterVmMapVO> sc = clusterIdSearch.create();

View File

@ -145,7 +145,7 @@ public class BigSwitchBcfGuestNetworkGuru extends GuestNetworkGuru implements Ne
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
// Check if the isolation type of the physical network is BCF_SEGMENT, then delegate GuestNetworkGuru to design
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
if (physnet == null || physnet.getIsolationMethods() == null || !physnet.getIsolationMethods().contains("BCF_SEGMENT")) {
@ -164,7 +164,7 @@ public class BigSwitchBcfGuestNetworkGuru extends GuestNetworkGuru implements Ne
}
s_logger.debug("Physical isolation type is BCF_SEGMENT, asking GuestNetworkGuru to design this network");
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, name, vpcId, owner);
if (networkObject == null) {
return null;
}

View File

@ -97,7 +97,7 @@ public class BrocadeVcsGuestNetworkGuru extends GuestNetworkGuru {
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
// Check of the isolation type of the related physical network is VLAN
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
@ -106,7 +106,7 @@ public class BrocadeVcsGuestNetworkGuru extends GuestNetworkGuru {
return null;
}
s_logger.debug("Physical isolation type is VCS, asking GuestNetworkGuru to design this network");
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, owner);
NetworkVO networkObject = (NetworkVO)super.design(offering, plan, userSpecified, name, vpcId, owner);
if (networkObject == null) {
return null;
}

View File

@ -170,7 +170,7 @@ public class BrocadeVcsGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork != null);
assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Vcs);
}
@ -191,7 +191,7 @@ public class BrocadeVcsGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork == null);
}
@ -213,7 +213,7 @@ public class BrocadeVcsGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork == null);
}

View File

@ -119,7 +119,7 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru {
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
// Check of the isolation type of the related physical network is L3VPN
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
@ -138,6 +138,11 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru {
return network;
}
@Override
public void setup(Network network, long networkId) {
// do nothing
}
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
throws InsufficientVirtualNetworkCapacityException {

View File

@ -219,7 +219,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, null, null, true, null);
Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, null, null, null, true, null);
long id = voffer.getId();
_networkOfferingDao.update(id, voffer);
return _networkOfferingDao.findById(id);
@ -254,7 +254,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, null, null, true, null);
Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, null, null, null, true, null);
if (offeringName.equals(vpcRouterOfferingName)) {
voffer.setInternalLb(true);
}
@ -295,7 +295,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
}
serviceProviderMap.put(svc, providerSet);
}
vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, null, null, VpcOffering.State.Enabled);
vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, false, null, null, null, VpcOffering.State.Enabled);
long id = vpcOffer.getId();
_vpcOffDao.update(id, (VpcOfferingVO)vpcOffer);
return _vpcOffDao.findById(id);

View File

@ -111,7 +111,7 @@ public class ManagementNetworkGuru extends ContrailGuru {
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
if (!canHandle(offering)) {
return null;

View File

@ -138,7 +138,7 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru implements Netwo
}
@Override
public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) {
public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, String name, Long vpcId, final Account owner) {
// Check of the isolation type of the related physical network is supported
final PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId());
final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
@ -155,7 +155,7 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru implements Netwo
s_logger.debug("Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());
s_logger.debug("Physical isolation type is supported, asking GuestNetworkGuru to design this network");
final NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, owner);
final NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, name, vpcId, owner);
if (networkObject == null) {
return null;
}

View File

@ -168,7 +168,7 @@ public class NiciraNvpGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork != null);
assertTrue(designednetwork.getBroadcastDomainType() == BroadcastDomainType.Lswitch);
}
@ -192,7 +192,7 @@ public class NiciraNvpGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork == null);
}
@ -215,7 +215,7 @@ public class NiciraNvpGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork == null);
}
@ -241,7 +241,7 @@ public class NiciraNvpGuestNetworkGuruTest {
final Network network = mock(Network.class);
final Account account = mock(Account.class);
final Network designednetwork = guru.design(offering, plan, network, account);
final Network designednetwork = guru.design(offering, plan, network, "", 1L, account);
assertTrue(designednetwork == null);
}

View File

@ -0,0 +1,59 @@
<!--
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-nsx</artifactId>
<name>Apache CloudStack Plugin - NSX Network</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.19.0.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.vmware</groupId>
<artifactId>nsx-java-sdk</artifactId>
<version>4.1.0.2.0</version>
</dependency>
<dependency>
<groupId>com.vmware</groupId>
<artifactId>nsx-gpm-java-sdk</artifactId>
<version>4.1.0.2.0</version>
</dependency>
<dependency>
<groupId>com.vmware</groupId>
<artifactId>nsx-policy-java-sdk</artifactId>
<version>4.1.0.2.0</version>
</dependency>
<dependency>
<groupId>com.vmware.vapi</groupId>
<artifactId>vapi-authentication</artifactId>
<version>2.40.0</version>
</dependency>
<dependency>
<groupId>com.vmware.vapi</groupId>
<artifactId>vapi-runtime</artifactId>
<version>2.40.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,31 @@
// 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;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
public class NsxAnswer extends Answer {
public NsxAnswer(final Command command, final boolean success, final String details) {
super(command, success, details);
}
public NsxAnswer(final Command command, final Exception e) {
super(command, e);
}
}

View File

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

View File

@ -0,0 +1,77 @@
// 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 java.util.List;
import java.util.Objects;
public class CreateNsxDhcpRelayConfigCommand extends NsxCommand {
private Long vpcId;
private String vpcName;
private long networkId;
private String networkName;
private List<String> addresses;
public CreateNsxDhcpRelayConfigCommand(long domainId, long accountId, long zoneId,
Long vpcId, String vpcName, long networkId, String networkName,
List<String> addresses) {
super(domainId, accountId, zoneId);
this.vpcId = vpcId;
this.vpcName = vpcName;
this.networkId = networkId;
this.networkName = networkName;
this.addresses = addresses;
}
public Long getVpcId() {
return vpcId;
}
public String getVpcName() {
return vpcName;
}
public long getNetworkId() {
return networkId;
}
public String getNetworkName() {
return networkName;
}
public List<String> getAddresses() {
return addresses;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
CreateNsxDhcpRelayConfigCommand that = (CreateNsxDhcpRelayConfigCommand) o;
return networkId == that.networkId && Objects.equals(vpcId, that.vpcId) && Objects.equals(vpcName, that.vpcName) && Objects.equals(networkName, that.networkName) && Objects.equals(addresses, that.addresses);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), vpcId, vpcName, networkId, networkName, addresses);
}
}

View File

@ -0,0 +1,67 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.agent.api;
import org.apache.cloudstack.resource.NsxNetworkRule;
import java.util.List;
import java.util.Objects;
public class CreateNsxDistributedFirewallRulesCommand extends NsxCommand {
private Long vpcId;
private long networkId;
private List<NsxNetworkRule> rules;
public CreateNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId,
Long vpcId, long networkId,
List<NsxNetworkRule> rules) {
super(domainId, accountId, zoneId);
this.vpcId = vpcId;
this.networkId = networkId;
this.rules = rules;
}
public Long getVpcId() {
return vpcId;
}
public long getNetworkId() {
return networkId;
}
public List<NsxNetworkRule> getRules() {
return rules;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
CreateNsxDistributedFirewallRulesCommand that = (CreateNsxDistributedFirewallRulesCommand) o;
return networkId == that.networkId && Objects.equals(vpcId, that.vpcId) && Objects.equals(rules, that.rules);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), vpcId, networkId, rules);
}
}

View File

@ -0,0 +1,87 @@
// 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.NsxLoadBalancerMember;
import java.util.List;
import java.util.Objects;
public class CreateNsxLoadBalancerRuleCommand extends NsxNetworkCommand {
private final String publicPort;
private final String privatePort;
private final String algorithm;
private final String protocol;
List<NsxLoadBalancerMember> memberList;
private final long lbId;
public CreateNsxLoadBalancerRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId,
String networkResourceName, boolean isResourceVpc,
List<NsxLoadBalancerMember> memberList, long lbId, String publicPort,
String privatePort, String algorithm, String protocol) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc);
this.lbId = lbId;
this.memberList = memberList;
this.publicPort = publicPort;
this.privatePort = privatePort;
this.algorithm = algorithm;
this.protocol = protocol;
}
public long getLbId() {
return lbId;
}
public String getPublicPort() {
return publicPort;
}
public String getPrivatePort() {
return privatePort;
}
public List<NsxLoadBalancerMember> getMemberList() {
return memberList;
}
public String getAlgorithm() {
return algorithm;
}
public String getProtocol() {
return protocol;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
CreateNsxLoadBalancerRuleCommand command = (CreateNsxLoadBalancerRuleCommand) o;
return lbId == command.lbId && Objects.equals(publicPort, command.publicPort) && Objects.equals(privatePort, command.privatePort) && Objects.equals(algorithm, command.algorithm) && Objects.equals(protocol, command.protocol) && Objects.equals(memberList, command.memberList);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), publicPort, privatePort, algorithm, protocol, memberList, lbId);
}
}

View File

@ -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 java.util.Objects;
public class CreateNsxPortForwardRuleCommand extends NsxNetworkCommand {
private final String publicPort;
private final String privatePort;
private final String protocol;
private final long ruleId;
public CreateNsxPortForwardRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId,
String networkResourceName, boolean isResourceVpc, Long vmId,
long ruleId, String publicIp, String vmIp, String publicPort, String privatePort, String protocol) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc, vmId, publicIp, vmIp);
this.publicPort = publicPort;
this.privatePort = privatePort;
this.ruleId = ruleId;
this.protocol = protocol;
}
public String getPublicPort() {
return publicPort;
}
public String getPrivatePort() {
return privatePort;
}
public long getRuleId() {
return ruleId;
}
public String getProtocol() {
return protocol;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
CreateNsxPortForwardRuleCommand that = (CreateNsxPortForwardRuleCommand) o;
return ruleId == that.ruleId && Objects.equals(publicPort, that.publicPort) && Objects.equals(privatePort, that.privatePort) && Objects.equals(protocol, that.protocol);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), publicPort, privatePort, protocol, ruleId);
}
}

View File

@ -0,0 +1,79 @@
// 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 java.util.Objects;
public class CreateNsxSegmentCommand extends NsxCommand {
private Long vpcId;
private String vpcName;
private long networkId;
private String networkName;
private String networkGateway;
private String networkCidr;
public CreateNsxSegmentCommand(long domainId, long accountId, long zoneId,
Long vpcId, String vpcName, long networkId, String networkName,
String networkGateway, String networkCidr) {
super(domainId, accountId, zoneId);
this.vpcId = vpcId;
this.vpcName = vpcName;
this.networkId = networkId;
this.networkName = networkName;
this.networkGateway = networkGateway;
this.networkCidr = networkCidr;
}
public Long getVpcId() {
return vpcId;
}
public String getVpcName() {
return vpcName;
}
public long getNetworkId() {
return networkId;
}
public String getNetworkName() {
return networkName;
}
public String getNetworkGateway() {
return networkGateway;
}
public String getNetworkCidr() {
return networkCidr;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
CreateNsxSegmentCommand command = (CreateNsxSegmentCommand) o;
return Objects.equals(networkName, command.networkName);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), networkName);
}
}

View File

@ -0,0 +1,25 @@
// 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 CreateNsxStaticNatCommand extends NsxNetworkCommand {
public CreateNsxStaticNatCommand(long domainId, long accountId, long zoneId, Long networkResourceId, String networkResourceName,
boolean isResourceVpc, Long vmId, String publicIp, String vmIp) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc, vmId, publicIp, vmIp);
}
}

View File

@ -0,0 +1,67 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.agent.api;
import java.util.Objects;
public class CreateNsxTier1GatewayCommand extends NsxCommand {
private Long networkResourceId;
private String networkResourceName;
private boolean isResourceVpc;
private boolean sourceNatEnabled;
public CreateNsxTier1GatewayCommand(long domainId, long accountId, long zoneId,
Long networkResourceId, String networkResourceName, boolean isResourceVpc,
boolean sourceNatEnabled) {
super(domainId, accountId, zoneId);
this.networkResourceId = networkResourceId;
this.networkResourceName = networkResourceName;
this.isResourceVpc = isResourceVpc;
this.sourceNatEnabled = sourceNatEnabled;
}
public Long getNetworkResourceId() {
return networkResourceId;
}
public boolean isResourceVpc() {
return isResourceVpc;
}
public String getNetworkResourceName() {
return networkResourceName;
}
public boolean isSourceNatEnabled() {
return sourceNatEnabled;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
CreateNsxTier1GatewayCommand that = (CreateNsxTier1GatewayCommand) o;
return Objects.equals(networkResourceName, that.networkResourceName);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), networkResourceName);
}
}

View File

@ -0,0 +1,69 @@
// 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 java.util.Objects;
public class CreateOrUpdateNsxTier1NatRuleCommand extends NsxCommand {
private String tier1GatewayName;
private String action;
private String translatedIpAddress;
private String natRuleId;
public CreateOrUpdateNsxTier1NatRuleCommand(long domainId, long accountId, long zoneId,
String tier1GatewayName, String action, String translatedIpAddress, String natRuleId) {
super(domainId, accountId, zoneId);
this.tier1GatewayName = tier1GatewayName;
this.action = action;
this.translatedIpAddress = translatedIpAddress;
this.natRuleId = natRuleId;
}
public String getTier1GatewayName() {
return tier1GatewayName;
}
public String getAction() {
return action;
}
public String getTranslatedIpAddress() {
return translatedIpAddress;
}
public String getNatRuleId() {
return natRuleId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
CreateOrUpdateNsxTier1NatRuleCommand that = (CreateOrUpdateNsxTier1NatRuleCommand) o;
return Objects.equals(tier1GatewayName, that.tier1GatewayName) && Objects.equals(action, that.action) && Objects.equals(translatedIpAddress, that.translatedIpAddress) && Objects.equals(natRuleId, that.natRuleId);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), tier1GatewayName, action, translatedIpAddress, natRuleId);
}
}

View File

@ -0,0 +1,27 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.agent.api;
import org.apache.cloudstack.resource.NsxNetworkRule;
import java.util.List;
public class DeleteNsxDistributedFirewallRulesCommand extends CreateNsxDistributedFirewallRulesCommand {
public DeleteNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId, Long vpcId, long networkId, List<NsxNetworkRule> rules) {
super(domainId, accountId, zoneId, vpcId, networkId, rules);
}
}

View File

@ -0,0 +1,58 @@
// 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.NsxLoadBalancerMember;
import java.util.List;
import java.util.Objects;
public class DeleteNsxLoadBalancerRuleCommand extends NsxNetworkCommand {
private long lbId;
List<NsxLoadBalancerMember> memberList;
public DeleteNsxLoadBalancerRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId,
String networkResourceName, boolean isResourceVpc,
List<NsxLoadBalancerMember> memberList, long lbId, long vmId) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc, vmId);
this.lbId = lbId;
this.memberList = memberList;
}
public long getLbId() {
return lbId;
}
public List<NsxLoadBalancerMember> getMemberList() { return memberList; }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
DeleteNsxLoadBalancerRuleCommand that = (DeleteNsxLoadBalancerRuleCommand) o;
return lbId == that.lbId && Objects.equals(memberList, that.memberList);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), lbId, memberList);
}
}

View File

@ -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.agent.api;
import com.cloud.network.Network;
import java.util.Objects;
public class DeleteNsxNatRuleCommand extends NsxNetworkCommand {
private Long ruleId;
private Network.Service service;
private String privatePort;
private String protocol;
public DeleteNsxNatRuleCommand(long domainId, long accountId, long zoneId, Long networkResourceId, String networkResourceName,
boolean isResourceVpc, Long vmId, Long ruleId, String privatePort, String protocol) {
super(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc, vmId);
this.ruleId = ruleId;
this.privatePort = privatePort;
this.protocol = protocol;
}
public Long getRuleId() {
return ruleId;
}
public Network.Service getService() {
return service;
}
public void setService(Network.Service service) {
this.service = service;
}
public String getPrivatePort() {
return privatePort;
}
public String getProtocol() {
return protocol;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
DeleteNsxNatRuleCommand that = (DeleteNsxNatRuleCommand) o;
return Objects.equals(ruleId, that.ruleId) && Objects.equals(service, that.service) && Objects.equals(privatePort, that.privatePort) && Objects.equals(protocol, that.protocol);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), ruleId, service, privatePort, protocol);
}
}

View File

@ -0,0 +1,70 @@
// 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 java.util.Objects;
public class DeleteNsxSegmentCommand extends NsxCommand {
private Long vpcId;
private String vpcName;
private long networkId;
private String networkName;
public DeleteNsxSegmentCommand(long domainId, long accountId, long zoneId, Long vpcId,
String vpcName, long networkId, String networkName) {
super(domainId, accountId, zoneId);
this.vpcId = vpcId;
this.vpcName = vpcName;
this.networkId = networkId;
this.networkName = networkName;
}
public Long getVpcId() {
return vpcId;
}
public String getVpcName() {
return vpcName;
}
public long getNetworkId() {
return networkId;
}
public String getNetworkName() {
return networkName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
DeleteNsxSegmentCommand command = (DeleteNsxSegmentCommand) o;
return networkId == command.networkId && Objects.equals(vpcId, command.vpcId) && Objects.equals(vpcName, command.vpcName) && Objects.equals(networkName, command.networkName);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), vpcId, vpcName, networkId, networkName);
}
}

View File

@ -0,0 +1,63 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.agent.api;
import java.util.Objects;
public class DeleteNsxTier1GatewayCommand extends NsxCommand {
private Long networkResourceId;
private String networkResourceName;
private boolean isResourceVpc;
public DeleteNsxTier1GatewayCommand(long domainId, long accountId, long zoneId,
Long networkResourceId, String networkResourceName, boolean isResourceVpc) {
super(domainId, accountId, zoneId);
this.networkResourceId = networkResourceId;
this.networkResourceName = networkResourceName;
this.isResourceVpc = isResourceVpc;
}
public Long getNetworkResourceId() {
return networkResourceId;
}
public String getNetworkResourceName() {
return networkResourceName;
}
public boolean isResourceVpc() {
return isResourceVpc;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass() || !super.equals(o)) {
return false;
}
DeleteNsxTier1GatewayCommand that = (DeleteNsxTier1GatewayCommand) o;
return isResourceVpc == that.isResourceVpc && Objects.equals(networkResourceId, that.networkResourceId) && Objects.equals(networkResourceName, that.networkResourceName);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), networkResourceId, networkResourceName, isResourceVpc);
}
}

View File

@ -0,0 +1,67 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.agent.api;
import com.cloud.agent.api.Command;
import java.util.Objects;
public class NsxCommand extends Command {
private long zoneId;
private long accountId;
private long domainId;
public NsxCommand() {
}
public NsxCommand(long domainId, long accountId, long zoneId) {
this.zoneId = zoneId;
this.accountId = accountId;
this.domainId = domainId;
}
public long getZoneId() {
return zoneId;
}
public long getAccountId() {
return accountId;
}
public long getDomainId() {
return domainId;
}
@Override
public boolean executeInSequence() {
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
NsxCommand that = (NsxCommand) o;
return Objects.equals(zoneId, that.zoneId) && Objects.equals(accountId, that.accountId) && Objects.equals(domainId, that.domainId);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), zoneId, accountId, domainId);
}
}

View File

@ -0,0 +1,117 @@
// 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 java.util.Objects;
public class NsxNetworkCommand extends NsxCommand {
private Long networkResourceId;
private String networkResourceName;
private boolean isResourceVpc;
private Long vmId;
private String publicIp;
private String vmIp;
public NsxNetworkCommand(long domainId, long accountId, long zoneId, Long networkResourceId, String networkResourceName,
boolean isResourceVpc, Long vmId, String publicIp, String vmIp) {
super(domainId, accountId, zoneId);
this.networkResourceId = networkResourceId;
this.networkResourceName = networkResourceName;
this.isResourceVpc = isResourceVpc;
this.vmId = vmId;
this.publicIp = publicIp;
this.vmIp = vmIp;
}
public NsxNetworkCommand(long domainId, long accountId, long zoneId, Long networkResourceId, String networkResourceName,
boolean isResourceVpc) {
super(domainId, accountId, zoneId);
this.networkResourceId = networkResourceId;
this.networkResourceName = networkResourceName;
this.isResourceVpc = isResourceVpc;
}
public NsxNetworkCommand(long domainId, long accountId, long zoneId, Long networkResourceId, String networkResourceName,
boolean isResourceVpc, Long vmId) {
this(domainId, accountId, zoneId, networkResourceId, networkResourceName, isResourceVpc);
this.vmId = vmId;
}
public Long getNetworkResourceId() {
return networkResourceId;
}
public void setNetworkResourceId(long networkResourceId) {
this.networkResourceId = networkResourceId;
}
public String getNetworkResourceName() {
return networkResourceName;
}
public void setNetworkResourceName(String networkResourceName) {
this.networkResourceName = networkResourceName;
}
public boolean isResourceVpc() {
return isResourceVpc;
}
public void setResourceVpc(boolean resourceVpc) {
isResourceVpc = resourceVpc;
}
public Long getVmId() {
return vmId;
}
public void setVmId(Long vmId) {
this.vmId = vmId;
}
public String getPublicIp() {
return publicIp;
}
public void setPublicIp(String publicIp) {
this.publicIp = publicIp;
}
public String getVmIp() {
return vmIp;
}
public void setVmIp(String vmIp) {
this.vmIp = vmIp;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
NsxNetworkCommand that = (NsxNetworkCommand) o;
return networkResourceId == that.networkResourceId && vmId == that.vmId &&
Objects.equals(networkResourceName, that.networkResourceName) && Objects.equals(publicIp, that.publicIp)
&& Objects.equals(vmIp, that.vmIp);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), networkResourceId, networkResourceName, vmId, publicIp, vmIp);
}
}

View File

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

View File

@ -0,0 +1,130 @@
// 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.network.nsx.NsxProvider;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.response.NsxControllerResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.service.NsxProviderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
@APICommand(name = AddNsxControllerCmd.APINAME, description = "Add NSX Controller to CloudStack",
responseObject = NsxControllerResponse.class, requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false, since = "4.19.0")
public class AddNsxControllerCmd extends BaseCmd {
public static final String APINAME = "addNsxController";
public static final Logger LOGGER = LoggerFactory.getLogger(AddNsxControllerCmd.class.getName());
@Inject
NsxProviderService nsxProviderService;
@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 = "NSX controller / provider name")
private String name;
@Parameter(name = ApiConstants.NSX_PROVIDER_HOSTNAME, type = CommandType.STRING, required = true, description = "NSX controller hostname / IP address")
private String hostname;
@Parameter(name = ApiConstants.NSX_PROVIDER_PORT, type = CommandType.STRING, description = "NSX controller port")
private String port;
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Username to log into NSX controller")
private String username;
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Password to login into NSX controller")
private String password;
@Parameter(name = ApiConstants.TIER0_GATEWAY, type = CommandType.STRING, required = true, description = "Tier-0 Gateway address")
private String tier0Gateway;
@Parameter(name = ApiConstants.EDGE_CLUSTER, type = CommandType.STRING, required = true, description = "Edge Cluster name")
private String edgeCluster;
@Parameter(name = ApiConstants.TRANSPORT_ZONE, type = CommandType.STRING, required = true, description = "Transport Zone controls to which hosts a logical switch can reach")
private String transportZone;
public NsxProviderService getNsxProviderService() {
return nsxProviderService;
}
public Long getZoneId() {
return zoneId;
}
public String getName() {
return name;
}
public String getHostname() {
return hostname;
}
public String getPort() {
return port;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getTier0Gateway() {
return tier0Gateway;
}
public String getEdgeCluster() {
return edgeCluster;
}
public String getTransportZone() {
return transportZone;
}
@Override
public void execute() throws ServerApiException {
NsxProvider nsxProvider = nsxProviderService.addProvider(this);
NsxControllerResponse nsxControllerResponse =
nsxProviderService.createNsxControllerResponse(
nsxProvider);
if (nsxControllerResponse == null)
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NSX controller");
else {
nsxControllerResponse.setResponseName(getCommandName());
setResponseObject(nsxControllerResponse);
}
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -0,0 +1,87 @@
// 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.InvalidParameterValueException;
import com.cloud.exception.ConcurrentOperationException;
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.response.SuccessResponse;
import org.apache.cloudstack.service.NsxProviderService;
import javax.inject.Inject;
import static org.apache.cloudstack.api.command.DeleteNsxControllerCmd.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";
@Inject
protected NsxProviderService nsxProviderService;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NSX_CONTROLLER_ID, type = CommandType.UUID, entityType = NsxControllerResponse.class,
required = true, description = "NSX Controller ID")
private Long nsxControllerId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getNsxControllerId() {
return nsxControllerId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ServerApiException, ConcurrentOperationException {
try {
boolean deleted = nsxProviderService.deleteNsxController(getNsxControllerId());
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");
}
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
} catch (CloudRuntimeException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
@Override
public long getEntityOwnerId() {
return 0;
}
}

View File

@ -0,0 +1,68 @@
// 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.ApiConstants;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.NsxControllerResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.service.NsxProviderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.List;
import static org.apache.cloudstack.api.command.ListNsxControllersCmd.APINAME;
@APICommand(name = APINAME, description = "list all NSX controllers added to CloudStack",
responseObject = NsxControllerResponse.class, requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false, since = "4.19.0")
public class ListNsxControllersCmd extends BaseListCmd {
public static final String APINAME = "listNsxControllers";
public static final Logger LOGGER = LoggerFactory.getLogger(ListNsxControllersCmd.class.getName());
@Inject
private NsxProviderService nsxProviderService;
@Parameter(name = ApiConstants.ZONE_ID, description = "NSX controller added to the specific zone",
type = CommandType.UUID, entityType = ZoneResponse.class)
Long zoneId;
@Override
public void execute() throws ServerApiException, ConcurrentOperationException {
List<BaseResponse> baseResponseList = nsxProviderService.listNsxProviders(zoneId);
List<BaseResponse> pagingList = StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
ListResponse<BaseResponse> listResponse = new ListResponse<>();
listResponse.setResponses(pagingList);
listResponse.setResponseName(getCommandName());
setResponseObject(listResponse);
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
}

View File

@ -0,0 +1,136 @@
// 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.nsx.NsxProvider;
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 = {NsxProvider.class})
public class NsxControllerResponse extends BaseResponse {
@SerializedName(ApiConstants.NSX_PROVIDER_UUID)
@Param(description = "NSX controller ID")
private String uuid;
@SerializedName(ApiConstants.NAME)
@Param(description = "NSX controller name")
private String name;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "Zone ID to which the NSX controller is associated with")
private String zoneId;
@SerializedName(ApiConstants.ZONE_NAME)
@Param(description = "Zone name to which the NSX controller is associated with")
private String zoneName;
@SerializedName(ApiConstants.HOST_NAME)
@Param(description = "NSX controller hostname or IP address")
private String hostname;
@SerializedName(ApiConstants.PORT)
@Param(description = "NSX controller port")
private String port;
@SerializedName(ApiConstants.TIER0_GATEWAY)
@Param(description = "The tier-0 gateway network. Tier-0 gateway is responsible for handling" +
" traffic between logical and physical networks"
)
private String tier0Gateway;
@SerializedName(ApiConstants.EDGE_CLUSTER)
@Param(description = "The name of the edge cluster. An edge cluster is a logical grouping of edge nodes in NSX")
private String edgeCluster;
@SerializedName(ApiConstants.TRANSPORT_ZONE)
@Param(description = "The name of the transport zone. A transport zone controls to which hosts a logical switch can reach")
private String transportZone;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 getTier0Gateway() {
return tier0Gateway;
}
public void setTier0Gateway(String tier0Gateway) {
this.tier0Gateway = tier0Gateway;
}
public String getEdgeCluster() {
return edgeCluster;
}
public void setEdgeCluster(String edgeCluster) {
this.edgeCluster = edgeCluster;
}
public String getTransportZone() {
return transportZone;
}
public void setTransportZone(String transportZone) {
this.transportZone = transportZone;
}
}

View File

@ -0,0 +1,41 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.resource;
public class NsxLoadBalancerMember {
private long vmId;
private String vmIp;
private int port;
public NsxLoadBalancerMember(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;
}
}

View File

@ -0,0 +1,397 @@
// 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.network.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 long getDomainId() {
return domainId;
}
public void setDomainId(long domainId) {
this.domainId = domainId;
}
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public long getZoneId() {
return zoneId;
}
public void setZoneId(long zoneId) {
this.zoneId = zoneId;
}
public Long getNetworkResourceId() {
return networkResourceId;
}
public void setNetworkResourceId(Long networkResourceId) {
this.networkResourceId = networkResourceId;
}
public String getNetworkResourceName() {
return networkResourceName;
}
public void setNetworkResourceName(String networkResourceName) {
this.networkResourceName = networkResourceName;
}
public boolean isVpcResource() {
return isVpcResource;
}
public void setVpcResource(boolean vpcResource) {
isVpcResource = vpcResource;
}
public long getVmId() {
return vmId;
}
public void setVmId(long vmId) {
this.vmId = vmId;
}
public long getRuleId() {
return ruleId;
}
public void setRuleId(long ruleId) {
this.ruleId = ruleId;
}
public String getPublicIp() {
return publicIp;
}
public void setPublicIp(String publicIp) {
this.publicIp = publicIp;
}
public String getVmIp() {
return vmIp;
}
public void setVmIp(String vmIp) {
this.vmIp = vmIp;
}
public String getPublicPort() {
return publicPort;
}
public void setPublicPort(String publicPort) {
this.publicPort = publicPort;
}
public String getPrivatePort() {
return privatePort;
}
public void setPrivatePort(String privatePort) {
this.privatePort = privatePort;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getAlgorithm() {
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;
}
public void setService(Network.Service service) {
this.service = service;
}
public Integer getIcmpCode() {
return icmpCode;
}
public void setIcmpCode(Integer icmpCode) {
this.icmpCode = icmpCode;
}
public Integer getIcmpType() {
return icmpType;
}
public void setIcmpType(Integer icmpType) {
this.icmpType = icmpType;
}
public List<String> getSourceCidrList() {
return sourceCidrList;
}
public void setSourceCidrList(List<String> sourceCidrList) {
this.sourceCidrList = sourceCidrList;
}
public List<String> getDestinationCidrList() {
return destinationCidrList;
}
public void setDestinationCidrList(List<String> destinationCidrList) {
this.destinationCidrList = destinationCidrList;
}
public String getTrafficType() {
return trafficType;
}
public void setTrafficType(String trafficType) {
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 Builder() {
// Default constructor
}
public Builder setDomainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder setAccountId(long accountId) {
this.accountId = accountId;
return this;
}
public Builder setZoneId(long zoneId) {
this.zoneId = zoneId;
return this;
}
public Builder setNetworkResourceId(Long networkResourceId) {
this.networkResourceId = networkResourceId;
return this;
}
public Builder setNetworkResourceName(String networkResourceName) {
this.networkResourceName = networkResourceName;
return this;
}
public Builder setVpcResource(boolean isVpcResource) {
this.isVpcResource = isVpcResource;
return this;
}
public Builder setVmId(long vmId) {
this.vmId = vmId;
return this;
}
public Builder setRuleId(long ruleId) {
this.ruleId = ruleId;
return this;
}
public Builder setPublicIp(String publicIp) {
this.publicIp = publicIp;
return this;
}
public Builder setVmIp(String vmIp) {
this.vmIp = vmIp;
return this;
}
public Builder setPublicPort(String publicPort) {
this.publicPort = publicPort;
return this;
}
public Builder setPrivatePort(String privatePort) {
this.privatePort = privatePort;
return this;
}
public Builder setProtocol(String protocol) {
this.protocol = protocol;
return this;
}
public Builder setAlgorithm(String algorithm) {
this.algorithm = algorithm;
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;
}
public Builder setIcmpType(Integer icmpType) {
this.icmpType = icmpType;
return this;
}
public Builder setIcmpCode(Integer icmpCode) {
this.icmpCode = icmpCode;
return this;
}
public Builder setSourceCidrList(List<String> sourceCidrList) {
this.sourceCidrList = sourceCidrList;
return this;
}
public Builder setDestinationCidrList(List<String> destinationCidrList) {
this.destinationidrList = destinationCidrList;
return this;
}
public Builder setService(Network.Service service) {
this.service = service;
return this;
}
public NsxNetworkRule build() {
NsxNetworkRule rule = new NsxNetworkRule();
rule.setDomainId(this.domainId);
rule.setAccountId(this.accountId);
rule.setZoneId(this.zoneId);
rule.setNetworkResourceId(this.networkResourceId);
rule.setNetworkResourceName(this.networkResourceName);
rule.setVpcResource(this.isVpcResource);
rule.setVmId(this.vmId);
rule.setVmIp(this.vmIp);
rule.setPublicIp(this.publicIp);
rule.setPublicPort(this.publicPort);
rule.setPrivatePort(this.privatePort);
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.setTrafficType(this.trafficType);
rule.setService(service);
return rule;
}
}
}

View File

@ -0,0 +1,129 @@
// 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.network.dao.NetworkVO;
import com.cloud.network.vpc.VpcVO;
import java.util.Objects;
public class NsxOpObject {
VpcVO vpcVO;
NetworkVO networkVO;
long accountId;
long domainId;
long zoneId;
public VpcVO getVpcVO() {
return vpcVO;
}
public void setVpcVO(VpcVO vpcVO) {
this.vpcVO = vpcVO;
}
public NetworkVO getNetworkVO() {
return networkVO;
}
public void setNetworkVO(NetworkVO networkVO) {
this.networkVO = networkVO;
}
public long getAccountId() {
return accountId;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public long getDomainId() {
return domainId;
}
public void setDomainId(long domainId) {
this.domainId = domainId;
}
public long getZoneId() {
return zoneId;
}
public void setZoneId(long zoneId) {
this.zoneId = zoneId;
}
public String getNetworkResourceName() {
return Objects.nonNull(vpcVO) ? vpcVO.getName() : networkVO.getName();
}
public boolean isVpcResource() {
return Objects.nonNull(vpcVO);
}
public long getNetworkResourceId() {
return Objects.nonNull(vpcVO) ? vpcVO.getId() : networkVO.getId();
}
public static final class Builder {
VpcVO vpcVO;
NetworkVO networkVO;
long accountId;
long domainId;
long zoneId;
public Builder() {
// Default constructor
}
public Builder vpcVO(VpcVO vpcVO) {
this.vpcVO = vpcVO;
return this;
}
public Builder networkVO(NetworkVO networkVO) {
this.networkVO = networkVO;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder accountId(long accountId) {
this.accountId = accountId;
return this;
}
public Builder zoneId(long zoneId) {
this.zoneId = zoneId;
return this;
}
public NsxOpObject build() {
NsxOpObject object = new NsxOpObject();
object.setVpcVO(this.vpcVO);
object.setNetworkVO(this.networkVO);
object.setDomainId(this.domainId);
object.setAccountId(this.accountId);
object.setZoneId(this.zoneId);
return object;
}
}
}

View File

@ -0,0 +1,480 @@
// 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.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.Network;
import com.cloud.resource.ServerResource;
import com.cloud.utils.exception.CloudRuntimeException;
import com.vmware.nsx.model.TransportZone;
import com.vmware.nsx.model.TransportZoneListResult;
import com.vmware.nsx_policy.model.Segment;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.StartupNsxCommand;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
import org.apache.cloudstack.service.NsxApiClient;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import javax.naming.ConfigurationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public class NsxResource implements ServerResource {
private static final Logger LOGGER = Logger.getLogger(NsxResource.class);
private static final String DHCP_RELAY_CONFIGS_PATH_PREFIX = "/infra/dhcp-relay-configs";
private String name;
protected String hostname;
protected String username;
protected String password;
protected String guid;
protected String port;
protected String tier0Gateway;
protected String edgeCluster;
protected String transportZone;
protected String zoneId;
protected NsxApiClient nsxApiClient;
@Override
public Host.Type getType() {
return Host.Type.Routing;
}
@Override
public StartupCommand[] initialize() {
StartupNsxCommand sc = new StartupNsxCommand();
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 DeleteNsxTier1GatewayCommand) {
return executeRequest((DeleteNsxTier1GatewayCommand) cmd);
} else if (cmd instanceof DeleteNsxSegmentCommand) {
return executeRequest((DeleteNsxSegmentCommand) cmd);
} else if (cmd instanceof CreateNsxSegmentCommand) {
return executeRequest((CreateNsxSegmentCommand) cmd);
} else if (cmd instanceof CreateNsxTier1GatewayCommand) {
return executeRequest((CreateNsxTier1GatewayCommand) cmd);
} else if (cmd instanceof CreateNsxDhcpRelayConfigCommand) {
return executeRequest((CreateNsxDhcpRelayConfigCommand) cmd);
} else if (cmd instanceof CreateOrUpdateNsxTier1NatRuleCommand) {
return executeRequest((CreateOrUpdateNsxTier1NatRuleCommand) cmd);
} else if (cmd instanceof CreateNsxStaticNatCommand) {
return executeRequest((CreateNsxStaticNatCommand) cmd);
} else if (cmd instanceof DeleteNsxNatRuleCommand) {
return executeRequest((DeleteNsxNatRuleCommand) cmd);
} else if (cmd instanceof CreateNsxPortForwardRuleCommand) {
return executeRequest((CreateNsxPortForwardRuleCommand) cmd);
} else if (cmd instanceof CreateNsxLoadBalancerRuleCommand) {
return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) {
return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd);
} else if (cmd instanceof DeleteNsxDistributedFirewallRulesCommand) {
return executeRequest((DeleteNsxDistributedFirewallRulesCommand) cmd);
} else if (cmd instanceof CreateNsxDistributedFirewallRulesCommand) {
return executeRequest((CreateNsxDistributedFirewallRulesCommand) 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) {
// Do nothing
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
hostname = (String) params.get("hostname");
if (hostname == null) {
throw new ConfigurationException("Missing NSX hostname from params: " + params);
}
port = (String) params.get("port");
if (port == null) {
throw new ConfigurationException("Missing NSX port from params: " + params);
}
username = (String) params.get("username");
if (username == null) {
throw new ConfigurationException("Missing NSX username from params: " + params);
}
password = (String) params.get("password");
if (password == null) {
throw new ConfigurationException("Missing NSX 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");
}
tier0Gateway = (String) params.get("tier0Gateway");
if (tier0Gateway == null) {
throw new ConfigurationException("Missing NSX tier0 gateway");
}
edgeCluster = (String) params.get("edgeCluster");
if (edgeCluster == null) {
throw new ConfigurationException("Missing NSX edgeCluster");
}
transportZone = (String) params.get("transportZone");
if (transportZone == null) {
throw new ConfigurationException("Missing NSX transportZone");
}
nsxApiClient = new NsxApiClient(hostname, port, username, password.toCharArray());
return true;
}
private Answer executeRequest(CreateOrUpdateNsxTier1NatRuleCommand cmd) {
String tier1GatewayName = cmd.getTier1GatewayName();
String action = cmd.getAction();
String translatedIpAddress = cmd.getTranslatedIpAddress();
String natRuleId = cmd.getNatRuleId();
String natId = "USER";
try {
nsxApiClient.createTier1NatRule(tier1GatewayName, natId, natRuleId, action, translatedIpAddress);
} catch (CloudRuntimeException e) {
String msg = String.format("Error creating the NAT rule with ID %s on Tier1 Gateway %s: %s", natRuleId, tier1GatewayName, e.getMessage());
LOGGER.error(msg, e);
return new NsxAnswer(cmd, e);
}
return new NsxAnswer(cmd, true, "");
}
private Answer executeRequest(CreateNsxDhcpRelayConfigCommand cmd) {
long datacenterId = cmd.getZoneId();
long domainId = cmd.getDomainId();
long accountId = cmd.getAccountId();
Long vpcId = cmd.getVpcId();
long networkId = cmd.getNetworkId();
String vpcName = cmd.getVpcName();
String networkName = cmd.getNetworkName();
List<String> addresses = cmd.getAddresses();
String dhcpRelayConfigName = NsxControllerUtils.getNsxDhcpRelayConfigId(datacenterId, domainId, accountId, vpcId, networkId);
String msg = String.format("Creating DHCP relay config with name %s on network %s of VPC %s",
dhcpRelayConfigName, networkName, vpcName);
LOGGER.debug(msg);
try {
nsxApiClient.createDhcpRelayConfig(dhcpRelayConfigName, addresses);
} catch (CloudRuntimeException e) {
msg = String.format("Error creating the DHCP relay config with name %s: %s", dhcpRelayConfigName, e.getMessage());
LOGGER.error(msg, e);
return new NsxAnswer(cmd, e);
}
String segmentName = NsxControllerUtils.getNsxSegmentId(domainId, accountId, datacenterId, vpcId, networkId);
String dhcpConfigPath = String.format("%s/%s", DHCP_RELAY_CONFIGS_PATH_PREFIX, dhcpRelayConfigName);
try {
Segment segment = nsxApiClient.getSegmentById(segmentName);
segment.setDhcpConfigPath(dhcpConfigPath);
nsxApiClient.updateSegment(segmentName, segment);
} catch (CloudRuntimeException e) {
msg = String.format("Error adding the DHCP relay config with name %s to the segment %s: %s", dhcpRelayConfigName, segmentName, e.getMessage());
LOGGER.error(msg);
return new NsxAnswer(cmd, e);
}
return new NsxAnswer(cmd, true, "");
}
private Answer executeRequest(ReadyCommand cmd) {
return new ReadyAnswer(cmd);
}
private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) {
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
boolean sourceNatEnabled = cmd.isSourceNatEnabled();
try {
nsxApiClient.createTier1Gateway(tier1GatewayName, tier0Gateway, edgeCluster, sourceNatEnabled);
return new NsxAnswer(cmd, true, "");
} catch (CloudRuntimeException e) {
String msg = String.format("Cannot create tier 1 gateway %s (%s: %s): %s", tier1GatewayName,
(cmd.isResourceVpc() ? "VPC" : "NETWORK"), cmd.getNetworkResourceName(), e.getMessage());
LOGGER.error(msg);
return new NsxAnswer(cmd, e);
}
}
private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) {
String tier1Id = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
nsxApiClient.deleteTier1Gateway(tier1Id);
} catch (Exception e) {
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private Answer executeRequest(CreateNsxSegmentCommand cmd) {
try {
String siteId = nsxApiClient.getDefaultSiteId();
String enforcementPointPath = nsxApiClient.getDefaultEnforcementPointPath(siteId);
TransportZoneListResult transportZoneListResult = nsxApiClient.getTransportZones();
if (CollectionUtils.isEmpty(transportZoneListResult.getResults())) {
String errorMsg = String.format("Failed to create network: %s as no transport zones were found in the linked NSX infrastructure", cmd.getNetworkName());
LOGGER.error(errorMsg);
return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg));
}
List<TransportZone> transportZones = transportZoneListResult.getResults().stream().filter(tz -> tz.getDisplayName().equals(transportZone)).collect(Collectors.toList());
if (CollectionUtils.isEmpty(transportZones)) {
String errorMsg = String.format("Failed to create network: %s as no transport zone of name %s was found in the linked NSX infrastructure", cmd.getNetworkName(), transportZone);
LOGGER.error(errorMsg);
return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg));
}
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
String gatewayAddress = cmd.getNetworkGateway() + "/" + cmd.getNetworkCidr().split("/")[1];
Long networkResourceId = Objects.isNull(cmd.getVpcId()) ? cmd.getNetworkId() : cmd.getVpcId();
boolean isResourceVpc = !Objects.isNull(cmd.getVpcId());
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(),
cmd.getZoneId(), networkResourceId, isResourceVpc);
nsxApiClient.createSegment(segmentName, tier1GatewayName, gatewayAddress, enforcementPointPath, transportZones);
nsxApiClient.createGroupForSegment(segmentName);
} catch (Exception e) {
LOGGER.error(String.format("Failed to create network: %s", cmd.getNetworkName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(DeleteNsxSegmentCommand cmd) {
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getVpcId(), cmd.getNetworkId());
try {
nsxApiClient.deleteSegment(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getVpcId(), cmd.getNetworkId(), segmentName);
} catch (Exception e) {
LOGGER.error(String.format("Failed to delete NSX segment %s: %s", segmentName, e.getMessage()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(CreateNsxStaticNatCommand cmd) {
String staticNatRuleName = NsxControllerUtils.getStaticNatRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
nsxApiClient.createStaticNatRule(cmd.getNetworkResourceName(), tier1GatewayName, staticNatRuleName, cmd.getPublicIp(), cmd.getVmIp());
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX static NAT rule %s for network: %s", staticNatRuleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(CreateNsxPortForwardRuleCommand cmd) {
String ruleName = NsxControllerUtils.getPortForwardRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.getRuleId(), cmd.isResourceVpc());
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
String privatePort = cmd.getPrivatePort();
String service = privatePort.contains("-") ? nsxApiClient.getServicePath(ruleName, privatePort, cmd.getProtocol(), null, null) :
nsxApiClient.getNsxInfraServices(ruleName, privatePort, cmd.getProtocol(), null, null);
nsxApiClient.createPortForwardingRule(ruleName, tier1GatewayName, cmd.getNetworkResourceName(), cmd.getPublicIp(),
cmd.getVmIp(), cmd.getPublicPort(), service);
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX port forward rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(DeleteNsxNatRuleCommand cmd) {
String ruleName = null;
if (cmd.getService() == Network.Service.StaticNat) {
ruleName = NsxControllerUtils.getStaticNatRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
} else if (cmd.getService() == Network.Service.PortForwarding) {
ruleName = NsxControllerUtils.getPortForwardRuleName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.getRuleId(), cmd.isResourceVpc());
}
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
try {
nsxApiClient.deleteNatRule(cmd.getService(), cmd.getPrivatePort(), cmd.getProtocol(),
cmd.getNetworkResourceName(), tier1GatewayName, ruleName);
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX static NAT rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(CreateNsxLoadBalancerRuleCommand cmd) {
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(),
cmd.getNetworkResourceId(), cmd.isResourceVpc());
String ruleName = NsxControllerUtils.getLoadBalancerRuleName(tier1GatewayName, cmd.getLbId());
try {
nsxApiClient.createAndAddNsxLbVirtualServer(tier1GatewayName, cmd.getLbId(), cmd.getPublicIp(), cmd.getPublicPort(),
cmd.getMemberList(), cmd.getAlgorithm(), cmd.getProtocol(), cmd.getPrivatePort());
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX load balancer rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(DeleteNsxLoadBalancerRuleCommand cmd) {
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(),
cmd.getZoneId(), cmd.getNetworkResourceId(), cmd.isResourceVpc());
String ruleName = NsxControllerUtils.getLoadBalancerRuleName(tier1GatewayName, cmd.getLbId());
try {
nsxApiClient.deleteNsxLbResources(tier1GatewayName, cmd.getLbId());
} catch (Exception e) {
LOGGER.error(String.format("Failed to add NSX load balancer rule %s for network: %s", ruleName, cmd.getNetworkResourceName()));
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(CreateNsxDistributedFirewallRulesCommand cmd) {
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(),
cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
List<NsxNetworkRule> rules = cmd.getRules();
try {
nsxApiClient.createSegmentDistributedFirewall(segmentName, rules);
} catch (Exception e) {
LOGGER.error(String.format("Failed to create NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
private NsxAnswer executeRequest(DeleteNsxDistributedFirewallRulesCommand cmd) {
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(),
cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
List<NsxNetworkRule> rules = cmd.getRules();
try {
nsxApiClient.deleteDistributedFirewallRules(segmentName, rules);
} catch (Exception e) {
LOGGER.error(String.format("Failed to delete NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
}
return new NsxAnswer(cmd, true, null);
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
}

View File

@ -0,0 +1,781 @@
// 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.amazonaws.util.CollectionUtils;
import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.to.LoadBalancerTO;
import com.cloud.api.ApiDBUtils;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.DomainVO;
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;
import com.cloud.host.Status;
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.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.PhysicalNetworkVO;
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.VpcProvider;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.rules.FirewallRule;
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.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;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.user.Account;
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.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
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.StartupNsxCommand;
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.apache.cloudstack.resource.NsxOpObject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.LongFunction;
@Component
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
LoadBalancingServiceProvider, FirewallServiceProvider, ResourceStateAdapter, Listener {
@Inject
AccountManager accountMgr;
@Inject
NsxServiceImpl nsxService;
@Inject
DataCenterDao dataCenterDao;
@Inject
NetworkDao networkDao;
@Inject
AgentManager agentManager;
@Inject
ResourceManager resourceManager;
@Inject
PhysicalNetworkDao physicalNetworkDao;
@Inject
NetworkModel networkModel;
@Inject
DomainDao domainDao;
@Inject
protected VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
@Inject
IPAddressDao ipAddressDao;
@Inject
VMInstanceDao vmInstanceDao;
@Inject
VpcDao vpcDao;
@Inject
LoadBalancerVMMapDao lbVmMapDao;
private static final Logger LOGGER = Logger.getLogger(NsxElement.class);
private final Map<Network.Service, Map<Network.Capability, String>> capabilities = initCapabilities();
private 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");
capabilities.put(Network.Service.Dhcp, dhcpCapabilities);
Map<Network.Capability, String> dnsCapabilities = new HashMap<>();
dnsCapabilities.put(Network.Capability.AllowDnsSuffixModification, "true");
capabilities.put(Network.Service.Dns, dnsCapabilities);
capabilities.put(Network.Service.StaticNat, null);
capabilities.put(Network.Service.Lb, null);
capabilities.put(Network.Service.PortForwarding, null);
capabilities.put(Network.Service.NetworkACL, null);
Map<Network.Capability, String> firewallCapabilities = new HashMap<>();
firewallCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp");
firewallCapabilities.put(Network.Capability.SupportedEgressProtocols, "tcp,udp,icmp,all");
firewallCapabilities.put(Network.Capability.MultipleIps, "true");
firewallCapabilities.put(Network.Capability.TrafficStatistics, "per public ip");
firewallCapabilities.put(Network.Capability.SupportedTrafficDirection, "ingress, egress");
capabilities.put(Network.Service.Firewall, firewallCapabilities);
Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
capabilities.put(Network.Service.SourceNat, sourceNatCapabilities);
return capabilities;
}
@Override
public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
return true;
}
@Override
public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
return true;
}
@Override
public boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException {
return true;
}
@Override
public boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions) {
return true;
}
@Override
public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) throws ResourceUnavailableException {
return true;
}
@Override
public boolean addDnsEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
return true;
}
@Override
public boolean configDnsSupportForSubnet(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
return true;
}
@Override
public boolean removeDnsSupportForSubnet(Network network) throws ResourceUnavailableException {
return true;
}
@Override
public Map<Network.Service, Map<Network.Capability, String>> getCapabilities() {
return capabilities;
}
@Override
public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Network.Service> services) throws ResourceUnavailableException {
return true;
}
@Override
public Network.Provider getProvider() {
return Network.Provider.Nsx;
}
@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;
}
@Override
public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
return false;
}
@Override
public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
return false;
}
@Override
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
return canHandle(network, Network.Service.Connectivity);
}
@Override
public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
Account account = accountMgr.getAccount(network.getAccountId());
NetworkVO networkVO = networkDao.findById(network.getId());
DataCenterVO zone = dataCenterDao.findById(network.getDataCenterId());
DomainVO domain = domainDao.findById(account.getDomainId());
if (Objects.isNull(zone)) {
String msg = String.format("Cannot find zone with ID %s", network.getDataCenterId());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
return nsxService.deleteNetwork(zone.getId(), account.getId(), domain.getId(), networkVO);
}
@Override
public boolean isReady(PhysicalNetworkServiceProvider provider) {
return true;
}
@Override
public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
return false;
}
@Override
public boolean canEnableIndividualServices() {
return true;
}
@Override
public boolean verifyServicesCombination(Set<Network.Service> services) {
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;
}
@Override
public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
if (!(startup[0] instanceof StartupNsxCommand)) {
return null;
}
host.setType(Host.Type.L2Networking);
return host;
}
@Override
public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
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) || physicalNetworks.size() > 1 ) {
throw new InvalidConfigurationException(String.format("Desired number of physical networks is not present in the zone %s for traffic type %s. ", zone.getName(), Networks.TrafficType.Guest.name()));
}
if (physicalNetworks.get(0).getIsolationMethods().contains("NSX")) {
account = accountMgr.getAccount(vpc.getAccountId());
forNsx = true;
}
return new Pair<>(forNsx, account);
}
@Override
public boolean createPrivateGateway(PrivateGateway gateway) throws ConcurrentOperationException, ResourceUnavailableException {
return false;
}
@Override
public boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException {
return false;
}
@Override
public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
return false;
}
@Override
public boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
return false;
}
@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 Nsx Element can handle service " + service.getName() + " on network "
+ network.getDisplayText());
if (!networkModel.isProviderForNetwork(getProvider(), network.getId())) {
LOGGER.debug("Nsx Element is not a provider for network " + network.getDisplayText());
return false;
}
return true;
}
private final LongFunction<DataCenterVO> zoneFunction = zoneId -> dataCenterDao.findById(zoneId);
@Override
public IpDeployer getIpDeployer(Network network) {
return this;
}
@Override
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
for(StaticNat staticNat : rules) {
long sourceIpAddressId = staticNat.getSourceIpAddressId();
IPAddressVO ipAddressVO = ipAddressDao.findByIdIncludingRemoved(sourceIpAddressId);
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(ipAddressVO.getAssociatedWithVmId());
// floating ip is released when nic was deleted
if (vm == null || networkModel.getNicInNetworkIncludingRemoved(vm.getId(), config.getId()) == null) {
continue;
}
Pair<VpcVO, NetworkVO> vpcOrNetwork = getVpcOrNetwork(config.getVpcId(), config.getId());
VpcVO vpc = vpcOrNetwork.first();
NetworkVO network = vpcOrNetwork.second();
Long networkResourceId = Objects.nonNull(vpc) ? vpc.getId() : network.getId();
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());
} else {
return nsxService.deleteStaticNatRule(config.getDataCenterId(), config.getDomainId(), config.getAccountId(),
networkResourceId, networkResourceName, isVpcResource);
}
}
return false;
}
@Override
public boolean applyPFRules(Network network, List<PortForwardingRule> rules) throws ResourceUnavailableException {
if (!canHandle(network, Network.Service.PortForwarding)) {
return false;
}
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)) ||
(vm != null && networkModel.getNicInNetwork(vm.getId(), network.getId()) == null)) {
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();
if (rule.getState() == FirewallRule.State.Add) {
result &= nsxService.createPortForwardRule(networkRule);
} else if (rule.getState() == FirewallRule.State.Revoke) {
result &= nsxService.deletePortForwardRule(networkRule);
}
}
return result;
}
public Pair<VpcVO, NetworkVO> getVpcOrNetwork(Long vpcId, long networkId) {
VpcVO vpc = null;
NetworkVO network = null;
if (Objects.nonNull(vpcId)) {
vpc = vpcDao.findById(vpcId);
if (Objects.isNull(vpc)) {
throw new CloudRuntimeException(String.format("Failed to find VPC with id: %s", vpcId));
}
} else {
network = networkDao.findById(networkId);
if (Objects.isNull(network)) {
throw new CloudRuntimeException(String.format("Failed to find network with id: %s", networkId));
}
}
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()));
}
private 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()));
}
private 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()));
}
private long getResourceId(String resource, VpcVO vpc, NetworkVO network) {
switch (resource) {
case "domain":
return Objects.nonNull(vpc) ? vpc.getDomainId() : network.getDomainId();
case "account":
return Objects.nonNull(vpc) ? vpc.getAccountId() : network.getAccountId();
case "zone":
return Objects.nonNull(vpc) ? vpc.getZoneId() : network.getDataCenterId();
default:
return 0;
}
}
private NsxOpObject getNsxOpObject(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);
return new NsxOpObject.Builder()
.vpcVO(vpc)
.networkVO(networkVO)
.domainId(domainId)
.accountId(accountId)
.zoneId(zoneId)
.build();
}
@Override
public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
boolean result = true;
for (LoadBalancingRule loadBalancingRule : rules) {
if (loadBalancingRule.getState() == FirewallRule.State.Active) {
continue;
}
IPAddressVO publicIp = ipAddressDao.findByIpAndDcId(network.getDataCenterId(),
loadBalancingRule.getSourceIp().addr());
NsxOpObject nsxObject = getNsxOpObject(network);
List<NsxLoadBalancerMember> lbMembers = getLoadBalancerMembers(loadBalancingRule);
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setDomainId(nsxObject.getDomainId())
.setAccountId(nsxObject.getAccountId())
.setZoneId(nsxObject.getZoneId())
.setNetworkResourceId(nsxObject.getNetworkResourceId())
.setNetworkResourceName(nsxObject.getNetworkResourceName())
.setVpcResource(nsxObject.isVpcResource())
.setMemberList(lbMembers)
.setPublicIp(publicIp.getAddress().addr())
.setPublicPort(String.valueOf(loadBalancingRule.getSourcePortStart()))
.setPrivatePort(String.valueOf(loadBalancingRule.getDefaultPortStart()))
.setRuleId(loadBalancingRule.getId())
.setProtocol(loadBalancingRule.getProtocol().toUpperCase(Locale.ROOT))
.setAlgorithm(loadBalancingRule.getAlgorithm())
.build();
if (loadBalancingRule.getState() == FirewallRule.State.Add) {
result &= nsxService.createLbRule(networkRule);
} else if (loadBalancingRule.getState() == FirewallRule.State.Revoke) {
result &= nsxService.deleteLbRule(networkRule);
}
}
return result;
}
@Override
public boolean validateLBRule(Network network, LoadBalancingRule rule) {
return true;
}
@Override
public List<LoadBalancerTO> updateHealthChecks(Network network, List<LoadBalancingRule> lbrules) {
return new ArrayList<>();
}
@Override
public boolean handlesOnlyRulesInTransitionState() {
return false;
}
private List<NsxLoadBalancerMember> getLoadBalancerMembers(LoadBalancingRule lbRule) {
List<LoadBalancerVMMapVO> lbVms = lbVmMapDao.listByLoadBalancerId(lbRule.getId(), false);
List<NsxLoadBalancerMember> lbMembers = new ArrayList<>();
for (LoadBalancerVMMapVO lbVm : lbVms) {
NsxLoadBalancerMember member = new NsxLoadBalancerMember(lbVm.getInstanceId(), lbVm.getInstanceIp(), lbRule.getDefaultPortStart());
lbMembers.add(member);
}
return lbMembers;
}
@Override
public boolean applyNetworkACLs(Network network, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
if (!canHandle(network, Network.Service.NetworkACL)) {
return false;
}
List<NsxNetworkRule> nsxAddNetworkRules = new ArrayList<>();
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
for (NetworkACLItem rule : rules) {
String privatePort = getPrivatePortRangeForACLRule(rule);
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setRuleId(rule.getId())
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
.setAclAction(transformActionValue(rule.getAction()))
.setTrafficType(rule.getTrafficType().toString())
.setProtocol(rule.getProtocol().toUpperCase())
.setPublicPort(String.valueOf(rule.getSourcePortStart()))
.setPrivatePort(privatePort)
.setIcmpCode(rule.getIcmpCode())
.setIcmpType(rule.getIcmpType())
.setService(Network.Service.NetworkACL)
.build();
if (Arrays.asList(NetworkACLItem.State.Active, NetworkACLItem.State.Add).contains(rule.getState())) {
nsxAddNetworkRules.add(networkRule);
} else if (NetworkACLItem.State.Revoke == rule.getState()) {
nsxDelNetworkRules.add(networkRule);
}
}
boolean success = true;
if (!nsxDelNetworkRules.isEmpty()) {
success = nsxService.deleteFirewallRules(network, nsxDelNetworkRules);
if (!success) {
LOGGER.warn("Not all firewall rules were successfully deleted");
}
}
return success && nsxService.addFirewallRules(network, nsxAddNetworkRules);
}
@Override
public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
if (!canHandle(network, Network.Service.Firewall)) {
return false;
}
List<NsxNetworkRule> nsxAddNetworkRules = new ArrayList<>();
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
for (FirewallRule rule : rules) {
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
.setRuleId(rule.getId())
.setAclAction(NsxNetworkRule.NsxRuleAction.ALLOW)
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ?
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
.setDestinationCidrList(Objects.nonNull(rule.getDestinationCidrList()) ?
transformCidrListValues(rule.getDestinationCidrList()) : List.of("ANY"))
.setIcmpCode(rule.getIcmpCode())
.setIcmpType(rule.getIcmpType())
.setPrivatePort(getPrivatePortRange(rule))
.setTrafficType(rule.getTrafficType().toString())
.setService(Network.Service.Firewall)
.setProtocol(rule.getProtocol().toUpperCase(Locale.ROOT))
.build();
if (rule.getState() == FirewallRule.State.Add) {
nsxAddNetworkRules.add(networkRule);
} else if (rule.getState() == FirewallRule.State.Revoke) {
nsxDelNetworkRules.add(networkRule);
}
}
boolean success = true;
if (!nsxDelNetworkRules.isEmpty()) {
success = nsxService.deleteFirewallRules(network, nsxDelNetworkRules);
if (!success) {
LOGGER.warn("Not all firewall rules were successfully deleted");
}
}
return success && nsxService.addFirewallRules(network, nsxAddNetworkRules);
}
protected NsxNetworkRule.NsxRuleAction transformActionValue(NetworkACLItem.Action action) {
if (action == NetworkACLItem.Action.Allow) {
return NsxNetworkRule.NsxRuleAction.ALLOW;
} else if (action == NetworkACLItem.Action.Deny) {
return NsxNetworkRule.NsxRuleAction.DROP;
}
String err = String.format("Unsupported action %s", action.toString());
LOGGER.error(err);
throw new CloudRuntimeException(err);
}
/**
* Replace 0.0.0.0/0 to ANY on each occurrence
*/
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;
}
}

View File

@ -0,0 +1,338 @@
// 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 static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import com.cloud.dc.DataCenter;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Network;
import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.guru.GuestNetworkGuru;
import com.cloud.network.vpc.VpcVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.cloudstack.utils.NsxHelper;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.List;
import java.util.Objects;
public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigrationResponder {
private static final Logger LOGGER = Logger.getLogger(NsxGuestNetworkGuru.class);
@Inject
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@Inject
NsxControllerUtils nsxControllerUtils;
@Inject
AccountDao accountDao;
@Inject
DomainDao domainDao;
@Inject
NetworkModel networkModel;
public NsxGuestNetworkGuru() {
super();
_isolationMethods = new PhysicalNetwork.IsolationMethod[] {new PhysicalNetwork.IsolationMethod("NSX")};
}
@Override
public boolean canHandle(NetworkOffering offering, DataCenter.NetworkType networkType,
PhysicalNetwork physicalNetwork) {
return networkType == DataCenter.NetworkType.Advanced && isMyTrafficType(offering.getTrafficType())
&& isMyIsolationMethod(physicalNetwork) && (NetworkOffering.NsxMode.ROUTED.name().equals(offering.getNsxMode())
|| (networkOfferingServiceMapDao.isProviderForNetworkOffering(
offering.getId(), Network.Provider.Nsx) && NetworkOffering.NsxMode.NATTED.name().equals(offering.getNsxMode())));
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner) {
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
if (!canHandle(offering, dc.getNetworkType(), physnet)) {
LOGGER.debug("Refusing to design this network");
return null;
}
NetworkVO network = (NetworkVO) super.design(offering, plan, userSpecified, name, vpcId, owner);
if (network == null) {
return null;
}
network.setBroadcastDomainType(Networks.BroadcastDomainType.NSX);
if (userSpecified != null) {
if ((userSpecified.getIp6Cidr() == null && userSpecified.getIp6Gateway() != null) || (
userSpecified.getIp6Cidr() != null && userSpecified.getIp6Gateway() == null)) {
throw new InvalidParameterValueException("cidrv6 and gatewayv6 must be specified together.");
}
if (userSpecified.getIp6Cidr() != null) {
network.setIp6Cidr(userSpecified.getIp6Cidr());
network.setIp6Gateway(userSpecified.getIp6Gateway());
}
}
network.setBroadcastDomainType(Networks.BroadcastDomainType.NSX);
network.setState(Network.State.Allocated);
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(),
network.getBroadcastDomainType(), network.getNetworkOfferingId(), Network.State.Implemented,
network.getDataCenterId(), network.getPhysicalNetworkId(), offering.isRedundantRouter());
implemented.setAccountId(owner.getAccountId());
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
if (vpcId != null) {
implemented.setVpcId(vpcId);
}
if (name != null) {
implemented.setName(name);
}
implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx"));
return network;
}
@Override
public void setup(Network network, long networkId) {
try {
NetworkVO designedNetwork = _networkDao.findById(networkId);
long zoneId = network.getDataCenterId();
DataCenter zone = _dcDao.findById(zoneId);
if (isNull(zone)) {
throw new CloudRuntimeException(String.format("Failed to find zone with id: %s", zoneId));
}
createNsxSegment(designedNetwork, zone);
} catch (Exception ex) {
throw new CloudRuntimeException("unable to create NSX network " + network.getUuid() + "due to: " + ex.getMessage());
}
}
@Override
@DB
public void deallocate(Network config, NicProfile nic, VirtualMachineProfile vm) {
// Do nothing
}
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination dest,
ReservationContext context) {
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(),
network.getBroadcastDomainType(), network.getNetworkOfferingId(), Network.State.Implemented,
network.getDataCenterId(), network.getPhysicalNetworkId(), offering.isRedundantRouter());
implemented.setAccountId(network.getAccountId());
if (network.getGateway() != null) {
implemented.setGateway(network.getGateway());
}
if (network.getCidr() != null) {
implemented.setCidr(network.getCidr());
}
if (network.getVpcId() != null) {
implemented.setVpcId(network.getVpcId());
}
if (network.getName() != null) {
implemented.setName(network.getName());
}
implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx"));
return implemented;
}
@Override
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
NicProfile nicProfile = super.allocate(network, nic, vm);
if (vm.getType() != VirtualMachine.Type.DomainRouter) {
return nicProfile;
}
final DataCenter zone = _dcDao.findById(network.getDataCenterId());
long zoneId = network.getDataCenterId();
if (Objects.isNull(zone)) {
String msg = String.format("Unable to find zone with id: %s", zoneId);
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
Account account = accountDao.findById(network.getAccountId());
if (Objects.isNull(account)) {
String msg = String.format("Unable to find account with id: %s", network.getAccountId());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
VpcVO vpc = _vpcDao.findById(network.getVpcId());
if (Objects.isNull(vpc)) {
String msg = String.format("Unable to find VPC with id: %s, allocating for network %s", network.getVpcId(), network.getName());
LOGGER.debug(msg);
}
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);
}
NetworkOfferingVO networkOfferingVO = networkOfferingDao.findById(network.getNetworkOfferingId());
if (isNull(network.getVpcId()) && networkOfferingVO.getNsxMode().equals(NetworkOffering.NsxMode.NATTED.name())) {
long domainId = domain.getId();
long accountId = account.getId();
long dataCenterId = zone.getId();
long resourceId = network.getId();
PublicIpAddress ipAddress = networkModel.getSourceNatIpAddressForGuestNetwork(account, network);
String translatedIp = ipAddress.getAddress().addr();
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, dataCenterId, resourceId, false);
LOGGER.debug(String.format("Creating NSX NAT Rule for Tier1 GW %s for translated IP %s for Isolated network %s", tier1GatewayName, translatedIp, network.getName()));
String natRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, dataCenterId, resourceId, false);
CreateOrUpdateNsxTier1NatRuleCommand cmd = NsxHelper.createOrUpdateNsxNatRuleCommand(domainId, accountId, dataCenterId, tier1GatewayName, "SNAT", translatedIp, natRuleId);
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(cmd, dataCenterId);
if (!nsxAnswer.getResult()) {
String msg = String.format("Could not create NSX NAT Rule on Tier1 Gateway %s for IP %s for Isolated network %s", tier1GatewayName, translatedIp, network.getName());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
}
// Create the DHCP relay config for the segment
String iPv4Address = nicProfile.getIPv4Address();
List<String> addresses = List.of(iPv4Address);
CreateNsxDhcpRelayConfigCommand command = NsxHelper.createNsxDhcpRelayConfigCommand(domain, account, zone, vpc, network, addresses);
NsxAnswer answer = nsxControllerUtils.sendNsxCommand(command, zone.getId());
if (!answer.getResult()) {
String msg = String.format("Error creating DHCP relay config for network %s and nic %s: %s", network.getName(), nic.getName(), answer.getDetails());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
return nicProfile;
}
@Override
public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm,
final DeployDestination dest, final ReservationContext context)
throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
// Do nothing
}
@Override
public boolean release(final NicProfile nic, final VirtualMachineProfile vm, final String reservationId) {
return true;
}
@Override
public void shutdown(final NetworkProfile profile, final NetworkOffering offering) {
// Do nothing
}
@Override
public boolean trash(Network network, NetworkOffering offering) {
return true;
}
@Override
public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) {
return false;
}
@Override
public void rollbackMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) {
// Do nothing
}
@Override
public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) {
// Do nothing
}
public void createNsxSegment(NetworkVO networkVO, DataCenter zone) {
Account account = accountDao.findById(networkVO.getAccountId());
if (isNull(account)) {
throw new CloudRuntimeException(String.format("Unable to find account with id: %s", networkVO.getAccountId()));
}
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);
}
String vpcName = null;
if (nonNull(networkVO.getVpcId())) {
VpcVO vpc = _vpcDao.findById(networkVO.getVpcId());
if (isNull(vpc)) {
throw new CloudRuntimeException(String.format("Failed to find VPC network with id: %s", networkVO.getVpcId()));
}
vpcName = vpc.getName();
} else {
LOGGER.debug(String.format("Creating a Tier 1 Gateway for the network %s before creating the NSX segment", networkVO.getName()));
boolean isSourceNatSupported = networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(networkVO.getNetworkOfferingId(), Network.Service.SourceNat);
CreateNsxTier1GatewayCommand nsxTier1GatewayCommand = new CreateNsxTier1GatewayCommand(domain.getId(), account.getId(), zone.getId(), networkVO.getId(), networkVO.getName(), false, isSourceNatSupported);
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(nsxTier1GatewayCommand, zone.getId());
if (!nsxAnswer.getResult()) {
String msg = String.format("Could not create a Tier 1 Gateway for network %s: %s", networkVO.getName(), nsxAnswer.getDetails());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
}
CreateNsxSegmentCommand command = NsxHelper.createNsxSegmentCommand(domain, account, zone, vpcName, networkVO);
NsxAnswer answer = nsxControllerUtils.sendNsxCommand(command, zone.getId());
if (!answer.getResult()) {
throw new CloudRuntimeException("can not create NSX network");
}
}
}

View File

@ -0,0 +1,35 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.service;
import com.cloud.network.nsx.NsxProvider;
import com.cloud.utils.component.PluggableService;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.command.AddNsxControllerCmd;
import org.apache.cloudstack.api.response.NsxControllerResponse;
import java.util.List;
public interface NsxProviderService extends PluggableService {
NsxProvider addProvider(AddNsxControllerCmd cmd);
NsxControllerResponse createNsxControllerResponse(NsxProvider nsxProvider);
List<BaseResponse> listNsxProviders(Long zoneId);
boolean deleteNsxController(Long nsxControllerId);
}

View File

@ -0,0 +1,213 @@
// 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.amazonaws.util.CollectionUtils;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.host.DetailVO;
import com.cloud.host.Host;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.network.Network;
import com.cloud.network.Networks;
import com.cloud.network.nsx.NsxProvider;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NsxProviderDao;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.element.NsxProviderVO;
import com.cloud.resource.ResourceManager;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.exception.CloudRuntimeException;
import com.google.common.annotations.VisibleForTesting;
import org.apache.cloudstack.api.command.DeleteNsxControllerCmd;
import org.apache.cloudstack.api.command.ListNsxControllersCmd;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.command.AddNsxControllerCmd;
import org.apache.cloudstack.api.response.NsxControllerResponse;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.resource.NsxResource;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class NsxProviderServiceImpl implements NsxProviderService {
@Inject
NsxProviderDao nsxProviderDao;
@Inject
DataCenterDao dataCenterDao;
@Inject
PhysicalNetworkDao physicalNetworkDao;
@Inject
NetworkDao networkDao;
@Inject
ResourceManager resourceManager;
@Inject
HostDetailsDao hostDetailsDao;
@Override
public NsxProvider addProvider(AddNsxControllerCmd cmd) {
final Long zoneId = cmd.getZoneId();
final String name = cmd.getName();
final String hostname = cmd.getHostname();
final String port = cmd.getPort() == null || cmd.getPort().equals(StringUtils.EMPTY) ? "443" : cmd.getPort();
final String username = cmd.getUsername();
final String password = cmd.getPassword();
final String tier0Gateway = cmd.getTier0Gateway();
final String edgeCluster = cmd.getEdgeCluster();
final String transportZone = cmd.getTransportZone();
Map<String, String> params = new HashMap<>();
params.put("guid", UUID.randomUUID().toString());
params.put("zoneId", zoneId.toString());
params.put("name", name);
params.put("hostname", hostname);
params.put("port", port);
params.put("username", username);
params.put("password", password);
params.put("tier0Gateway", tier0Gateway);
params.put("edgeCluster", edgeCluster);
params.put("transportZone", transportZone);
Map<String, Object> hostdetails = new HashMap<>(params);
NsxProvider nsxProvider;
NsxResource nsxResource = new NsxResource();
try {
nsxResource.configure(hostname, hostdetails);
final Host host = resourceManager.addHost(zoneId, nsxResource, nsxResource.getType(), params);
if (host != null) {
nsxProvider = Transaction.execute((TransactionCallback<NsxProviderVO>) status -> {
NsxProviderVO nsxProviderVO = new NsxProviderVO.Builder()
.setZoneId(zoneId)
.setHostId(host.getId())
.setProviderName(name)
.setHostname(hostname)
.setPort(port)
.setUsername(username)
.setPassword(password)
.setTier0Gateway(tier0Gateway)
.setEdgeCluster(edgeCluster)
.setTransportZone(transportZone)
.build();
nsxProviderDao.persist(nsxProviderVO);
DetailVO detail = new DetailVO(host.getId(), "nsxcontrollerid",
String.valueOf(nsxProviderVO.getId()));
hostDetailsDao.persist(detail);
return nsxProviderVO;
});
} else {
throw new CloudRuntimeException("Failed to add NSX controller due to internal error.");
}
} catch (ConfigurationException e) {
throw new CloudRuntimeException(e.getMessage());
}
return nsxProvider;
}
@Override
public NsxControllerResponse createNsxControllerResponse(NsxProvider nsxProvider) {
DataCenterVO zone = dataCenterDao.findById(nsxProvider.getZoneId());
if (Objects.isNull(zone)) {
throw new CloudRuntimeException(String.format("Failed to find zone with id %s", nsxProvider.getZoneId()));
}
NsxControllerResponse response = new NsxControllerResponse();
response.setName(nsxProvider.getProviderName());
response.setUuid(nsxProvider.getUuid());
response.setHostname(nsxProvider.getHostname());
response.setPort(nsxProvider.getPort());
response.setZoneId(zone.getUuid());
response.setZoneName(zone.getName());
response.setTier0Gateway(nsxProvider.getTier0Gateway());
response.setEdgeCluster(nsxProvider.getEdgeCluster());
response.setTransportZone(nsxProvider.getTransportZone());
response.setObjectName("nsxController");
return response;
}
@Override
public List<BaseResponse> listNsxProviders(Long zoneId) {
List<BaseResponse> nsxControllersResponseList = new ArrayList<>();
if (zoneId != null) {
NsxProviderVO nsxProviderVO = nsxProviderDao.findByZoneId(zoneId);
if (Objects.nonNull(nsxProviderVO)) {
nsxControllersResponseList.add(createNsxControllerResponse(nsxProviderVO));
}
} else {
List<NsxProviderVO> nsxProviderVOList = nsxProviderDao.listAll();
for (NsxProviderVO nsxProviderVO : nsxProviderVOList) {
nsxControllersResponseList.add(createNsxControllerResponse(nsxProviderVO));
}
}
return nsxControllersResponseList;
}
@Override
public boolean deleteNsxController(Long nsxControllerId) {
NsxProviderVO nsxProvider = nsxProviderDao.findById(nsxControllerId);
if (Objects.isNull(nsxProvider)) {
throw new InvalidParameterValueException(String.format("Failed to find NSX controller with id: %s", nsxControllerId));
}
Long zoneId = nsxProvider.getZoneId();
// Find the physical network we work for
List<PhysicalNetworkVO> physicalNetworks = physicalNetworkDao.listByZone(zoneId);
for (PhysicalNetworkVO physicalNetwork : physicalNetworks) {
List<NetworkVO> networkList = networkDao.listByPhysicalNetwork(physicalNetwork.getId());
if (!CollectionUtils.isNullOrEmpty(networkList)) {
validateNetworkState(networkList);
}
}
nsxProviderDao.remove(nsxControllerId);
return true;
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<>();
if (Boolean.TRUE.equals(NetworkOrchestrationService.NSX_ENABLED.value())) {
cmdList.add(AddNsxControllerCmd.class);
cmdList.add(ListNsxControllersCmd.class);
cmdList.add(DeleteNsxControllerCmd.class);
}
return cmdList;
}
@VisibleForTesting
void validateNetworkState(List<NetworkVO> networkList) {
for (NetworkVO network : networkList) {
if (network.getBroadcastDomainType() == Networks.BroadcastDomainType.NSX &&
((network.getState() != Network.State.Shutdown) && (network.getState() != Network.State.Destroy))) {
throw new CloudRuntimeException("This NSX Controller cannot be deleted as there are one or more logical networks provisioned by CloudStack on it.");
}
}
}
}

View File

@ -0,0 +1,165 @@
// 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.dc.VlanDetailsVO;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.network.Network;
import com.cloud.network.Networks;
import com.cloud.network.nsx.NsxService;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.vpc.VpcOffering;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.cloudstack.utils.NsxHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.List;
import java.util.stream.Collectors;
public class NsxPublicNetworkGuru extends PublicNetworkGuru {
@Inject
private VlanDetailsDao vlanDetailsDao;
@Inject
private VpcDao vpcDao;
@Inject
private VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
@Inject
private NsxControllerUtils nsxControllerUtils;
@Inject
private NsxService nsxService;
@Inject
private VpcOfferingDao vpcOfferingDao;
@Inject
private NetworkOfferingDao offeringDao;
private static final Logger s_logger = Logger.getLogger(NsxPublicNetworkGuru.class);
public NsxPublicNetworkGuru() {
super();
}
@Override
protected boolean canHandle(NetworkOffering offering) {
return isMyTrafficType(offering.getTrafficType()) && offering.isSystemOnly() && offering.isForNsx();
}
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network network, String name, Long vpcId, Account owner) {
if (!canHandle(offering)) {
return null;
}
if (offering.getTrafficType() == Networks.TrafficType.Public) {
return new NetworkVO(offering.getTrafficType(), Networks.Mode.Static, network.getBroadcastDomainType(), offering.getId(), Network.State.Setup, plan.getDataCenterId(),
plan.getPhysicalNetworkId(), offering.isRedundantRouter());
}
return null;
}
@Override
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException, ConcurrentOperationException {
s_logger.debug("NSX Public network guru: allocate");
IPAddressVO ipAddress = _ipAddressDao.findByIp(nic.getIPv4Address());
if (ipAddress == null) {
String err = String.format("Cannot find the IP address %s", nic.getIPv4Address());
s_logger.error(err);
throw new CloudRuntimeException(err);
}
Long vpcId = ipAddress.getVpcId();
boolean isForVpc = vpcId != null;
VpcVO vpc = vpcDao.findById(vpcId);
if (vpc == null) {
String err = String.format("Cannot find a VPC with ID %s", vpcId);
s_logger.error(err);
throw new CloudRuntimeException(err);
}
// For NSX, use VR Public IP != Source NAT
List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpc.getId(), true);
if (CollectionUtils.isEmpty(ips)) {
String err = String.format("Cannot find a source NAT IP for the VPC %s", vpc.getName());
s_logger.error(err);
throw new CloudRuntimeException(err);
}
ips = ips.stream().filter(x -> !x.getAddress().addr().equals(nic.getIPv4Address())).collect(Collectors.toList());
// Use Source NAT IP address from the NSX Public Range. Do not Use the VR Public IP address
ipAddress = ips.get(0);
if (ipAddress.isSourceNat() && !ipAddress.isForSystemVms()) {
VlanDetailsVO detail = vlanDetailsDao.findDetail(ipAddress.getVlanId(), ApiConstants.NSX_DETAIL_KEY);
if (detail != null && detail.getValue().equalsIgnoreCase("true")) {
long accountId = vpc.getAccountId();
long domainId = vpc.getDomainId();
long dataCenterId = vpc.getZoneId();
long resourceId = vpc.getId();
Network.Service[] services = { Network.Service.SourceNat };
boolean sourceNatEnabled = vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), services);
s_logger.info(String.format("Creating Tier 1 Gateway for VPC %s", vpc.getName()));
boolean result = nsxService.createVpcNetwork(dataCenterId, accountId, domainId, resourceId, vpc.getName(), sourceNatEnabled);
if (!result) {
String msg = String.format("Error creating Tier 1 Gateway for VPC %s", vpc.getName());
s_logger.error(msg);
throw new CloudRuntimeException(msg);
}
boolean hasNatSupport = false;
VpcOffering vpcOffering = vpcOfferingDao.findById(vpc.getVpcOfferingId());
hasNatSupport = NetworkOffering.NsxMode.NATTED.name().equals(vpcOffering.getNsxMode());
if (!hasNatSupport) {
return nic;
}
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, dataCenterId, resourceId, isForVpc);
String translatedIp = ipAddress.getAddress().addr();
s_logger.debug(String.format("Creating NSX Nat Rule for Tier1 GW %s for translated IP %s", tier1GatewayName, translatedIp));
String natRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, dataCenterId, resourceId, isForVpc);
CreateOrUpdateNsxTier1NatRuleCommand cmd = NsxHelper.createOrUpdateNsxNatRuleCommand(domainId, accountId, dataCenterId, tier1GatewayName, "SNAT", translatedIp, natRuleId);
NsxAnswer nsxAnswer = nsxControllerUtils.sendNsxCommand(cmd, dataCenterId);
if (!nsxAnswer.getResult()) {
String msg = String.format("Could not create NSX Nat Rule on Tier1 Gateway %s for IP %s", tier1GatewayName, translatedIp);
s_logger.error(msg);
throw new CloudRuntimeException(msg);
}
}
}
return nic;
}
}

View File

@ -0,0 +1,192 @@
// 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.IpAddress;
import com.cloud.network.Network;
import com.cloud.network.nsx.NsxService;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.apache.cloudstack.utils.NsxHelper;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.List;
import java.util.Objects;
public class NsxServiceImpl implements NsxService {
@Inject
NsxControllerUtils nsxControllerUtils;
@Inject
VpcDao vpcDao;
@Inject
NetworkDao networkDao;
private static final Logger LOGGER = Logger.getLogger(NsxServiceImpl.class);
public boolean createVpcNetwork(Long zoneId, long accountId, long domainId, Long vpcId, String vpcName, boolean sourceNatEnabled) {
CreateNsxTier1GatewayCommand createNsxTier1GatewayCommand =
new CreateNsxTier1GatewayCommand(domainId, accountId, zoneId, vpcId, vpcName, true, sourceNatEnabled);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxTier1GatewayCommand, zoneId);
return result.getResult();
}
@Override
public boolean updateVpcSourceNatIp(Vpc vpc, IpAddress address) {
if (vpc == null || address == null) {
return false;
}
long accountId = vpc.getAccountId();
long domainId = vpc.getDomainId();
long zoneId = vpc.getZoneId();
long vpcId = vpc.getId();
LOGGER.debug(String.format("Updating the source NAT IP for NSX VPC %s to IP: %s", vpc.getName(), address.getAddress().addr()));
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, zoneId, vpcId, true);
String sourceNatRuleId = NsxControllerUtils.getNsxNatRuleId(domainId, accountId, zoneId, vpcId, true);
CreateOrUpdateNsxTier1NatRuleCommand cmd = NsxHelper.createOrUpdateNsxNatRuleCommand(domainId, accountId, zoneId, tier1GatewayName, "SNAT", address.getAddress().addr(), sourceNatRuleId);
NsxAnswer answer = nsxControllerUtils.sendNsxCommand(cmd, zoneId);
if (!answer.getResult()) {
LOGGER.error(String.format("Could not update the source NAT IP address for VPC %s: %s", vpc.getName(), answer.getDetails()));
return false;
}
return true;
}
public boolean createNetwork(Long zoneId, long accountId, long domainId, Long networkId, String networkName) {
CreateNsxTier1GatewayCommand createNsxTier1GatewayCommand =
new CreateNsxTier1GatewayCommand(domainId, accountId, zoneId, networkId, networkName, false, false);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxTier1GatewayCommand, zoneId);
return result.getResult();
}
public boolean deleteVpcNetwork(Long zoneId, long accountId, long domainId, Long vpcId, String vpcName) {
DeleteNsxTier1GatewayCommand deleteNsxTier1GatewayCommand =
new DeleteNsxTier1GatewayCommand(domainId, accountId, zoneId, vpcId, vpcName, true);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId);
return result.getResult();
}
public boolean deleteNetwork(long zoneId, long accountId, long domainId, NetworkVO network) {
String vpcName = null;
if (Objects.nonNull(network.getVpcId())) {
VpcVO vpc = vpcDao.findById(network.getVpcId());
vpcName = Objects.nonNull(vpc) ? vpc.getName() : null;
}
DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(domainId, accountId, zoneId,
network.getVpcId(), vpcName, network.getId(), network.getName());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId());
if (!result.getResult()) {
String msg = String.format("Could not remove the NSX segment for network %s: %s", network.getName(), result.getDetails());
LOGGER.error(msg);
throw new CloudRuntimeException(msg);
}
if (Objects.isNull(network.getVpcId())) {
DeleteNsxTier1GatewayCommand deleteNsxTier1GatewayCommand = new DeleteNsxTier1GatewayCommand(domainId, accountId, zoneId, network.getId(), network.getName(), false);
result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId);
}
return result.getResult();
}
public boolean createStaticNatRule(long zoneId, long domainId, long accountId, Long networkResourceId, String networkResourceName,
boolean isVpcResource, long vmId, String publicIp, String vmIp) {
CreateNsxStaticNatCommand createNsxStaticNatCommand = new CreateNsxStaticNatCommand(domainId, accountId, zoneId,
networkResourceId, networkResourceName, isVpcResource, vmId, publicIp, vmIp);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxStaticNatCommand, zoneId);
return result.getResult();
}
public boolean deleteStaticNatRule(long zoneId, long domainId, long accountId, Long networkResourceId, String networkResourceName,
boolean isVpcResource) {
DeleteNsxNatRuleCommand deleteNsxStaticNatCommand = new DeleteNsxNatRuleCommand(domainId, accountId, zoneId,
networkResourceId, networkResourceName, isVpcResource, null, null, null, null);
deleteNsxStaticNatCommand.setService(Network.Service.StaticNat);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxStaticNatCommand, zoneId);
return result.getResult();
}
public boolean createPortForwardRule(NsxNetworkRule netRule) {
// TODO: if port doesn't exist in default list of services, create a service entry
CreateNsxPortForwardRuleCommand createPortForwardCmd = new CreateNsxPortForwardRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getVmId(), netRule.getRuleId(),
netRule.getPublicIp(), netRule.getVmIp(), netRule.getPublicPort(), netRule.getPrivatePort(), netRule.getProtocol());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(createPortForwardCmd, netRule.getZoneId());
return result.getResult();
}
public boolean deletePortForwardRule(NsxNetworkRule netRule) {
DeleteNsxNatRuleCommand deleteCmd = new DeleteNsxNatRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getVmId(), netRule.getRuleId(), netRule.getPrivatePort(), netRule.getProtocol());
deleteCmd.setService(Network.Service.PortForwarding);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteCmd, netRule.getZoneId());
return result.getResult();
}
public boolean createLbRule(NsxNetworkRule netRule) {
CreateNsxLoadBalancerRuleCommand command = new CreateNsxLoadBalancerRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getMemberList(), netRule.getRuleId(),
netRule.getPublicPort(), netRule.getPrivatePort(), netRule.getAlgorithm(), netRule.getProtocol());
command.setPublicIp(netRule.getPublicIp());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
return result.getResult();
}
public boolean deleteLbRule(NsxNetworkRule netRule) {
DeleteNsxLoadBalancerRuleCommand command = new DeleteNsxLoadBalancerRuleCommand(netRule.getDomainId(),
netRule.getAccountId(), netRule.getZoneId(), netRule.getNetworkResourceId(),
netRule.getNetworkResourceName(), netRule.isVpcResource(), netRule.getMemberList(), netRule.getRuleId(),
netRule.getVmId());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
return result.getResult();
}
public boolean addFirewallRules(Network network, List<NsxNetworkRule> netRules) {
CreateNsxDistributedFirewallRulesCommand command = new CreateNsxDistributedFirewallRulesCommand(network.getDomainId(),
network.getAccountId(), network.getDataCenterId(), network.getVpcId(), network.getId(), netRules);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, network.getDataCenterId());
return result.getResult();
}
public boolean deleteFirewallRules(Network network, List<NsxNetworkRule> netRules) {
DeleteNsxDistributedFirewallRulesCommand command = new DeleteNsxDistributedFirewallRulesCommand(network.getDomainId(),
network.getAccountId(), network.getDataCenterId(), network.getVpcId(), network.getId(), netRules);
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, network.getDataCenterId());
return result.getResult();
}
}

View File

@ -0,0 +1,147 @@
// 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.utils;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.dao.NsxProviderDao;
import com.cloud.network.element.NsxProviderVO;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.NsxCommand;
import org.apache.cloudstack.service.NsxApiClient;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import static java.util.Objects.isNull;
@Component
public class NsxControllerUtils {
private static final Logger s_logger = Logger.getLogger(NsxControllerUtils.class);
@Inject
private AgentManager agentMgr;
@Inject
private NsxProviderDao nsxProviderDao;
public static String getNsxNatRuleId(long domainId, long accountId, long dataCenterId, long resourceId, boolean isForVpc) {
String resourcePrefix = isForVpc ? "V" : "N";
return String.format("D%s-A%s-Z%s-%s%s-NAT", domainId, accountId, dataCenterId, resourcePrefix, resourceId);
}
public static String getNsxDistributedFirewallPolicyRuleId(String segmentName, long ruleId) {
return String.format("%s-R%s", segmentName, ruleId);
}
public NsxAnswer sendNsxCommand(NsxCommand cmd, long zoneId) throws IllegalArgumentException {
NsxProviderVO nsxProviderVO = nsxProviderDao.findByZoneId(zoneId);
if (nsxProviderVO == null) {
s_logger.error("No NSX controller was found!");
throw new InvalidParameterValueException("Failed to find an NSX controller");
}
Answer answer = agentMgr.easySend(nsxProviderVO.getHostId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("NSX API Command failed");
throw new InvalidParameterValueException("Failed API call to NSX controller");
}
return (NsxAnswer) answer;
}
/**
* Generates the Tier 1 Gateway name and identifier for the resource on the NSX manager
*/
public static String getTier1GatewayName(long domainId, long accountId, long zoneId,
Long networkResourceId, boolean isResourceVpc) {
String resourcePrefix = isResourceVpc ? "V" : "N";
return String.format("D%s-A%s-Z%s-%s%s", domainId, accountId, zoneId, resourcePrefix, networkResourceId);
}
public static String getNsxSegmentId(long domainId, long accountId, long zoneId, Long vpcId, long networkId) {
String segmentName = String.format("D%s-A%s-Z%s", domainId, accountId, zoneId);
if (isNull(vpcId)) {
return String.format("%s-S%s", segmentName, networkId);
}
return String.format("%s-V%s-S%s",segmentName, vpcId, networkId);
}
public static String getNsxDhcpRelayConfigId(long zoneId, long domainId, long accountId, Long vpcId, long networkId) {
String suffix = "Relay";
if (isNull(vpcId)) {
return String.format("D%s-A%s-Z%s-S%s-%s", domainId, accountId, zoneId, networkId, suffix);
}
return String.format("D%s-A%s-Z%s-V%s-S%s-%s", domainId, accountId, zoneId, vpcId, networkId, suffix);
}
public static String getStaticNatRuleName(long domainId, long accountId, long zoneId, Long networkResourceId, boolean isVpcResource) {
String suffix = "-STATICNAT";
return getTier1GatewayName(domainId, accountId, zoneId, networkResourceId, isVpcResource) + suffix;
}
public static String getPortForwardRuleName(long domainId, long accountId, long zoneId, Long networkResourceId, long ruleId, boolean isVpcResource) {
String suffix = "-PF";
return getTier1GatewayName(domainId, accountId, zoneId, networkResourceId, isVpcResource) + suffix + ruleId;
}
public static String getServiceName(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) {
return protocol.equalsIgnoreCase("icmp") ?
String.format("%s-SVC-%s-%s-%s", ruleName, icmpType, icmpCode, protocol) :
String.format("%s-SVC-%s-%s", ruleName, port, protocol);
}
public static String getServiceEntryName(String ruleName, String port, String protocol) {
return ruleName + "-SE-" + port + "-" + protocol;
}
public static String getLoadBalancerName(String tier1GatewayName) {
return tier1GatewayName + "-LB";
}
public static String getLoadBalancerRuleName(String tier1GatewayName, long lbId) {
return tier1GatewayName + "-LB" + lbId;
}
public static String getServerPoolName(String tier1GatewayName, long lbId) {
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-SP";
}
public static String getActiveMonitorProfileName(String lbServerPoolName, String port, String protocol) {
return lbServerPoolName + "-" + protocol + "-" + port + "-AM";
}
public static String getVirtualServerName(String tier1GatewayName, long lbId) {
return getLoadBalancerRuleName(tier1GatewayName, lbId) + "-VS";
}
public static String getServerPoolMemberName(String tier1GatewayName, long vmId) {
return tier1GatewayName + "-VM" + vmId;
}
public static String getLoadBalancerAlgorithm(String algorithm) {
switch (algorithm) {
case "leastconn":
return NsxApiClient.LBAlgorithm.LEAST_CONNECTION.name();
case "source":
return NsxApiClient.LBAlgorithm.IP_HASH.name();
default:
return NsxApiClient.LBAlgorithm.ROUND_ROBIN.name();
}
}
}

View File

@ -0,0 +1,53 @@
// 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.utils;
import com.cloud.dc.DataCenter;
import com.cloud.domain.DomainVO;
import com.cloud.network.Network;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.VpcVO;
import com.cloud.user.Account;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import java.util.List;
public class NsxHelper {
private NsxHelper() {
}
public static CreateNsxDhcpRelayConfigCommand createNsxDhcpRelayConfigCommand(DomainVO domain, Account account, DataCenter zone, VpcVO vpc, Network network, List<String> addresses) {
Long vpcId = vpc != null ? vpc.getId() : null;
String vpcName = vpc != null ? vpc.getName() : null;
return new CreateNsxDhcpRelayConfigCommand(domain.getId(), account.getId(), zone.getId(),
vpcId, vpcName, network.getId(), network.getName(), addresses);
}
public static CreateNsxSegmentCommand createNsxSegmentCommand(DomainVO domain, Account account, DataCenter zone, String vpcName, NetworkVO networkVO) {
return new CreateNsxSegmentCommand(domain.getId(), account.getId(), zone.getId(),
networkVO.getVpcId(), vpcName, networkVO.getId(), networkVO.getName(), networkVO.getGateway(), networkVO.getCidr());
}
public static CreateOrUpdateNsxTier1NatRuleCommand createOrUpdateNsxNatRuleCommand(long domainId, long accountId, long zoneId,
String tier1Gateway, String action, String ipAddress,
String natRuleId) {
return new CreateOrUpdateNsxTier1NatRuleCommand(domainId, accountId, zoneId, tier1Gateway, action, ipAddress, natRuleId);
}
}

View File

@ -0,0 +1,32 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="nsxService" class="org.apache.cloudstack.service.NsxServiceImpl"/>
<bean id="nsxControllerUtils" class="org.apache.cloudstack.utils.NsxControllerUtils" />
</beans>

View File

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

View File

@ -0,0 +1,39 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="Nsx" class="org.apache.cloudstack.service.NsxElement">
<property name="name" value="Nsx"/>
</bean>
<bean id="nsxGuestNetworkGuru" class="org.apache.cloudstack.service.NsxGuestNetworkGuru">
<property name="name" value="NsxGuestNetworkGuru" />
</bean>
<bean id="NsxPublicNetworkGuru" class="org.apache.cloudstack.service.NsxPublicNetworkGuru">
<property name="name" value="NsxPublicNetworkGuru" />
</bean>
<bean id="nsxProviderService" class="org.apache.cloudstack.service.NsxProviderServiceImpl"/>
</beans>

View File

@ -0,0 +1,293 @@
// 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.network.dao.NetworkVO;
import com.cloud.utils.exception.CloudRuntimeException;
import com.vmware.nsx.model.TransportZone;
import com.vmware.nsx.model.TransportZoneListResult;
import com.vmware.nsx_policy.model.EnforcementPoint;
import com.vmware.nsx_policy.model.Site;
import junit.framework.Assert;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.CreateOrUpdateNsxTier1NatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.NsxCommand;
import org.apache.cloudstack.service.NsxApiClient;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import javax.naming.ConfigurationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class NsxResourceTest {
@Mock
NsxApiClient nsxApi;
NsxResource nsxResource;
AutoCloseable closeable;
@Mock
TransportZoneListResult transportZoneListResult;
private static final String transportZone = "Overlay";
private static final String tier0Gateway = "Tier0-GW01";
private static final String edgeCluster = "EdgeCluster";
private static final long domainId = 1L;
private static final long accountId = 2L;
private static final long zoneId = 1L;
@Before
public void setup() {
closeable = MockitoAnnotations.openMocks(this);
nsxResource = new NsxResource();
nsxResource.nsxApiClient = nsxApi;
nsxResource.transportZone = transportZone;
nsxResource.tier0Gateway = tier0Gateway;
nsxResource.edgeCluster = edgeCluster;
}
@After
public void tearDown() throws Exception {
closeable.close();
}
@Test
public void testConfigure() throws ConfigurationException {
Map<String, Object> params = new HashMap<>();
params.put("name", "nsxController");
params.put("guid", "5944b356-644f-11ee-b8c2-f37bc1b564ff");
params.put("zoneId", "1");
params.put("hostname", "host1");
params.put("username", "admin");
params.put("password", "password");
params.put("tier0Gateway", tier0Gateway);
params.put("edgeCluster", edgeCluster);
params.put("transportZone", transportZone);
params.put("port", "443");
Assert.assertTrue(nsxResource.configure("nsx", params));
}
@Test
public void testConfigure_MissingParameter() throws ConfigurationException {
Map<String, Object> params = new HashMap<>();
assertThrows(ConfigurationException.class, () -> nsxResource.configure("nsx", params));
}
@Test
public void testCreateNsxTier1Gateway() {
NsxCommand command = new CreateNsxTier1GatewayCommand(domainId, accountId, zoneId,
3L, "VPC01", true, false);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertTrue(answer.getResult());
}
@Test
public void testCreateNsxTier1GatewayError() {
NsxCommand command = new CreateNsxTier1GatewayCommand(domainId, accountId, zoneId,
3L, "VPC01", true, false);
Mockito.doThrow(new CloudRuntimeException("ERROR"))
.when(nsxApi).createTier1Gateway(anyString(), anyString(), anyString(), anyBoolean());
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testDeleteTier1Gateway() {
NsxCommand command = new DeleteNsxTier1GatewayCommand(domainId, accountId, zoneId,
2L, "VPC01", true);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertTrue(answer.getResult());
}
@Test
public void testDeleteTier1GatewayError() {
NsxCommand command = new DeleteNsxTier1GatewayCommand(domainId, accountId, zoneId,
2L, "VPC01", true);
Mockito.doThrow(new CloudRuntimeException("ERROR")).when(nsxApi).deleteTier1Gateway(anyString());
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testCreateNsxSegment() {
NetworkVO tierNetwork = new NetworkVO();
tierNetwork.setName("tier1");
tierNetwork.setCidr("10.0.0.0/8");
tierNetwork.setGateway("10.0.0.1");
Site site = mock(Site.class);
List<Site> siteList = List.of(site);
EnforcementPoint enforcementPoint = mock(EnforcementPoint.class);
List<EnforcementPoint> enforcementPointList = List.of(enforcementPoint);
List<TransportZone> transportZoneList = List.of(new TransportZone.Builder().setDisplayName(transportZone).build());
NsxCommand command = new CreateNsxSegmentCommand(domainId, accountId, zoneId,
2L, "VPC01", 3L, "Web", "10.10.10.1", "10.10.10.0/24");
when(nsxApi.getDefaultSiteId()).thenReturn("site1");
when(nsxApi.getDefaultEnforcementPointPath(anyString())).thenReturn("enforcementPointPath");
when(nsxApi.getTransportZones()).thenReturn(transportZoneListResult);
when(transportZoneListResult.getResults()).thenReturn(transportZoneList);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertTrue(answer.getResult());
}
@Test
public void testCreateNsxSegmentEmptySites() {
when(nsxApi.getDefaultSiteId()).thenReturn(null);
CreateNsxSegmentCommand command = Mockito.mock(CreateNsxSegmentCommand.class);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testCreateNsxSegmentEmptyEnforcementPoints() {
Site site = mock(Site.class);
when(nsxApi.getDefaultSiteId()).thenReturn("site1");
when(nsxApi.getDefaultEnforcementPointPath(anyString())).thenReturn(null);
CreateNsxSegmentCommand command = Mockito.mock(CreateNsxSegmentCommand.class);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testCreateNsxSegmentEmptyTransportZones() {
Site site = mock(Site.class);
when(nsxApi.getDefaultSiteId()).thenReturn("site1");
CreateNsxSegmentCommand command = Mockito.mock(CreateNsxSegmentCommand.class);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testDeleteNsxSegment() {
NetworkVO tierNetwork = new NetworkVO();
tierNetwork.setName("tier1");
DeleteNsxSegmentCommand command = new DeleteNsxSegmentCommand(domainId, accountId, zoneId,
3L, "VPC01", 2L, "Web");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertTrue(answer.getResult());
}
@Test
public void testDeleteNsxSegmentError() {
NetworkVO tierNetwork = new NetworkVO();
tierNetwork.setName("tier1");
DeleteNsxSegmentCommand command = new DeleteNsxSegmentCommand(domainId, accountId, zoneId,
3L, "VPC01", 2L, "Web");
doThrow(new CloudRuntimeException("ERROR")).when(nsxApi).deleteSegment(anyLong(), anyLong(), anyLong(), anyLong(), anyLong(), anyString());
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertFalse(answer.getResult());
}
@Test
public void testCreateStaticNat() {
CreateNsxStaticNatCommand cmd = new CreateNsxStaticNatCommand(domainId, accountId, zoneId, 3L, "VPC01", true, 2L, "10.1.12.10", "172.30.20.12");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testCreatePortForwardRule() {
CreateNsxPortForwardRuleCommand cmd = new CreateNsxPortForwardRuleCommand(domainId, accountId, zoneId, 3L, "VPC01", true, 2L, 5L, "10.1.12.10", "172.30.20.12", "2222", "22", "tcp");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testDeleteNsxNatRule() {
DeleteNsxNatRuleCommand cmd = new DeleteNsxNatRuleCommand(domainId, accountId, zoneId, 3L, "VPC01", true, 2L, 5L, "22", "tcp");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testCreateNsxLoadBalancerRule() {
List<NsxLoadBalancerMember> loadBalancerMembers = List.of(new NsxLoadBalancerMember(
1L, "172.30.20.12", 6443
));
CreateNsxLoadBalancerRuleCommand cmd = new CreateNsxLoadBalancerRuleCommand(domainId, accountId, zoneId,
3L, "VPC01", true, loadBalancerMembers, 1L, "6443", "6443", "RoundRobin", "TCP");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testCreateNsxDistributedFirewallRule() {
List<NsxNetworkRule> networkRules = List.of(new NsxNetworkRule());
CreateNsxDistributedFirewallRulesCommand cmd = new CreateNsxDistributedFirewallRulesCommand(domainId, accountId, zoneId,
3L, 1L, networkRules);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testDeleteNsxDistributedFirewallRule() {
List<NsxNetworkRule> networkRules = List.of(new NsxNetworkRule());
DeleteNsxDistributedFirewallRulesCommand cmd = new DeleteNsxDistributedFirewallRulesCommand(domainId, accountId, zoneId,
3L, 1L, networkRules);
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(cmd);
assertTrue(answer.getResult());
}
@Test
public void testCreateTier1NatRule() {
long vpcId = 5L;
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(domainId, accountId, zoneId, vpcId, true);
CreateOrUpdateNsxTier1NatRuleCommand command = new CreateOrUpdateNsxTier1NatRuleCommand(domainId, accountId, zoneId,
tier1GatewayName, "SNAT", "10.1.10.10", "natRuleId");
NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command);
assertTrue(answer.getResult());
}
}

View File

@ -0,0 +1,96 @@
// 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.Network;
import com.vmware.nsx_policy.infra.domains.Groups;
import com.vmware.nsx_policy.model.Group;
import com.vmware.nsx_policy.model.PathExpression;
import com.vmware.vapi.bindings.Service;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.function.Function;
public class NsxApiClientTest {
@Mock
private Function<Class<? extends Service>, Service> nsxService;
@Mock
private Groups groupService;
private NsxApiClient client = new NsxApiClient();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
client.nsxService = nsxService;
Mockito.when(nsxService.apply(Groups.class)).thenReturn(groupService);
}
@Test
public void testCreateGroupForSegment() {
final Group[] groups = new Group[1];
final PathExpression[] pathExpressions = new PathExpression[1];
try (MockedConstruction<Group> ignored = Mockito.mockConstruction(Group.class, (mock, context) -> {
groups[0] = mock;
}); MockedConstruction<PathExpression> ignoredExp = Mockito.mockConstruction(PathExpression.class, (mock, context) -> {
pathExpressions[0] = mock;
})
) {
String segmentName = "segment1";
client.createGroupForSegment(segmentName);
Mockito.verify(groupService).patch(NsxApiClient.DEFAULT_DOMAIN, segmentName, groups[0]);
String segmentPath = String.format("%s/%s", NsxApiClient.SEGMENTS_PATH, segmentName);
Mockito.verify(groups[0]).setExpression(List.of(pathExpressions[0]));
Mockito.verify(pathExpressions[0]).setPaths(List.of(segmentPath));
}
}
@Test
public void testGetGroupsForTrafficIngress() {
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getTrafficType()).thenReturn("Ingress");
Mockito.when(rule.getService()).thenReturn(Network.Service.NetworkACL);
String segmentName = "segment";
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);
Assert.assertEquals(List.of("ANY"), sourceGroups);
Assert.assertEquals(List.of(String.format("%s/%s", NsxApiClient.GROUPS_PATH_PREFIX, segmentName)), destinationGroups);
}
@Test
public void testGetGroupsForTrafficEgress() {
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
Mockito.when(rule.getTrafficType()).thenReturn("Egress");
Mockito.when(rule.getService()).thenReturn(Network.Service.NetworkACL);
String segmentName = "segment";
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);
Assert.assertEquals(List.of(String.format("%s/%s", NsxApiClient.GROUPS_PATH_PREFIX, segmentName)), sourceGroups);
Assert.assertEquals(List.of("ANY"), destinationGroups);
}
}

View File

@ -0,0 +1,495 @@
// 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.api.ApiDBUtils;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.StaticNatImpl;
import com.cloud.network.vpc.NetworkACLItem;
import com.cloud.network.vpc.NetworkACLItemVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.resource.ResourceManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.net.Ip;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.resource.NsxNetworkRule;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class NsxElementTest {
@Mock
DataCenterDao dataCenterDao;
@Mock
NsxServiceImpl nsxService;
@Mock
AccountManager accountManager;
@Mock
NetworkDao networkDao;
@Mock
ResourceManager resourceManager;
@Mock
PhysicalNetworkDao physicalNetworkDao;
@Mock
NetworkModel networkModel;
@Mock
Vpc vpc;
@Mock
DataCenterVO zone;
@Mock
DataCenterVO dataCenterVO;
@Mock
Account account;
@Mock
DomainVO domain;
@Mock
IPAddressDao ipAddressDao;
@Mock
VMInstanceDao vmInstanceDao;
@Mock
VpcDao vpcDao;
@Mock
UserVmDao userVmDao;
@Mock
private VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
@Mock
LoadBalancerVMMapDao lbVmMapDao;
NsxElement nsxElement;
ReservationContext reservationContext;
DeployDestination deployDestination;
@Mock
DomainDao domainDao;
@Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
nsxElement = new NsxElement();
nsxElement.dataCenterDao = dataCenterDao;
nsxElement.nsxService = nsxService;
nsxElement.accountMgr = accountManager;
nsxElement.networkDao = networkDao;
nsxElement.resourceManager = resourceManager;
nsxElement.physicalNetworkDao = physicalNetworkDao;
nsxElement.domainDao = domainDao;
nsxElement.networkModel = networkModel;
nsxElement.vpcOfferingServiceMapDao = vpcOfferingServiceMapDao;
nsxElement.ipAddressDao = ipAddressDao;
nsxElement.vmInstanceDao = vmInstanceDao;
nsxElement.vpcDao = vpcDao;
nsxElement.lbVmMapDao = lbVmMapDao;
Field field = ApiDBUtils.class.getDeclaredField("s_ipAddressDao");
field.setAccessible(true);
field.set(null, ipAddressDao);
field = ApiDBUtils.class.getDeclaredField("s_userVmDao");
field.setAccessible(true);
field.set(null, userVmDao);
reservationContext = mock(ReservationContext.class);
deployDestination = mock(DeployDestination.class);
when(vpc.getZoneId()).thenReturn(1L);
when(vpc.getAccountId()).thenReturn(2L);
when(dataCenterVO.getId()).thenReturn(1L);
when(vpc.getName()).thenReturn("VPC01");
when(accountManager.getAccount(2L)).thenReturn(account);
when(dataCenterDao.findById(anyLong())).thenReturn(dataCenterVO);
when(domainDao.findById(anyLong())).thenReturn(domain);
when(vpc.getZoneId()).thenReturn(1L);
when(vpc.getName()).thenReturn("testVPC");
PhysicalNetworkVO physicalNetworkVO = new PhysicalNetworkVO();
physicalNetworkVO.setIsolationMethods(List.of("NSX"));
List<PhysicalNetworkVO> physicalNetworkVOList = List.of(physicalNetworkVO);
when(physicalNetworkDao.listByZoneAndTrafficType(1L, Networks.TrafficType.Guest)).thenReturn(physicalNetworkVOList);
}
@Test
public void testImplementVpc() throws ResourceUnavailableException, InsufficientCapacityException {
assertTrue(nsxElement.implementVpc(vpc, deployDestination, reservationContext));
}
@Test
public void testShutdownVpc() {
when(nsxService.deleteVpcNetwork(anyLong(), anyLong(), anyLong(), anyLong(), anyString())).thenReturn(true);
assertTrue(nsxElement.shutdownVpc(vpc, reservationContext));
}
@Test
public void testTransformActionValue() {
NsxNetworkRule.NsxRuleAction action = nsxElement.transformActionValue(NetworkACLItem.Action.Deny);
Assert.assertEquals(NsxNetworkRule.NsxRuleAction.DROP, action);
}
@Test
public void testTransformCidrListValuesEmptyList() {
List<String> values = nsxElement.transformCidrListValues(null);
Assert.assertNotNull(values);
Assert.assertTrue(values.isEmpty());
}
@Test
public void testTransformCidrListValuesList() {
List<String> values = nsxElement.transformCidrListValues(List.of("0.0.0.0/0"));
Assert.assertEquals(1, values.size());
Assert.assertEquals("ANY", values.get(0));
}
@Test
public void testCanHandleService() {
when(networkModel.isProviderForNetwork(any(Network.Provider.class), anyLong())).thenReturn(true);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
NetworkVO network = new NetworkVO();
network.setName("network1");
assertTrue(nsxElement.canHandle(network, service));
}
@Test
public void testApplyStaticNatRules() throws ResourceUnavailableException {
StaticNatImpl rule = new StaticNatImpl(1L , 1L, 3L, 7L, "172.30.10.15", false);
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
Ip ip = new Ip("10.1.13.15");
IPAddressVO ipAddress = new IPAddressVO(ip, 2L, 0xaabbccddeeffL, 3L, false);
ipAddress.setAssociatedWithVmId(10L);
VMInstanceVO vm = new VMInstanceVO(10L, 9L, "vm1", "i-5-10-VM" , VirtualMachine.Type.User,
18L, Hypervisor.HypervisorType.VMware, 26L,
2L, 5L, 6L, false, false);
NicVO nic = Mockito.mock(NicVO.class);
VpcVO vpc = Mockito.mock(VpcVO.class);
when(ipAddressDao.findByIdIncludingRemoved(anyLong())).thenReturn(ipAddress);
when(vmInstanceDao.findByIdIncludingRemoved(anyLong())).thenReturn(vm);
when(networkModel.getNicInNetworkIncludingRemoved(anyLong(), anyLong())).thenReturn(nic);
when(vpcDao.findById(anyLong())).thenReturn(vpc);
when(vpc.getId()).thenReturn(1L);
when(vpc.getName()).thenReturn("vpc1");
when(nsxService.createStaticNatRule(anyLong(), anyLong(), anyLong(), anyLong(), anyString(), anyBoolean(), anyLong(), anyString(), anyString())).thenReturn(true);
assertTrue(nsxElement.applyStaticNats(networkVO, List.of(rule)));
}
@Test
public void testApplyPFRules_add() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
PortForwardingRuleVO rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
5L, 2L, 15L);
rule.setState(FirewallRule.State.Add);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
assertTrue(nsxElement.applyPFRules(networkVO, List.of(rule)));
}
@Test
public void testApplyPFRules_delete() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
PortForwardingRuleVO rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
5L, 2L, 15L);
rule.setState(FirewallRule.State.Revoke);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
VpcVO vpcVO = Mockito.mock(VpcVO.class);
when(vpcDao.findById(1L)).thenReturn(vpcVO);
when(vpcVO.getDomainId()).thenReturn(2L);
IPAddressVO ipAddress = new IPAddressVO(new Ip("10.1.13.10"), 1L, 1L, 1L,false);
when(ApiDBUtils.findIpAddressById(anyLong())).thenReturn(ipAddress);
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
when(nsxService.deletePortForwardRule(any(NsxNetworkRule.class))).thenReturn(true);
assertTrue(nsxElement.applyPFRules(networkVO, List.of(rule)));
}
@Test
public void testGetVpcOrNetworkReturnsVpcIfVpcIdPresent() {
VpcVO vpc = new VpcVO();
when(vpcDao.findById(anyLong())).thenReturn(vpc);
Pair<VpcVO, NetworkVO> vpcNetworkPair = nsxElement.getVpcOrNetwork(1L, 1L);
assertNotNull(vpcNetworkPair.first());
assertNull(vpcNetworkPair.second());
}
@Test
public void testGetVpcOrNetworkReturnsNetworkIfVpcIdNotPresent() {
NetworkVO network = new NetworkVO();
when(networkDao.findById(anyLong())).thenReturn(network);
Pair<VpcVO, NetworkVO> vpcNetworkPair = nsxElement.getVpcOrNetwork(null, 1L);
assertNull(vpcNetworkPair.first());
assertNotNull(vpcNetworkPair.second());
}
private Method getPublicPortRangeMethod() throws NoSuchMethodException {
Method method = NsxElement.class.getDeclaredMethod("getPublicPortRange", PortForwardingRule.class);
method.setAccessible(true);
return method;
}
private Method getPrivatePFPortRangeMethod() throws NoSuchMethodException {
Method method = NsxElement.class.getDeclaredMethod("getPrivatePFPortRange", PortForwardingRule.class);
method.setAccessible(true);
return method;
}
private Method getPrivatePortRangeMethod() throws NoSuchMethodException {
Method method = NsxElement.class.getDeclaredMethod("getPrivatePortRange", FirewallRule.class);
method.setAccessible(true);
return method;
}
private Method getPrivatePortRangeForACLRuleMethod() throws NoSuchMethodException {
Method method = NsxElement.class.getDeclaredMethod("getPrivatePortRangeForACLRule", NetworkACLItem.class);
method.setAccessible(true);
return method;
}
@Test
public void testGetPublicPortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
5L, 2L, 15L);
assertEquals("80-90", getPublicPortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPublicPortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 80, new Ip("172.30.10.11"), 8080, 8080, "tcp", 12L,
5L, 2L, 15L);
assertEquals("80", getPublicPortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePFPortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 90, new Ip("172.30.10.11"), 8080, 8090, "tcp", 12L,
5L, 2L, 15L);
assertEquals("8080-8090", getPrivatePFPortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePFPortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
PortForwardingRule rule = new PortForwardingRuleVO("1", 11L, 80, 80, new Ip("172.30.10.11"), 8080, 8080, "tcp", 12L,
5L, 2L, 15L);
assertEquals("8080", getPrivatePFPortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePortRangeWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 80, "tcp", 23L, 5L, 2L,
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
assertEquals("80", getPrivatePortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePortRangeWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 90, "tcp", 23L, 5L, 2L,
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
assertEquals("80-90", getPrivatePortRangeMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePortRangeForACLWhenStartAndEndPortNumbersAreSame() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
NetworkACLItem rule = new NetworkACLItemVO(80, 80, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
2, null);
assertEquals("80", getPrivatePortRangeForACLRuleMethod().invoke(null, rule));
}
@Test
public void testGetPrivatePortRangeForACLWhenStartAndEndPortNumbersAreDifferent() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
NetworkACLItem rule = new NetworkACLItemVO(80, 90, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
2, null);
assertEquals("80-90", getPrivatePortRangeForACLRuleMethod().invoke(null, rule));
}
@Test
public void testApplyLBRules_add() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
LoadBalancerVO lb = new LoadBalancerVO(null, null, null, 0L, 8080, 8081, null, 0L, 0L, 1L, null, null);
lb.setState(FirewallRule.State.Add);
LoadBalancingRule.LbDestination destination = new LoadBalancingRule.LbDestination(6443, 6443, "172.30.110.11", false);
LoadBalancingRule rule = new LoadBalancingRule(lb, List.of(destination), null, null, new Ip("10.1.13.10"));
VpcVO vpc = Mockito.mock(VpcVO.class);
IPAddressVO ipAddress = new IPAddressVO(new Ip("10.1.13.10"), 1L, 1L, 1L,false);
when(vpcDao.findById(anyLong())).thenReturn(vpc);
when(vpc.getDomainId()).thenReturn(2L);
when(vpc.getAccountId()).thenReturn(5L);
when(ipAddressDao.findByIpAndDcId(anyLong(), anyString())).thenReturn(ipAddress);
when(nsxService.createLbRule(any(NsxNetworkRule.class))).thenReturn(true);
assertTrue(nsxElement.applyLBRules(networkVO, List.of(rule)));
}
@Test
public void testApplyLBRules_delete() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
LoadBalancerVO lb = new LoadBalancerVO(null, null, null, 0L, 8080, 8081, null, 0L, 0L, 1L, null, null);
lb.setState(FirewallRule.State.Revoke);
LoadBalancingRule.LbDestination destination = new LoadBalancingRule.LbDestination(6443, 6443, "172.30.110.11", false);
LoadBalancingRule rule = new LoadBalancingRule(lb, List.of(destination), null, null, new Ip("10.1.13.10"));
VpcVO vpc = Mockito.mock(VpcVO.class);
IPAddressVO ipAddress = new IPAddressVO(new Ip("10.1.13.10"), 1L, 1L, 1L,false);
when(vpcDao.findById(anyLong())).thenReturn(vpc);
when(vpc.getDomainId()).thenReturn(2L);
when(vpc.getAccountId()).thenReturn(5L);
when(ipAddressDao.findByIpAndDcId(anyLong(), anyString())).thenReturn(ipAddress);
when(nsxService.deleteLbRule(any(NsxNetworkRule.class))).thenReturn(true);
assertTrue(nsxElement.applyLBRules(networkVO, List.of(rule)));
}
@Test
public void testApplyNetworkAclRules() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
NetworkACLItem rule = new NetworkACLItemVO(80, 80, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
2, null);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
when(nsxService.addFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
assertTrue(nsxElement.applyNetworkACLs(networkVO, List.of(rule)));
}
@Test
public void testDeleteNetworkAclRules() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
NetworkACLItemVO rule = new NetworkACLItemVO(80, 80, "udp", 10L, List.of("172.30.10.0/24"), null, null, NetworkACLItem.TrafficType.Ingress, NetworkACLItem.Action.Allow,
2, null);
rule.setState(NetworkACLItem.State.Revoke);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
when(nsxService.deleteFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
when(nsxService.addFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
assertTrue(nsxElement.applyNetworkACLs(networkVO, List.of(rule)));
}
@Test
public void testApplyFirewallRules() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 80, "tcp", 23L, 5L, 2L,
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
when(nsxService.addFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
assertTrue(nsxElement.applyFWRules(networkVO, List.of(rule)));
}
@Test
public void testRevokeFirewallRules() throws ResourceUnavailableException {
NetworkVO networkVO = new NetworkVO(1L, Networks.TrafficType.Public, Networks.Mode.Static,
Networks.BroadcastDomainType.NSX, 12L, 2L, 5L, 1L, "network1",
"network1", null, Network.GuestType.Isolated, 2L, 2L,
ControlledEntity.ACLType.Domain, false, 1L, false );
FirewallRuleVO rule = new FirewallRuleVO("1", 11L, 80, 80, "tcp", 23L, 5L, 2L,
FirewallRule.Purpose.Firewall, List.of("172.30.10.0/24"), null, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.User);
rule.setState(FirewallRule.State.Revoke);
Network.Service service = new Network.Service("service1", new Network.Capability("capability"));
when(nsxElement.canHandle(networkVO, service)).thenReturn(true);
when(nsxService.deleteFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
when(nsxService.addFirewallRules(any(Network.class), any(List.class))).thenReturn(true);
assertTrue(nsxElement.applyFWRules(networkVO, List.of(rule)));
}
}

View File

@ -0,0 +1,324 @@
// 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.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.guru.GuestNetworkGuru;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Pair;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.NsxAnswer;
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
import org.apache.cloudstack.agent.api.NsxCommand;
import org.apache.cloudstack.utils.NsxControllerUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.lenient;
@RunWith(MockitoJUnitRunner.class)
public class NsxGuestNetworkGuruTest {
@Mock
PhysicalNetworkDao physicalNetworkDao;
@Mock
DataCenterDao dcDao;
@Mock
VpcDao vpcDao;
@Mock
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@Mock
NsxControllerUtils nsxControllerUtils;
@Mock
AccountDao accountDao;
@Mock
PhysicalNetworkVO physicalNetwork;
@Mock
DataCenterVO dataCenterVO;
@Mock
NetworkOffering offering;
@Mock
DeploymentPlan plan;
@Mock
Network network;
@Mock
Account account;
@Mock
VpcVO vpcVO;
@Mock
NetworkModel networkModel;
@Mock
DomainDao domainDao;
@Mock
NetworkDao networkDao;
@Mock
IpAddressManager ipAddressManager;
@Mock
NetworkOfferingDao networkOfferingDao;
NsxGuestNetworkGuru guru;
AutoCloseable closeable;
@Before
public void setUp() throws IllegalAccessException, NoSuchFieldException {
closeable = MockitoAnnotations.openMocks(this);
guru = new NsxGuestNetworkGuru();
ReflectionTestUtils.setField(guru, "_dcDao", dcDao);
ReflectionTestUtils.setField(guru, "_networkDao", networkDao);
ReflectionTestUtils.setField(guru, "_networkModel", networkModel);
ReflectionTestUtils.setField(guru, "_vpcDao", vpcDao);
ReflectionTestUtils.setField((GuestNetworkGuru) guru, "_ipAddrMgr", ipAddressManager);
ReflectionTestUtils.setField((GuestNetworkGuru) guru, "_networkModel", networkModel);
ReflectionTestUtils.setField((GuestNetworkGuru) guru, "networkOfferingDao", networkOfferingDao);
ReflectionTestUtils.setField((GuestNetworkGuru) guru, "_physicalNetworkDao", physicalNetworkDao);
guru.networkOfferingServiceMapDao = networkOfferingServiceMapDao;
guru.nsxControllerUtils = nsxControllerUtils;
guru.accountDao = accountDao;
guru.domainDao = domainDao;
Mockito.when(dataCenterVO.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
when(physicalNetwork.getIsolationMethods()).thenReturn(List.of("NSX"));
when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated);
when(offering.getNsxMode()).thenReturn(NetworkOffering.NsxMode.NATTED.name());
when(offering.getId()).thenReturn(1L);
when(plan.getDataCenterId()).thenReturn(1L);
when(plan.getPhysicalNetworkId()).thenReturn(1L);
when(vpcDao.findById(anyLong())).thenReturn(vpcVO);
when(vpcVO.getName()).thenReturn("VPC01");
when(account.getAccountId()).thenReturn(1L);
when(accountDao.findById(anyLong())).thenReturn(mock(AccountVO.class));
when(domainDao.findById(anyLong())).thenReturn(mock(DomainVO.class));
Mockito.when(networkOfferingServiceMapDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.Nsx)).thenReturn(
true);
}
@After
public void tearDown() throws Exception {
closeable.close();
}
@Test
public void testIsMyIsolationMethod() {
assertTrue(guru.isMyIsolationMethod(physicalNetwork));
}
@Test
public void testCanHandle() {
assertTrue(guru.canHandle(offering, dataCenterVO.getNetworkType(), physicalNetwork));
}
@Test
public void testNsxNetworkDesign() {
when(physicalNetworkDao.findById(ArgumentMatchers.anyLong())).thenReturn(physicalNetwork);
when(dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dataCenterVO);
Network designedNetwork = guru.design(offering, plan, network, "", 1L, account);
assertNotNull(designedNetwork);
assertSame(Networks.BroadcastDomainType.NSX, designedNetwork.getBroadcastDomainType());
assertSame(Network.State.Allocated, designedNetwork.getState());
}
@Test
public void testNsxNetworkSetup() {
when(dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dataCenterVO);
when(networkDao.findById(ArgumentMatchers.anyLong())).thenReturn(mock(NetworkVO.class));
when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong())).thenReturn(
new NsxAnswer(new NsxCommand(), true, ""));
guru.setup(network, 1L);
verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong());
}
@Test
public void testNsxNetworkImplementation() {
final DeployDestination deployDestination = mock(DeployDestination.class);
final ReservationContext reservationContext = mock(ReservationContext.class);
when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
when(network.getMode()).thenReturn(Networks.Mode.Dhcp);
when(network.getGateway()).thenReturn("192.168.1.1");
when(network.getCidr()).thenReturn("192.168.1.0/24");
when(network.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.NSX);
when(network.getNetworkOfferingId()).thenReturn(1L);
lenient().when(network.getState()).thenReturn(Network.State.Implementing);
when(network.getDataCenterId()).thenReturn(2L);
when(network.getPhysicalNetworkId()).thenReturn(3L);
when(network.getVpcId()).thenReturn(4L);
when(offering.isRedundantRouter()).thenReturn(false);
lenient().when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated);
final Network implemented = guru.implement(network, offering, deployDestination, reservationContext);
assertEquals(Networks.BroadcastDomainType.NSX.toUri("nsx"), implemented.getBroadcastUri());
assertEquals("192.168.1.1", implemented.getGateway());
assertEquals("192.168.1.0/24", implemented.getCidr());
assertEquals(Networks.Mode.Dhcp, implemented.getMode());
assertEquals(Networks.BroadcastDomainType.NSX, implemented.getBroadcastDomainType());
assertEquals(1L, implemented.getNetworkOfferingId());
assertEquals(Network.State.Implemented, implemented.getState());
assertEquals(2L, implemented.getDataCenterId());
assertEquals(3L, implemented.getPhysicalNetworkId().longValue());
assertEquals(4L, implemented.getVpcId().longValue());
assertFalse(implemented.isRedundant());
}
@Test
public void testAllocateForUserVM() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Network network = Mockito.mock(Network.class);
NicProfile nicProfile = Mockito.mock(NicProfile.class);
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
VirtualMachine virtualMachine = Mockito.mock(VirtualMachine.class);
Pair<String, String> dns = new Pair<>("10.1.5.1", "8.8.8.8");
String macAddress = "00:00:00:11:1D:1E:CD";
when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
when(vmProfile.getVirtualMachine()).thenReturn(virtualMachine);
when(virtualMachine.getType()).thenReturn(VirtualMachine.Type.User);
when(networkModel.getNetworkIp4Dns(any(Network.class), nullable(DataCenter.class))).thenReturn(dns);
when(nicProfile.getMacAddress()).thenReturn(macAddress);
when(networkOfferingDao.isIpv6Supported(anyLong())).thenReturn(false);
NicProfile profile = guru.allocate(network, nicProfile, vmProfile);
assertNotNull(profile);
}
@Test
public void testAllocateForDomainRouter() throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
Network network = Mockito.mock(Network.class);
NicProfile nicProfile = Mockito.mock(NicProfile.class);
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
VirtualMachine virtualMachine = Mockito.mock(VirtualMachine.class);
Pair<String, String> dns = new Pair<>("10.1.5.1", "8.8.8.8");
String macAddress = "00:00:00:11:1D:1E:CD";
when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
when(vmProfile.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
when(vmProfile.getVirtualMachine()).thenReturn(virtualMachine);
when(virtualMachine.getType()).thenReturn(VirtualMachine.Type.DomainRouter);
when(network.getId()).thenReturn(2L);
when(nicProfile.getMacAddress()).thenReturn(macAddress);
when(networkOfferingDao.isIpv6Supported(anyLong())).thenReturn(false);
when(network.getDataCenterId()).thenReturn(1L);
when(network.getAccountId()).thenReturn(5L);
when(network.getVpcId()).thenReturn(51L);
when(dcDao.findById(anyLong())).thenReturn(Mockito.mock(DataCenterVO.class));
when(accountDao.findById(anyLong())).thenReturn(Mockito.mock(AccountVO.class));
when(vpcDao.findById(anyLong())).thenReturn(Mockito.mock(VpcVO.class));
when(domainDao.findById(anyLong())).thenReturn(Mockito.mock(DomainVO.class));
when(nicProfile.getIPv4Address()).thenReturn("10.1.13.10");
when(nsxControllerUtils.sendNsxCommand(any(CreateNsxDhcpRelayConfigCommand.class),
anyLong())).thenReturn(new NsxAnswer(new NsxCommand(), true, ""));
NicProfile profile = guru.allocate(network, nicProfile, vmProfile);
assertNotNull(profile);
verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxDhcpRelayConfigCommand.class),
anyLong());
}
@Test
public void testCreateNsxSegmentForVpc() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
DataCenter dataCenter = Mockito.mock(DataCenter.class);
when(networkVO.getAccountId()).thenReturn(1L);
when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class),
anyLong())).thenReturn(new NsxAnswer(new NsxCommand(), true, ""));
guru.createNsxSegment(networkVO, dataCenter);
verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class),
anyLong());
}
@Test
public void testCreateNsxSegmentForIsolatedNetwork() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
DataCenter dataCenter = Mockito.mock(DataCenter.class);
when(networkVO.getAccountId()).thenReturn(1L);
when(networkVO.getVpcId()).thenReturn(null);
when(nsxControllerUtils.sendNsxCommand(any(CreateNsxTier1GatewayCommand.class),
anyLong())).thenReturn(new NsxAnswer(new NsxCommand(), true, ""));
when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class),
anyLong())).thenReturn(new NsxAnswer(new NsxCommand(), true, ""));
guru.createNsxSegment(networkVO, dataCenter);
verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxTier1GatewayCommand.class),
anyLong());
verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class),
anyLong());
}
}

Some files were not shown because too many files have changed in this diff Show More