bug 8655: add security group for direct tagged network

This commit is contained in:
Edison Su 2011-02-23 15:49:13 -05:00
parent 0c8b86fc56
commit adbd20ca5a
24 changed files with 237 additions and 132 deletions

View File

@ -1401,12 +1401,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
private Answer execute(SecurityIngressRulesCmd cmd) {
String vif = null;
try {
Connect conn = LibvirtConnection.getConnection();
List<InterfaceDef> nics = getInterfaces(conn, cmd.getVmName());
vif = nics.get(0).getBrName();
} catch (LibvirtException e) {
}
boolean result = add_network_rules(cmd.getVmName(),
Long.toString(cmd.getVmId()),
cmd.getGuestIp(),cmd.getSignature(),
Long.toString(cmd.getSeqNum()),
cmd.getGuestMac(),
cmd.stringifyRules());
cmd.stringifyRules(), vif);
if (!result) {
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
@ -2046,23 +2055,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (vmSpec.getType() != VirtualMachine.Type.User) {
default_network_rules_for_systemvm(vmName);
} else {
NicTO[] nics = vmSpec.getNics();
List<InterfaceDef> vifs = getInterfaces(conn, vmName);
StringBuilder rules = new StringBuilder();
for (NicTO nic : nics) {
if (nic.getIsolationUri() != null ) {
if (nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()) ||
nic.getType() == TrafficType.Public) {
rules.append(nic.getIp() + "," + nic.getMac() + "," + vifs.get(nic.getDeviceId()).getDevName() + ";") ;
}
}
}
if (rules.toString() != null)
default_network_rules(vmName, vmSpec.getId(), rules.toString());
}
}
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
@ -3179,7 +3172,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return true;
}
private boolean add_network_rules(String vmName, String vmId, String guestIP, String sig, String seq, String mac, String rules) {
private boolean add_network_rules(String vmName, String vmId, String guestIP, String sig, String seq, String mac, String rules, String vif) {
if (!_can_bridge_firewall) {
return false;
}
@ -3192,6 +3185,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.add("--sig", sig);
cmd.add("--seq", seq);
cmd.add("--vmmac", mac);
cmd.add("--vif", vif);
if (rules != null)
cmd.add("--rules", newRules);
String result = cmd.execute();

View File

@ -138,6 +138,7 @@ public class ApiConstants {
public static final String SECURITY_GROUP_IDS = "securitygroupids";
public static final String SECURITY_GROUP_NAME = "securitygroupname";
public static final String SECURITY_GROUP_ID = "securitygroupid";
public static final String SECURITY_GROUP_EANBLED = "securitygroupEnabled";
public static final String SENT = "sent";
public static final String SENT_BYTES = "sentbytes";
public static final String SERVICE_OFFERING_ID = "serviceofferingid";

View File

@ -25,6 +25,7 @@ import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.NetworkResponse;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@ -81,6 +82,9 @@ public class CreateNetworkCmd extends BaseCmd {
@Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain")
private String networkDomain;
@Parameter(name=ApiConstants.SECURITY_GROUP_EANBLED, type=CommandType.BOOLEAN, description="true if network is security group enabled, false otherwise")
private Boolean is_security_group_enabled;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -140,6 +144,10 @@ public class CreateNetworkCmd extends BaseCmd {
public String getNetworkDomain() {
return networkDomain;
}
public boolean isSecurityGroupEnabled() {
return is_security_group_enabled == null ? false : true;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -91,7 +91,8 @@ public class CreateVlanIpRangeCmd extends BaseCmd {
}
public Boolean isForVirtualNetwork() {
return forVirtualNetwork == null ? true : forVirtualNetwork;
return false;
//return forVirtualNetwork == null ? true : forVirtualNetwork;
}
public String getGateway() {

View File

@ -67,6 +67,9 @@ public class CreateZoneCmd extends BaseCmd {
@Parameter(name=ApiConstants.NETWORK_TYPE, type=CommandType.STRING, required=true, description="network type of the zone, can be Basic or Advanced")
private String networkType;
@Parameter(name=ApiConstants.SECURITY_GROUP_EANBLED, type=CommandType.BOOLEAN, description="true if network is security group enabled, false otherwise")
private Boolean is_security_group_enabled;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -112,6 +115,11 @@ public class CreateZoneCmd extends BaseCmd {
return networkType;
}
public boolean isSecurityGroupEnabled() {
return true;
//return is_security_group_enabled == null ? false : true;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -95,6 +95,9 @@ public class NetworkResponse extends BaseResponse{
@SerializedName("networkdomain") @Param(description="the network domain")
private String networkDomain;
@SerializedName(ApiConstants.SECURITY_GROUP_EANBLED) @Param(description="true if security group is enabled, false otherwise")
private Boolean isSecurityGroupEnabled;
public Long getId() {
return id;
}
@ -327,4 +330,12 @@ public class NetworkResponse extends BaseResponse{
this.networkDomain = networkDomain;
}
public Boolean getIsSecurityGroupEnabled() {
return this.isSecurityGroupEnabled;
}
public void setIsSecurityGroupEnabled(Boolean sgEnabled) {
this.isSecurityGroupEnabled = sgEnabled;
}
}

View File

@ -205,4 +205,6 @@ public interface Network extends ControlledEntity {
String getNetworkDomain();
boolean isSecurityGroupEnabled();
}

View File

@ -54,6 +54,7 @@ def can_bridge_firewall(privnic):
print "failed to turn on bridge netfilter"
exit(3)
'''
try:
execute("iptables -N BRIDGE-FIREWALL")
execute("iptables -N BRIDGE-FIREWALL")
@ -72,10 +73,8 @@ def can_bridge_firewall(privnic):
execute("iptables -A FORWARD -j DROP")
except:
result = 1
'''
if result == 1:
print "br firewall is not supported"
if not os.path.exists('/var/run/cloud'):
os.makedirs('/var/run/cloud')
@ -155,10 +154,9 @@ def destroy_ebtables_rules(vm_name):
except:
logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_name)
def default_ebtables_rules(vm_name, rules):
def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif):
vmchain_in = vm_name + "-in"
vmchain_out = vm_name + "-out"
rule = rules.split(";")[:-1]
for chain in [vmchain_in, vmchain_out]:
try:
@ -168,40 +166,30 @@ def default_ebtables_rules(vm_name, rules):
try:
# -s ! 52:54:0:56:44:32 -j DROP
for r in rule:
vif = r.split(",")[2]
execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " + vmchain_in)
execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vmchain_out)
execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " + vmchain_in)
execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vmchain_out)
except:
logging.debug("Failed to program default rules")
return 'false'
try:
for r in rule:
vm_ip = r.split(",")[0]
vm_mac = r.split(",")[1]
vif = r.split(",")[2]
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -i " + vif + " -p ARP -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP -s ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j DROP")
except:
logging.exception("Failed to program default ebtables IN rules")
return 'false'
try:
for r in rule:
vm_ip = r.split(",")[0]
vm_mac = r.split(",")[1]
vif = r.split(",")[2]
execute("ebtables -t nat -A " + vmchain_out + " -i " + vif + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_out + " -i " + vif + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vmchain_out + " -i " + vif + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -i " + vif + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -i " + vif + " -p ARP -j DROP")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Request -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply -j ACCEPT")
execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j DROP")
except:
logging.debug("Failed to program default ebtables OUT rules")
return 'false'
@ -235,7 +223,7 @@ def default_network_rules_systemvm(vm_name):
return 'true'
def default_network_rules(vm_name, vm_id, rules):
def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif):
vmName = vm_name
domID = getvmId(vm_name)
delete_rules_for_vm_in_bridge_firewall_chain(vmName)
@ -254,35 +242,25 @@ def default_network_rules(vm_name, vm_id, rules):
except:
execute("iptables -F " + vmchain_default)
rule = rules.split(";")[:-1]
try:
for r in rule:
vif = r.split(",")[2]
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default)
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default)
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default)
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default)
execute("iptables -A " + vmchain_default + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
#allow dhcp
for r in rule:
vif = r.split(",")[2]
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -p udp --dport 67 --sport 68 -j ACCEPT")
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -p udp --dport 68 --sport 67 -j ACCEPT")
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -p udp --dport 67 --sport 68 -j ACCEPT")
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -p udp --dport 68 --sport 67 -j ACCEPT")
#don't let vm spoof its ip address
for r in rule:
vmip = r.split(",")[0]
vif = r.split(",")[2]
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vmip + " -j ACCEPT")
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT")
execute("iptables -A " + vmchain_default + " -j " + vmchain)
except:
logging.debug("Failed to program default rules for vm " + vm_name)
return 'false'
default_ebtables_rules(vmchain, rules)
default_ebtables_rules(vmchain, vm_ip, vm_mac, vif)
for r in rule:
vm_ip = r.split(",")[0]
if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False:
logging.debug("Failed to log default network rules, ignoring")
if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False:
logging.debug("Failed to log default network rules, ignoring")
logging.debug("Programmed default rules for vm " + vm_name)
return 'true'
@ -441,7 +419,7 @@ def remove_rule_log_for_vm(vmName):
return result
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules):
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif):
try:
vmName = vm_name
domId = getvmId(vmName)
@ -458,6 +436,9 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules):
write_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno)
return 'true'
if changes[0] or changes[2]:
default_network_rules(vmName, vm_id, vm_ip, vmMac, vif)
lines = rules.split(';')[:-1]
logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name)
@ -549,7 +530,7 @@ if __name__ == '__main__':
if cmd == "can_bridge_firewall":
can_bridge_firewall(args[1])
elif cmd == "default_network_rules":
default_network_rules(option.vmName, option.vmID, option.rules)
default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif)
elif cmd == "destroy_network_rules_for_vm":
destroy_network_rules_for_vm(option.vmName)
elif cmd == "default_network_rules_systemvm":
@ -557,6 +538,6 @@ if __name__ == '__main__':
elif cmd == "get_rule_logs_for_vms":
get_rule_logs_for_vms()
elif cmd == "add_network_rules":
add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules)
add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif)
elif cmd == "cleanup_rules":
cleanup_rules()

View File

@ -2301,6 +2301,8 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setDns1(profile.getDns1());
response.setDns2(profile.getDns2());
response.setIsSecurityGroupEnabled(network.isSecurityGroupEnabled());
//populate capability
Map<Service, Map<Capability, String>> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId());
List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

View File

@ -112,7 +112,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
* @throws
* @throws
*/
DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId, NetworkType zoneType);
DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId, NetworkType zoneType, boolean isSecurityGroupEnabled);
/**
* Deletes a VLAN from the database, along with all of its IP addresses. Will not delete VLANs that have allocated IP addresses.
@ -173,7 +173,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
Vlan createVlanAndPublicIpRange(Long userId, Long zoneId, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, boolean forVirtualNetwork, String vlanId, Account account, Long networkId) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
void createDefaultNetworks(long zoneId) throws ConcurrentOperationException;
void createDefaultNetworks(long zoneId, boolean isSecurityGroupEnabled) throws ConcurrentOperationException;
DataCenterVO getZone(long id);

View File

@ -1091,7 +1091,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
@Override @DB
public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId, NetworkType zoneType) {
public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId, NetworkType zoneType, boolean isSecurityGroupEnabled) {
int vnetStart = 0;
int vnetEnd = 0;
if (vnetRange != null) {
@ -1134,8 +1134,11 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
//Create deafult networks
createDefaultNetworks(zone.getId());
createDefaultNetworks(zone.getId(), isSecurityGroupEnabled);
if (isSecurityGroupEnabled) {
_configDao.update(Config.DirectAttachSecurityGroupsEnabled.key(), "true");
}
txn.commit();
return zone;
} catch (Exception ex) {
@ -1148,7 +1151,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
@Override
public void createDefaultNetworks(long zoneId) throws ConcurrentOperationException{
public void createDefaultNetworks(long zoneId, boolean isSecurityGroupEnabled) throws ConcurrentOperationException{
DataCenterVO zone = _zoneDao.findById(zoneId);
//Create public, management, control and storage networks as a part of the zone creation
if (zone != null) {
@ -1168,6 +1171,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
broadcastDomainType = BroadcastDomainType.LinkLocal;
} else if (offering.getTrafficType() == TrafficType.Public) {
if (zone.getNetworkType() == NetworkType.Advanced) {
if (isSecurityGroupEnabled) {
isNetworkDefault = true;
userNetwork.setSecurityGroupEnabled(isSecurityGroupEnabled);
}
broadcastDomainType = BroadcastDomainType.Vlan;
} else {
continue;
@ -1176,6 +1183,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (zone.getNetworkType() == NetworkType.Basic) {
isNetworkDefault = true;
broadcastDomainType = BroadcastDomainType.Native;
userNetwork.setSecurityGroupEnabled(isSecurityGroupEnabled);
} else {
continue;
}
@ -1233,7 +1241,12 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
vnetRange = null;
}
return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, vnetRange, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType);
boolean securityGroupEnabled = cmd.isSecurityGroupEnabled();
if (zoneType == NetworkType.Basic) {
securityGroupEnabled = true;
}
return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, vnetRange, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, securityGroupEnabled);
}
@Override
@ -1588,7 +1601,11 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (zone.getNetworkType() == DataCenter.NetworkType.Basic) {
networkId = _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId();
} else {
throw new InvalidParameterValueException("Nework id is required for Direct vlan creation ");
network = _networkMgr.getNetworkWithSecurityGroupEnabled(zoneId);
if (network == null) {
throw new InvalidParameterValueException("Nework id is required for Direct vlan creation ");
}
networkId = network.getId();
}
} else if (network.getGuestType() == null || network.getGuestType() == GuestIpType.Virtual) {
throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId + " with GuestType: " + network.getGuestType());
@ -1600,7 +1617,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
endIP = startIP;
}
if (forVirtualNetwork || zone.getNetworkType() == DataCenter.NetworkType.Basic) {
if (forVirtualNetwork || zone.getNetworkType() == DataCenter.NetworkType.Basic || network.isSecurityGroupEnabled()) {
if (vlanGateway == null || vlanNetmask == null || zoneId == null) {
throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks");
}

View File

@ -142,7 +142,7 @@ public interface NetworkManager extends NetworkService {
boolean destroyNetwork(long networkId, ReservationContext context);
Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String cidr, String vlanId, String networkDomain, Account owner) throws ConcurrentOperationException, InsufficientCapacityException;
Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled) throws ConcurrentOperationException, InsufficientCapacityException;
/**
* @throws InsufficientCapacityException
@ -179,4 +179,6 @@ public interface NetworkManager extends NetworkService {
boolean isServiceSupported(long networkId, Network.Service service);
Network getNetworkWithSecurityGroupEnabled(Long zoneId);
}

View File

@ -871,7 +871,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
related = id;
}
NetworkVO vo = new NetworkVO(id, config, offering.getId(), plan.getDataCenterId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, isShared, isDefault);
NetworkVO vo = new NetworkVO(id, config, offering.getId(), plan.getDataCenterId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, isShared, isDefault, predefined.isSecurityGroupEnabled());
configs.add(_networksDao.persist(vo, vo.getGuestType() != null));
}
@ -1502,7 +1502,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
txn.start();
Network network = createNetwork(networkOfferingId, name, displayText, isShared, isDefault, zoneId, gateway, cidr, vlanId, networkDomain, owner);
Network network = createNetwork(networkOfferingId, name, displayText, isShared, isDefault, zoneId, gateway, cidr, vlanId, networkDomain, owner, cmd.isSecurityGroupEnabled());
// Don't pass owner to create vlan when network offering is of type Direct - done to prevent accountVlanMap entry
// creation when vlan is mapped to network
@ -1521,7 +1521,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override @DB
public Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String cidr, String vlanId, String networkDomain, Account owner)
public Network createNetwork(long networkOfferingId, String name, String displayText, Boolean isShared, Boolean isDefault, Long zoneId, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled)
throws ConcurrentOperationException, InsufficientCapacityException {
Account ctxAccount = UserContext.current().getCaller();
Long userId = UserContext.current().getCallerUserId();
@ -1535,6 +1535,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
DataCenterDeployment plan = new DataCenterDeployment(zoneId, null, null, null);
NetworkVO userNetwork = new NetworkVO();
userNetwork.setNetworkDomain(networkDomain);
userNetwork.setSecurityGroupEnabled(isSecurityGroupEnabled);
// cidr should be set only when the user is admin
if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN) {
@ -2142,6 +2143,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
return networks.get(0);
}
@Override
public Network getNetworkWithSecurityGroupEnabled(Long zoneId) {
List<NetworkVO> networks = _networksDao.listByZoneSecurityGroup(zoneId);
if (networks == null || networks.isEmpty()) {
return null;
}
if (networks.size() > 1) {
s_logger.debug("There are multiple network with security group enabled? select one of them...");
}
return networks.get(0);
}
@Override
public PublicIpAddress getPublicIpAddress(long ipAddressId) {
@ -2205,7 +2219,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
// create new Virtual network for the user if it doesn't exist
if (createNetwork) {
List<? extends NetworkOffering> offerings = _configMgr.listNetworkOfferings(TrafficType.Guest, false);
network = createNetwork(offerings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", false, true, zoneId, null, null, null, null, owner);
network = createNetwork(offerings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", false, true, zoneId, null, null, null, null, owner, false);
if (network == null) {
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);

View File

@ -134,6 +134,9 @@ public class NetworkVO implements Network {
@Column(name="is_default")
boolean isDefault;
@Column(name="is_security_group_enabled")
boolean securityGroupEnabled = false;
public NetworkVO() {
}
@ -161,7 +164,7 @@ public class NetworkVO implements Network {
this.guestType = guestType;
}
public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related, String name, String displayText, Boolean isShared, boolean isDefault) {
public NetworkVO(long id, Network that, long offeringId, long dataCenterId, String guruName, long domainId, long accountId, long related, String name, String displayText, Boolean isShared, boolean isDefault, boolean isSecurityGroupEnabled) {
this(id, that.getTrafficType(), that.getGuestType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId, domainId, accountId, related, name, displayText, isShared, isDefault);
this.gateway = that.getGateway();
this.cidr = that.getCidr();
@ -170,6 +173,7 @@ public class NetworkVO implements Network {
this.guruName = guruName;
this.state = that.getState();
this.networkDomain = that.getNetworkDomain();
this.securityGroupEnabled = isSecurityGroupEnabled;
if (state == null) {
state = State.Allocated;
}
@ -381,6 +385,15 @@ public class NetworkVO implements Network {
public boolean isDefault() {
return isDefault;
}
@Override
public boolean isSecurityGroupEnabled() {
return securityGroupEnabled;
}
public void setSecurityGroupEnabled(boolean enabled) {
this.securityGroupEnabled = enabled;
}
public void setShared(boolean isShared) {
this.isShared = isShared;

View File

@ -58,4 +58,5 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long> {
int getActiveNicsIn(long networkId);
List<Long> findNetworksToGarbageCollect();
void clearCheckForGc(long networkId);
List<NetworkVO> listByZoneSecurityGroup(Long zoneId);
}

View File

@ -49,6 +49,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
final SearchBuilder<NetworkVO> RelatedConfigSearch;
final SearchBuilder<NetworkVO> AccountNetworkSearch;
final SearchBuilder<NetworkVO> ZoneBroadcastUriSearch;
final SearchBuilder<NetworkVO> ZoneSecurityGroupSearch;
NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class);
NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
@ -100,6 +101,11 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
ZoneBroadcastUriSearch.done();
ZoneSecurityGroupSearch = createSearchBuilder();
ZoneSecurityGroupSearch.and("dataCenterId", ZoneSecurityGroupSearch.entity().getDataCenterId(), Op.EQ);
ZoneSecurityGroupSearch.and("securityGroup", ZoneSecurityGroupSearch.entity().isSecurityGroupEnabled(), Op.EQ);
ZoneSecurityGroupSearch.done();
_tgMacAddress = _tgs.get("macAddress");
}
@ -230,6 +236,15 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
return search(sc, null);
}
@Override
public List<NetworkVO> listByZoneSecurityGroup(Long zoneId) {
SearchCriteria<NetworkVO> sc = ZoneSecurityGroupSearch.create();
if (zoneId != null)
sc.setParameters("dataCenterId", zoneId);
sc.setParameters("securityGroup", true);
return search(sc, null);
}
@Override
public void changeActiveNicsBy(long networkId, int count) {
_opDao.changeActiveNicsBy(networkId, count);

View File

@ -19,6 +19,7 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.network.IPAddressVO;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkProfile;
@ -70,7 +71,12 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
}
if (offering.getTrafficType() == TrafficType.Public) {
NetworkVO ntwk = new NetworkVO(offering.getTrafficType(), null, Mode.Static, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId(), State.Setup);
GuestIpType type = null;
if (network.isSecurityGroupEnabled()) {
type = GuestIpType.Direct;
}
NetworkVO ntwk = new NetworkVO(offering.getTrafficType(), type, Mode.Static, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId(), State.Setup);
return ntwk;
} else {
return null;
@ -83,7 +89,14 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null);
VlanType type = VlanType.VirtualNetwork;
Long networkId = null;
if (network.isSecurityGroupEnabled()) {
type = VlanType.DirectAttached;
networkId = network.getId();
}
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), type, networkId);
nic.setIp4Address(ip.getAddress().toString());
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());

View File

@ -849,7 +849,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
if (dc.getNetworkType() == NetworkType.Advanced) {
String cidr = network.getCidr();
dhcpRange = NetUtils.getDhcpRange(cidr);
if (cidr != null) {
dhcpRange = NetUtils.getDhcpRange(cidr);
}
}
if (router.getRole() == Role.DHCP_USERDATA) {

View File

@ -84,6 +84,7 @@ import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.StateListener;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
@ -108,6 +109,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Inject DomainDao _domainDao;
@Inject AgentManager _agentMgr;
@Inject VirtualMachineManager _itMgr;
@Inject UserVmManager _userVmMgr;
ScheduledExecutorService _executorPool;
ScheduledExecutorService _cleanupExecutor;
@ -115,8 +117,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
private final long _timeBetweenCleanups = 30; //seconds
boolean _enabled = false;
SecurityGroupListener _answerListener;
@ -300,7 +300,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
}
protected void handleVmStarted(VMInstanceVO vm) {
if (vm.getType() != VirtualMachine.Type.User || !_enabled)
if (vm.getType() != VirtualMachine.Type.User || !isVmSecurityGroupEnabled(vm.getId()))
return;
Set<Long> affectedVms = getAffectedVmsForVmStart(vm);
scheduleRulesetUpdateToHosts(affectedVms, true, null);
@ -308,9 +308,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@DB
public void scheduleRulesetUpdateToHosts(Set<Long> affectedVms, boolean updateSeqno, Long delayMs) {
if (!_enabled) {
return;
}
if (delayMs == null) {
delayMs = new Long(100l);
}
@ -413,7 +410,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
}
protected void handleVmStopped(VMInstanceVO vm) {
if (vm.getType() != VirtualMachine.Type.User || !_enabled)
if (vm.getType() != VirtualMachine.Type.User || !isVmSecurityGroupEnabled(vm.getId()))
return;
Set<Long> affectedVms = getAffectedVmsForVmStop(vm);
scheduleRulesetUpdateToHosts(affectedVms, true, null);
@ -450,10 +447,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
Integer endPortOrCode = null;
Long accountId = null;
if (!_enabled) {
return null;
}
//Verify input parameters
if (protocol == null) {
protocol = "all";
@ -653,11 +646,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
@DB
public boolean revokeSecurityGroupIngress(RevokeSecurityGroupIngressCmd cmd) {
if (!_enabled) {
return false;
}
//input validation
Account account = UserContext.current().getCaller();
Long domainId = cmd.getDomainId();
@ -741,9 +729,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
public SecurityGroupVO createSecurityGroup(CreateSecurityGroupCmd cmd) throws PermissionDeniedException, InvalidParameterValueException {
if (!_enabled) {
return null;
}
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
@ -802,9 +787,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@DB
@Override
public SecurityGroupVO createSecurityGroup(String name, String description, Long domainId, Long accountId, String accountName) {
if (!_enabled) {
return null;
}
final Transaction txn = Transaction.currentTxn();
AccountVO account = null;
txn.start();
@ -835,13 +817,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
/*register state listener, no matter security group is enabled or not*/
VirtualMachine.State.getStateMachine().registerListener(this);
String enabled =_configDao.getValue("direct.attach.security.groups.enabled");
if ("true".equalsIgnoreCase(enabled)) {
_enabled = true;
}
if (!_enabled) {
return false;
}
_answerListener = new SecurityGroupListener(this, _agentMgr, _workDao);
_agentMgr.registerForHostEvents(_answerListener, true, true, true);
@ -861,9 +836,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
public boolean start() {
if (!_enabled) {
return true;
}
_cleanupExecutor.scheduleAtFixedRate(new CleanupThread(), _timeBetweenCleanups, _timeBetweenCleanups, TimeUnit.SECONDS);
return true;
}
@ -876,9 +848,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
public SecurityGroupVO createDefaultSecurityGroup(Long accountId) {
if (!_enabled) {
return null;
}
SecurityGroupVO groupVO = _securityGroupDao.findByAccountAndName(accountId, SecurityGroupManager.DEFAULT_GROUP_NAME);
if (groupVO == null ) {
Account accVO = _accountDao.findById(accountId);
@ -947,7 +916,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
@DB
public boolean addInstanceToGroups(final Long userVmId, final List<Long> groups) {
if (!_enabled) {
if (!isVmSecurityGroupEnabled(userVmId)) {
return true;
}
if (groups != null && !groups.isEmpty()) {
@ -995,7 +964,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
@Override
@DB
public void removeInstanceFromGroups(Long userVmId) {
if (!_enabled) {
if (!isVmSecurityGroupEnabled(userVmId)) {
return;
}
final Transaction txn = Transaction.currentTxn();
@ -1018,10 +987,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
Long domainId = cmd.getDomainId();
Account account = UserContext.current().getCaller();
if (!_enabled) {
return true;
}
//Verify input parameters
Long accountId = null;
if ((account == null) || isAdmin(account.getType())) {
@ -1343,4 +1308,7 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
return true;
}
private boolean isVmSecurityGroupEnabled(Long vmId) {
return _userVmMgr.isVmSecurityGroupEnabled(vmId);
}
}

View File

@ -183,6 +183,8 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.network.IPAddressVO;
import com.cloud.network.Network;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
@ -320,6 +322,7 @@ public class ManagementServerImpl implements ManagementServer {
private final NetworkDao _networkDao;
private final StorageManager _storageMgr;
private final VirtualMachineManager _itMgr;
private final NetworkManager _networkMgr;
private final Adapters<UserAuthenticator> _userAuthenticators;
private final HostPodDao _hostPodDao;
@ -407,6 +410,7 @@ public class ManagementServerImpl implements ManagementServer {
_uploadMonitor = locator.getManager(UploadMonitor.class);
_sshKeyPairDao = locator.getDao(SSHKeyPairDao.class);
_itMgr = locator.getManager(VirtualMachineManager.class);
_networkMgr = locator.getManager(NetworkManager.class);
_userAuthenticators = locator.getAdapters(UserAuthenticator.class);
if (_userAuthenticators == null || !_userAuthenticators.isSet()) {
@ -4185,8 +4189,12 @@ public class ManagementServerImpl implements ManagementServer {
@Override
public Map<String, Object> listCapabilities(ListCapabilitiesCmd cmd) {
Map<String, Object> capabilities = new HashMap<String, Object>();
String securityGroupsEnabled = "false";
Network net = _networkMgr.getNetworkWithSecurityGroupEnabled(null);
if (net != null) {
securityGroupsEnabled = "true";
}
String securityGroupsEnabled = _configs.get(Config.DirectAttachSecurityGroupsEnabled.key());
String userPublicTemplateEnabled = _configs.get(Config.AllowPublicUserTemplates.key());
capabilities.put("securityGroupsEnabled", (securityGroupsEnabled == null || securityGroupsEnabled.equals("false") ? false : true));

View File

@ -88,4 +88,8 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>{
*/
List<UserVmVO> searchForUserVMs(Criteria c);
boolean isVmSecurityGroupEnabled(Long vmId);
}

View File

@ -2009,8 +2009,35 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
List<Long> sgs = cmd.getSecurityGroupIdList();
if (sgs != null && !sgs.isEmpty()) {
if (networkList == null || networkList.isEmpty()) {
Network networkWithSecurityGroup = _networkMgr.getNetworkWithSecurityGroupEnabled(dc.getId());
if (networkWithSecurityGroup == null) {
throw new InvalidParameterValueException("No network with security enabled");
}
networkList = new ArrayList<Long>();
networkList.add(networkWithSecurityGroup.getId());
} else {
if (networkList.size() > 1) {
throw new InvalidParameterValueException("Only support one network per VM if security group enabled");
}
Network net = _networkMgr.getNetwork(networkList.get(0).longValue());
if (!net.isSecurityGroupEnabled()) {
throw new InvalidParameterValueException("need to enable security group for network: " + net.getId());
}
}
}
if (networkList == null || networkList.isEmpty()) {
throw new InvalidParameterValueException("NetworkIds have to be specified");
Network networkWithSecurityGroup = _networkMgr.getNetworkWithSecurityGroupEnabled(dc.getId());
if (networkWithSecurityGroup != null) {
networkList = new ArrayList<Long>();
networkList.add(networkWithSecurityGroup.getId());
} else {
throw new InvalidParameterValueException("NetworkIds have to be specified");
}
}
List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
@ -2676,4 +2703,16 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return _vmDao.search(sc, searchFilter);
}
@Override
public boolean isVmSecurityGroupEnabled(Long vmId) {
List<NicVO> nics = _nicDao.listByVmId(vmId);
for (NicVO nic : nics) {
Network network = _networkDao.findById(nic.getNetworkId());
if (network != null && network.isSecurityGroupEnabled()) {
return true;
}
}
return false;
}
}

View File

@ -179,6 +179,7 @@ CREATE TABLE `cloud`.`networks` (
`is_default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if network is default',
`created` datetime NOT NULL COMMENT 'date created',
`removed` datetime COMMENT 'date removed if not null',
`is_security_group_enabled` smallint(1) NOT NULL COMMENT '1: enabled, 0: not',
PRIMARY KEY (`id`),
CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`),
CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`),

View File

@ -7,7 +7,7 @@ INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type,
VALUES (3, 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/systemvm.qcow2.bz2', 'ec463e677054f280f152fcc264255d2f', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM');
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, display_text, enable_password, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable)
VALUES (4, 'centos55-x86_64', 'CentOS 5.5(64-bit) no GUI (KVM)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', 'ed0e788280ff2912ea40f7f91ca7a249', 'CentOS 5.5(64-bit) no GUI (KVM)', 0, 'QCOW2', 112, 1, 1, 'KVM', 1);
VALUES (4, 'centos55-x86_64', 'CentOS 5.5(64-bit) no GUI (KVM)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', 'ed0e788280ff2912ea40f7f91ca7a249', 'CentOS 5.5(64-bit) no GUI (KVM)', 0, 'QCOW2', 112, 1, 1, 'KVM', 1);
INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type, extractable)
VALUES (7, 'centos53-x64', 'CentOS 5.3(64-bit) no GUI (vSphere)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/CentOS5.3-x86_64.ova', 'f6f881b7f2292948d8494db837fe0f47', 0, 'CentOS 5.3(64-bit) no GUI (vSphere)', 'OVA', 12, 1, 1, 'VMware', 1);