mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-24: mipn feature for basiczone
Signed-off-by: Abhinandan Prateek <aprateek@apache.org>
This commit is contained in:
parent
630e75596e
commit
a49261c3b1
@ -18,6 +18,7 @@ package com.cloud.agent.api;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
@ -80,6 +81,7 @@ public class SecurityGroupRulesCmd extends Command {
|
||||
Long msId;
|
||||
IpPortAndProto [] ingressRuleSet;
|
||||
IpPortAndProto [] egressRuleSet;
|
||||
private List<String> secIps;
|
||||
|
||||
public SecurityGroupRulesCmd() {
|
||||
super();
|
||||
@ -103,6 +105,23 @@ public class SecurityGroupRulesCmd extends Command {
|
||||
}
|
||||
|
||||
|
||||
public SecurityGroupRulesCmd(String guestIp, String guestMac, String vmName, Long vmId, String signature, Long seqNum, IpPortAndProto[] ingressRuleSet, IpPortAndProto[] egressRuleSet, List<String> secIps) {
|
||||
super();
|
||||
this.guestIp = guestIp;
|
||||
this.vmName = vmName;
|
||||
this.ingressRuleSet = ingressRuleSet;
|
||||
this.egressRuleSet = egressRuleSet;
|
||||
this.guestMac = guestMac;
|
||||
this.signature = signature;
|
||||
this.seqNum = seqNum;
|
||||
this.vmId = vmId;
|
||||
if (signature == null) {
|
||||
String stringified = stringifyRules();
|
||||
this.signature = DigestUtils.md5Hex(stringified);
|
||||
}
|
||||
this.secIps = secIps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return true;
|
||||
@ -131,6 +150,10 @@ public class SecurityGroupRulesCmd extends Command {
|
||||
return guestIp;
|
||||
}
|
||||
|
||||
public List<String> getSecIps() {
|
||||
return secIps;
|
||||
}
|
||||
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
@ -165,6 +188,20 @@ public class SecurityGroupRulesCmd extends Command {
|
||||
}
|
||||
|
||||
|
||||
public String getSecIpsString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> ips = getSecIps();
|
||||
if (ips == null) {
|
||||
return "0:";
|
||||
} else {
|
||||
for (String ip : ips) {
|
||||
sb.append(ip).append(":");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public String stringifyCompressedRules() {
|
||||
StringBuilder ruleBuilder = new StringBuilder();
|
||||
for (SecurityGroupRulesCmd.IpPortAndProto ipPandP : getIngressRuleSet()) {
|
||||
|
||||
@ -16,12 +16,15 @@
|
||||
// under the License.
|
||||
package com.cloud.agent.api.to;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NicTO extends NetworkTO {
|
||||
int deviceId;
|
||||
Integer networkRateMbps;
|
||||
Integer networkRateMulticastMbps;
|
||||
boolean defaultNic;
|
||||
String uuid;
|
||||
List <String> nicSecIps;
|
||||
|
||||
public NicTO() {
|
||||
super();
|
||||
@ -69,4 +72,12 @@ public class NicTO extends NetworkTO {
|
||||
public String toString() {
|
||||
return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString();
|
||||
}
|
||||
|
||||
public void setNicSecIps(List<String> secIps) {
|
||||
this.nicSecIps = secIps;
|
||||
}
|
||||
|
||||
public List<String> getNicSecIps() {
|
||||
return nicSecIps;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupC
|
||||
import org.apache.cloudstack.api.command.user.securitygroup.DeleteSecurityGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd;
|
||||
import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupIngressCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.AddIpToVmNicCmd;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
@ -45,5 +46,6 @@ public interface SecurityGroupService {
|
||||
public List<? extends SecurityRule> authorizeSecurityGroupIngress(AuthorizeSecurityGroupIngressCmd cmd);
|
||||
|
||||
public List<? extends SecurityRule> authorizeSecurityGroupEgress(AuthorizeSecurityGroupEgressCmd cmd);
|
||||
|
||||
public boolean securityGroupRulesForVmSecIp(Long nicId, Long networkId,
|
||||
String secondaryIp, boolean ruleAction);
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ import org.apache.cloudstack.api.response.NicResponse;
|
||||
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
||||
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
@ -83,6 +85,9 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd {
|
||||
|
||||
public Long getNetworkId() {
|
||||
Nic nic = _entityMgr.findById(Nic.class, nicId);
|
||||
if (nic == null) {
|
||||
throw new InvalidParameterValueException("Can't find network id for specified nic");
|
||||
}
|
||||
Long networkId = nic.getNetworkId();
|
||||
return networkId;
|
||||
}
|
||||
@ -98,6 +103,13 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkType getNetworkType() {
|
||||
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
|
||||
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
|
||||
return dc.getNetworkType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
@ -134,7 +146,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd {
|
||||
|
||||
UserContext.current().setEventDetails("Nic Id: " + getNicId() );
|
||||
String ip;
|
||||
String SecondaryIp = null;
|
||||
String secondaryIp = null;
|
||||
if ((ip = getIpaddress()) != null) {
|
||||
if (!NetUtils.isValidIp(ip)) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip);
|
||||
@ -142,13 +154,22 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd {
|
||||
}
|
||||
|
||||
try {
|
||||
SecondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress());
|
||||
secondaryIp = _networkService.allocateSecondaryGuestIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNicId(), getNetworkId(), getIpaddress());
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
throw new InvalidParameterValueException("Allocating guest ip for nic failed");
|
||||
}
|
||||
|
||||
if (SecondaryIp != null) {
|
||||
s_logger.info("Associated ip address to NIC : " + SecondaryIp);
|
||||
if (secondaryIp != null) {
|
||||
if (getNetworkType() == NetworkType.Basic) {
|
||||
// add security group rules for the secondary ip addresses
|
||||
boolean success = false;
|
||||
success = _securityGroupService.securityGroupRulesForVmSecIp(getNicId(), getNetworkId(), secondaryIp, (boolean) true);
|
||||
if (success == false) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.info("Associated ip address to NIC : " + secondaryIp);
|
||||
NicSecondaryIpResponse response = new NicSecondaryIpResponse();
|
||||
response = _responseGenerator.createSecondaryIPToNicResponse(ip, getNicId(), getNetworkId());
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -27,10 +27,15 @@ import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
|
||||
@APICommand(name = "removeIpFromNic", description="Assigns secondary IP to NIC.", responseObject=SuccessResponse.class)
|
||||
public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
|
||||
@ -43,7 +48,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, required = true, entityType = NicSecondaryIpResponse.class,
|
||||
description="the ID of the secondary ip address to nic")
|
||||
private long id;
|
||||
private Long id;
|
||||
|
||||
// unexposed parameter needed for events logging
|
||||
@Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.UUID, expose=false)
|
||||
@ -57,7 +62,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
|
||||
return "nic_secondary_ips";
|
||||
}
|
||||
|
||||
public long getIpAddressId() {
|
||||
public Long getIpAddressId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -80,6 +85,11 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
|
||||
return EventTypes.EVENT_NET_IP_ASSIGN;
|
||||
}
|
||||
|
||||
public NicSecondaryIp getIpEntry() {
|
||||
NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
|
||||
return nicSecIp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return ("Disassociating ip address with id=" + id);
|
||||
@ -98,9 +108,43 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
|
||||
return "addressinfo";
|
||||
}
|
||||
|
||||
public Long getNetworkId() {
|
||||
NicSecondaryIp nicSecIp = _entityMgr.findById(NicSecondaryIp.class, getIpAddressId());
|
||||
if (nicSecIp != null) {
|
||||
Long networkId = nicSecIp.getNetworkId();
|
||||
return networkId;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkType getNetworkType() {
|
||||
Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
|
||||
if (ntwk != null) {
|
||||
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
|
||||
return dc.getNetworkType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws InvalidParameterValueException {
|
||||
UserContext.current().setEventDetails("Ip Id: " + getIpAddressId());
|
||||
NicSecondaryIp nicSecIp = getIpEntry();
|
||||
|
||||
if (nicSecIp == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid IP id is passed");
|
||||
}
|
||||
|
||||
if (getNetworkType() == NetworkType.Basic) {
|
||||
//remove the security group rules for this secondary ip
|
||||
boolean success = false;
|
||||
success = _securityGroupService.securityGroupRulesForVmSecIp(nicSecIp.getNicId(), nicSecIp.getNetworkId(),nicSecIp.getIp4Address(), false);
|
||||
if (success == false) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set security group rules for the secondary ip");
|
||||
}
|
||||
}
|
||||
|
||||
boolean result = _networkService.releaseSecondaryIpFromNic(getIpAddressId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
|
||||
@ -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 com.cloud.agent.api;
|
||||
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class NetworkRulesVmSecondaryIpCommand extends Command {
|
||||
|
||||
private String vmName;
|
||||
private VirtualMachine.Type type;
|
||||
private String vmSecIp;
|
||||
private String vmMac;
|
||||
private String action;
|
||||
|
||||
public NetworkRulesVmSecondaryIpCommand(String vmName, VirtualMachine.Type type) {
|
||||
this.vmName = vmName;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public NetworkRulesVmSecondaryIpCommand(String vmName, String vmMac,
|
||||
String secondaryIp, boolean action) {
|
||||
this.vmName = vmName;
|
||||
this.vmMac = vmMac;
|
||||
this.vmSecIp = secondaryIp;
|
||||
if (action) {
|
||||
this.action = "-A";
|
||||
} else {
|
||||
this.action = "-D";
|
||||
}
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public VirtualMachine.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getVmSecIp() {
|
||||
return vmSecIp;
|
||||
}
|
||||
|
||||
public String getVmMac() {
|
||||
return vmMac;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -118,6 +118,7 @@ import com.cloud.agent.api.ModifySshKeysCommand;
|
||||
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
||||
import com.cloud.agent.api.ModifyStoragePoolCommand;
|
||||
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
|
||||
import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
|
||||
import com.cloud.agent.api.PingCommand;
|
||||
import com.cloud.agent.api.PingRoutingCommand;
|
||||
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
|
||||
@ -597,6 +598,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return execute((DeleteVMSnapshotCommand)cmd);
|
||||
} else if (clazz == RevertToVMSnapshotCommand.class) {
|
||||
return execute((RevertToVMSnapshotCommand)cmd);
|
||||
} else if (clazz == NetworkRulesVmSecondaryIpCommand.class) {
|
||||
return execute((NetworkRulesVmSecondaryIpCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -1468,7 +1471,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
for (NicTO nic : nics) {
|
||||
if ( nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null
|
||||
&& nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) {
|
||||
result = callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", Long.toString(vmSpec.getId()));
|
||||
List<String> nicSecIps = nic.getNicSecIps();
|
||||
String secIpsStr;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (nicSecIps != null) {
|
||||
for (String ip : nicSecIps) {
|
||||
sb.append(ip).append(":");
|
||||
}
|
||||
secIpsStr = sb.toString();
|
||||
} else {
|
||||
secIpsStr = "0:";
|
||||
}
|
||||
result = callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", Long.toString(vmSpec.getId()), "secIps", secIpsStr);
|
||||
|
||||
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
|
||||
s_logger.warn("Failed to program default network rules for " + vmName+" on nic with ip:"+nic.getIp()+" mac:"+nic.getMac());
|
||||
@ -5454,7 +5468,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
"signature", cmd.getSignature(),
|
||||
"seqno", Long.toString(cmd.getSeqNum()),
|
||||
"deflated", "true",
|
||||
"rules", cmd.compressStringifiedRules());
|
||||
"rules", cmd.compressStringifiedRules(),
|
||||
"secIps", cmd.getSecIpsString());
|
||||
|
||||
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
|
||||
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
|
||||
@ -7506,6 +7521,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return new Answer(cmd, success, "");
|
||||
}
|
||||
|
||||
private Answer execute(NetworkRulesVmSecondaryIpCommand cmd) {
|
||||
boolean success = true;
|
||||
Connection conn = getConnection();
|
||||
|
||||
String result = callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action",
|
||||
cmd.getAction());
|
||||
if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) {
|
||||
success = false;
|
||||
}
|
||||
|
||||
return new Answer(cmd, success, "");
|
||||
}
|
||||
|
||||
protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
String callResult;
|
||||
|
||||
@ -610,6 +610,7 @@ def destroy_network_rules_for_vm(session, args):
|
||||
util.SMlog("Ignoring failure to delete egress chain " + vmchain_egress)
|
||||
|
||||
remove_rule_log_for_vm(vm_name)
|
||||
remove_secip_log_for_vm(vm_name)
|
||||
|
||||
if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-', 'l-'] ]:
|
||||
return 'true'
|
||||
@ -749,6 +750,43 @@ def default_arp_antispoof(vm_chain, vifs, vm_ip, vm_mac):
|
||||
|
||||
return 'true'
|
||||
|
||||
|
||||
@echo
|
||||
def network_rules_vmSecondaryIp(session, args):
|
||||
vm_name = args.pop('vmName')
|
||||
vm_mac = args.pop('vmMac')
|
||||
ip_secondary = args.pop('vmSecIp')
|
||||
action = args.pop('action')
|
||||
util.SMlog("vmMac = "+ vm_mac)
|
||||
util.SMlog("vmName = "+ vm_name)
|
||||
#action = "-A"
|
||||
util.SMlog("action = "+ action)
|
||||
try:
|
||||
vm = session.xenapi.VM.get_by_name_label(vm_name)
|
||||
if len(vm) != 1:
|
||||
return 'false'
|
||||
vm_rec = session.xenapi.VM.get_record(vm[0])
|
||||
vm_vifs = vm_rec.get('VIFs')
|
||||
vifnums = [session.xenapi.VIF.get_record(vif).get('device') for vif in vm_vifs]
|
||||
domid = vm_rec.get('domid')
|
||||
except:
|
||||
util.SMlog("### Failed to get domid or vif list for vm ##" + vm_name)
|
||||
return 'false'
|
||||
|
||||
if domid == '-1':
|
||||
util.SMlog("### Failed to get domid for vm (-1): " + vm_name)
|
||||
return 'false'
|
||||
|
||||
vifs = ["vif" + domid + "." + v for v in vifnums]
|
||||
#vm_name = '-'.join(vm_name.split('-')[:-1])
|
||||
vmchain = chain_name(vm_name)
|
||||
add_to_ipset(vmchain, [ip_secondary], action)
|
||||
|
||||
#add arptables rules for the secondary ip
|
||||
arp_rules_vmip(vmchain, vifs, [ip_secondary], vm_mac, action)
|
||||
|
||||
return 'true'
|
||||
|
||||
@echo
|
||||
def default_network_rules_systemvm(session, args):
|
||||
vm_name = args.pop('vmName')
|
||||
@ -798,6 +836,55 @@ def default_network_rules_systemvm(session, args):
|
||||
util.SMlog("Failed to log default network rules for systemvm, ignoring")
|
||||
return 'true'
|
||||
|
||||
@echo
|
||||
def create_ipset_forvm (ipsetname):
|
||||
result = True
|
||||
try:
|
||||
util.SMlog("Creating ipset chain .... " + ipsetname)
|
||||
util.pread2(['ipset', '-F', ipsetname])
|
||||
util.pread2(['ipset', '-X', ipsetname])
|
||||
util.pread2(['ipset', '-N', ipsetname, 'iphash'])
|
||||
except:
|
||||
util.SMlog("ipset chain not exists creating.... " + ipsetname)
|
||||
util.pread2(['ipset', '-N', ipsetname, 'iphash'])
|
||||
|
||||
return result
|
||||
|
||||
@echo
|
||||
def add_to_ipset(ipsetname, ips, action):
|
||||
result = True
|
||||
for ip in ips:
|
||||
try:
|
||||
util.SMlog("vm ip " + ip)
|
||||
util.pread2(['ipset', action, ipsetname, ip])
|
||||
except:
|
||||
util.SMlog("vm ip alreday in ip set" + ip)
|
||||
continue
|
||||
|
||||
return result
|
||||
|
||||
@echo
|
||||
def arp_rules_vmip (vm_chain, vifs, ips, vm_mac, action):
|
||||
try:
|
||||
if action == "-A":
|
||||
action = "-I"
|
||||
for vif in vifs:
|
||||
for vm_ip in ips:
|
||||
#accept any arp requests to this vm as long as the request is for this vm's ip
|
||||
util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Request', '--destination-ip', vm_ip, '-j', 'ACCEPT'])
|
||||
#accept any arp replies to this vm as long as the mac and ip matches
|
||||
util.pread2(['arptables', action, vm_chain, '-o', vif, '--opcode', 'Reply', '--destination-mac', vm_mac, '--destination-ip', vm_ip, '-j', 'ACCEPT'])
|
||||
#accept arp replies into the bridge as long as the source mac and ips match the vm
|
||||
util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Reply', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'ACCEPT'])
|
||||
#accept any arp requests from this vm. In the future this can be restricted to deny attacks on hosts
|
||||
#also important to restrict source ip and src mac in these requests as they can be used to update arp tables on destination
|
||||
util.pread2(['arptables', action, vm_chain, '-i', vif, '--opcode', 'Request', '--source-mac', vm_mac, '--source-ip', vm_ip, '-j', 'RETURN'])
|
||||
except:
|
||||
util.SMlog("Failed to program arptables rules for ip")
|
||||
return 'false'
|
||||
|
||||
return 'true'
|
||||
|
||||
|
||||
@echo
|
||||
def default_network_rules(session, args):
|
||||
@ -805,6 +892,8 @@ def default_network_rules(session, args):
|
||||
vm_ip = args.pop('vmIP')
|
||||
vm_id = args.pop('vmID')
|
||||
vm_mac = args.pop('vmMAC')
|
||||
sec_ips = args.pop("secIps")
|
||||
action = "-A"
|
||||
|
||||
try:
|
||||
vm = session.xenapi.VM.get_by_name_label(vm_name)
|
||||
@ -854,6 +943,32 @@ def default_network_rules(session, args):
|
||||
except:
|
||||
util.pread2(['iptables', '-F', vmchain_default])
|
||||
|
||||
vmipset = vm_name
|
||||
#create ipset and add vm ips to that ip set
|
||||
if create_ipset_forvm(vmipset) == False:
|
||||
util.SMlog(" failed to create ipset for rule " + str(tokens))
|
||||
return 'false'
|
||||
|
||||
#add primary nic ip to ipset
|
||||
if add_to_ipset(vmipset, [vm_ip], action ) == False:
|
||||
util.SMlog(" failed to add vm " + vm_ip + " ip to set ")
|
||||
return 'false'
|
||||
|
||||
#add secodnary nic ips to ipset
|
||||
secIpSet = "1"
|
||||
ips = sec_ips.split(':')
|
||||
ips.pop()
|
||||
if ips[0] == "0":
|
||||
secIpSet = "0";
|
||||
|
||||
if secIpSet == "1":
|
||||
util.SMlog("Adding ipset for secondary ips")
|
||||
add_to_ipset(vmipset, ips, action)
|
||||
if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False:
|
||||
util.SMlog("Failed to log default network rules, ignoring")
|
||||
|
||||
keyword = '--' + get_ipset_keyword()
|
||||
|
||||
try:
|
||||
for v in vifs:
|
||||
util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default])
|
||||
@ -861,16 +976,22 @@ def default_network_rules(session, args):
|
||||
|
||||
#don't let vm spoof its ip address
|
||||
for v in vifs:
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', '!', vm_ip, '-j', 'DROP'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '--destination', '!', vm_ip, '-j', 'DROP'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', vmchain_egress])
|
||||
#util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip,'-p', 'udp', '--dport', '53', '-j', 'RETURN'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-p', 'udp', '--dport', '53', '-j', 'RETURN'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', '!', keyword, vmipset, 'src', '-j', 'DROP'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-m', 'set', '!', keyword, vmipset, 'dst', '-j', 'DROP'])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-m', 'set', keyword, vmipset, 'src', '-j', vmchain_egress])
|
||||
util.pread2(['iptables', '-A', vmchain_default, '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain])
|
||||
except:
|
||||
util.SMlog("Failed to program default rules for vm " + vm_name)
|
||||
return 'false'
|
||||
|
||||
default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac)
|
||||
#add default arp rules for secondary ips;
|
||||
if secIpSet == "1":
|
||||
util.SMlog("Adding arp rules for sec ip")
|
||||
arp_rules_vmip(vmchain, vifs, ips, vm_mac, action)
|
||||
|
||||
default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac)
|
||||
|
||||
if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domid, '_initial_', '-1', vm_mac) == False:
|
||||
@ -994,10 +1115,45 @@ def network_rules_for_rebooted_vm(session, vmName):
|
||||
destroy_arptables_rules(vmchain)
|
||||
[vm_ip, vm_mac] = get_vm_mac_ip_from_log(vmchain)
|
||||
default_arp_antispoof(vmchain, vifs, vm_ip, vm_mac)
|
||||
|
||||
#check wether the vm has secondary ips
|
||||
if is_secondary_ips_set(vm_name) == True:
|
||||
vmips = get_vm_sec_ips(vm_name)
|
||||
#add arp rules for the secondaryp ip
|
||||
for ip in vmips:
|
||||
arp_rules_vmip(vmchain, vifs, [ip], vm_mac, "-A")
|
||||
|
||||
|
||||
default_ebtables_antispoof_rules(vmchain, vifs, vm_ip, vm_mac)
|
||||
rewrite_rule_log_for_vm(vm_name, curr_domid)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@echo
|
||||
def get_vm_sec_ips(vm_name):
|
||||
logfilename = "/var/run/cloud/" + vm_name +".ip"
|
||||
|
||||
lines = (line.rstrip() for line in open(logfilename))
|
||||
for line in lines:
|
||||
try:
|
||||
[_vmName,_vmIP,_vmID] = line.split(',')
|
||||
break
|
||||
except ValueError,v:
|
||||
[_vmName,_vmIP,_vmID] = line.split(',')
|
||||
|
||||
_vmIPS = _vmIP.split(":")[:-1]
|
||||
return _vmIPS
|
||||
|
||||
@echo
|
||||
def is_secondary_ips_set(vm_name):
|
||||
logfilename = "/var/run/cloud/" + vm_name +".ip"
|
||||
if not os.path.exists(logfilename):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@echo
|
||||
def rewrite_rule_log_for_vm(vm_name, new_domid):
|
||||
logfilename = "/var/run/cloud/" + vm_name +".log"
|
||||
if not os.path.exists(logfilename):
|
||||
@ -1194,6 +1350,39 @@ def check_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno):
|
||||
|
||||
return [reprogramDefault, reprogramChain, rewriteLog]
|
||||
|
||||
@echo
|
||||
def write_secip_log_for_vm (vmName, secIps, vmId):
|
||||
vm_name = vmName
|
||||
logfilename = "/var/run/cloud/"+vm_name+".ip"
|
||||
util.SMlog("Writing log to " + logfilename)
|
||||
logf = open(logfilename, 'w')
|
||||
output = ','.join([vmName, secIps, vmId])
|
||||
result = True
|
||||
|
||||
try:
|
||||
logf.write(output)
|
||||
logf.write('\n')
|
||||
except:
|
||||
util.SMlog("Failed to write to rule log file " + logfilename)
|
||||
result = False
|
||||
|
||||
logf.close()
|
||||
|
||||
return result
|
||||
|
||||
@echo
|
||||
def remove_secip_log_for_vm(vmName):
|
||||
vm_name = vmName
|
||||
logfilename = "/var/run/cloud/"+vm_name+".ip"
|
||||
|
||||
result = True
|
||||
try:
|
||||
os.remove(logfilename)
|
||||
except:
|
||||
util.SMlog("Failed to delete rule log file " + logfilename)
|
||||
result = False
|
||||
|
||||
return result
|
||||
|
||||
@echo
|
||||
def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno, vmMac='ff:ff:ff:ff:ff:ff'):
|
||||
@ -1289,6 +1478,7 @@ def network_rules(session, args):
|
||||
vm_mac = args.get('vmMAC')
|
||||
signature = args.pop('signature')
|
||||
seqno = args.pop('seqno')
|
||||
sec_ips = args.pop("secIps")
|
||||
deflated = 'false'
|
||||
if 'deflated' in args:
|
||||
deflated = args.pop('deflated')
|
||||
@ -1469,6 +1659,7 @@ if __name__ == "__main__":
|
||||
"can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules,
|
||||
"destroy_network_rules_for_vm":destroy_network_rules_for_vm,
|
||||
"default_network_rules_systemvm":default_network_rules_systemvm,
|
||||
"network_rules_vmSecondaryIp":network_rules_vmSecondaryIp,
|
||||
"get_rule_logs_for_vms":get_rule_logs_for_vms,
|
||||
"setLinkLocalIP":setLinkLocalIP,
|
||||
"cleanup_rules":cleanup_rules,
|
||||
|
||||
@ -34,6 +34,7 @@ import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
|
||||
@ -41,7 +42,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
@Inject VMTemplateDetailsDao _templateDetailsDao;
|
||||
@Inject NicDao _nicDao;
|
||||
@Inject VMInstanceDao _virtualMachineDao;
|
||||
|
||||
@Inject NicSecondaryIpDao _nicSecIpDao;
|
||||
|
||||
protected HypervisorGuruBase() {
|
||||
super();
|
||||
}
|
||||
@ -68,6 +70,14 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
|
||||
// Workaround to make sure the TO has the UUID we need for Niciri integration
|
||||
NicVO nicVO = _nicDao.findById(profile.getId());
|
||||
to.setUuid(nicVO.getUuid());
|
||||
//check whether the this nic has secondary ip addresses set
|
||||
//set nic secondary ip address in NicTO which are used for security group
|
||||
// configuration. Use full when vm stop/start
|
||||
List <String> secIps = null;
|
||||
if (nicVO.getSecondaryIp()) {
|
||||
secIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nicVO.getId());
|
||||
}
|
||||
to.setNicSecIps(secIps);
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,8 @@ import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
@ -339,8 +341,9 @@ public interface NetworkManager {
|
||||
public String allocateGuestIP(Account ipOwner, boolean isSystem, long zoneId, Long networkId, String requestedIp)
|
||||
throws InsufficientAddressCapacityException;
|
||||
|
||||
boolean removeVmSecondaryIps(long vmId);
|
||||
|
||||
List<? extends Nic> listVmNics(Long vmId, Long nicId);
|
||||
String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, Pod pod, Account caller, String requestedIp) throws InsufficientAddressCapacityException;
|
||||
boolean removeVmSecondaryIpsOfNic(long nicId);
|
||||
|
||||
}
|
||||
|
||||
@ -1765,12 +1765,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
_nicDao.remove(nic.getId());
|
||||
s_logger.debug("Removed nic id=" + nic.getId());
|
||||
//remove the secondary ip addresses corresponding to to this nic
|
||||
List<NicSecondaryIpVO> secondaryIps = _nicSecondaryIpDao.listByNicId(nic.getId());
|
||||
if (secondaryIps != null) {
|
||||
for (NicSecondaryIpVO ip : secondaryIps) {
|
||||
_nicSecondaryIpDao.remove(ip.getId());
|
||||
}
|
||||
s_logger.debug("Removed nic " + nic.getId() + " secondary ip addreses");
|
||||
if (!removeVmSecondaryIpsOfNic(nic.getId())) {
|
||||
s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2835,7 +2831,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
|
||||
_accountMgr.checkAccess(caller, null, false, network);
|
||||
|
||||
//return acquireGuestIpAddress(network, requestedIp);
|
||||
ipaddr = acquireGuestIpAddress(network, requestedIp);
|
||||
return ipaddr;
|
||||
}
|
||||
@ -3654,11 +3649,11 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
return nic.getSecondaryIp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVmSecondaryIps(long vmId) {
|
||||
@Override
|
||||
public boolean removeVmSecondaryIpsOfNic(long nicId) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
List <NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByVmId(vmId);
|
||||
List <NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
|
||||
if (ipList != null) {
|
||||
for (NicSecondaryIpVO ip: ipList) {
|
||||
_nicSecondaryIpDao.remove(ip.getId());
|
||||
@ -3669,4 +3664,16 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc, Pod pod,Account owner,
|
||||
String requestedIp) throws InsufficientAddressCapacityException {
|
||||
PublicIp ip = assignPublicIpAddress(dc.getId(), null, owner, VlanType.DirectAttached, networkId, requestedIp, false);
|
||||
if (ip == null) {
|
||||
s_logger.debug("There is no free public ip address");
|
||||
return null;
|
||||
}
|
||||
Ip ipAddr = ip.getAddress();
|
||||
return ipAddr.addr();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -742,7 +742,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
||||
|
||||
@Override
|
||||
public Nic getNicInNetwork(long vmId, long networkId) {
|
||||
return _nicDao.findByInstanceIdAndNetworkId(networkId, vmId);
|
||||
return _nicDao.findByInstanceIdAndNetworkIdIncludingRemoved(networkId, vmId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -517,8 +517,45 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
throw new InvalidParameterValueException("Allocating guest ip for nic failed");
|
||||
}
|
||||
} else if (dc.getNetworkType() == NetworkType.Basic) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long callerUserId = UserContext.current().getCallerUserId();
|
||||
_accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
|
||||
//handle the basic networks here
|
||||
VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId());
|
||||
if (vm == null) {
|
||||
throw new InvalidParameterValueException("There is no vm with the nic");
|
||||
}
|
||||
VMInstanceVO vmi = (VMInstanceVO)vm;
|
||||
Long podId = vmi.getPodIdToDeployIn();
|
||||
if (podId == null) {
|
||||
throw new InvalidParameterValueException("vm pod id is null");
|
||||
}
|
||||
Pod pod = _hostPodDao.findById(podId);
|
||||
if (pod == null) {
|
||||
throw new InvalidParameterValueException("vm pod is null");
|
||||
}
|
||||
|
||||
try {
|
||||
ipaddr = _networkMgr.allocatePublicIpForGuestNic(networkId, dc, pod, caller, requestedIp);
|
||||
if (ipaddr == null) {
|
||||
throw new InvalidParameterValueException("Allocating ip to guest nic " + nicId + " failed");
|
||||
}
|
||||
} catch (InsufficientAddressCapacityException e) {
|
||||
s_logger.error("Allocating ip to guest nic " + nicId + " failed");
|
||||
return null;
|
||||
}
|
||||
} else if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && zone.getNetworkType() == NetworkType.Advanced) {
|
||||
// if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork'
|
||||
Account caller = UserContext.current().getCaller();
|
||||
long callerUserId = UserContext.current().getCallerUserId();
|
||||
_accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId());
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("AddIpToVMNic is not supported in this network...");
|
||||
s_logger.error("AddIpToVMNic is not supported in this network...");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ipaddr != null) {
|
||||
@ -549,18 +586,18 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
boolean success = false;
|
||||
|
||||
// Verify input parameters
|
||||
NicSecondaryIpVO ipVO= _nicSecondaryIpDao.findById(ipAddressId);
|
||||
if (ipVO == null) {
|
||||
NicSecondaryIpVO secIpVO= _nicSecondaryIpDao.findById(ipAddressId);
|
||||
if (secIpVO == null) {
|
||||
throw new InvalidParameterValueException("Unable to find ip address by id");
|
||||
}
|
||||
|
||||
Network network = _networksDao.findById(ipVO.getNetworkId());
|
||||
Network network = _networksDao.findById(secIpVO.getNetworkId());
|
||||
|
||||
// verify permissions
|
||||
_accountMgr.checkAccess(caller, null, true, network);
|
||||
|
||||
Long nicId = ipVO.getNicId();
|
||||
s_logger.debug("ip id and nic id" + ipAddressId + "..." + nicId);
|
||||
Long nicId = secIpVO.getNicId();
|
||||
s_logger.debug("ip id and nic id " + ipAddressId + "..." + nicId);
|
||||
//check is this the last secondary ip for NIC
|
||||
List<NicSecondaryIpVO> ipList = _nicSecondaryIpDao.listByNicId(nicId);
|
||||
boolean lastIp = false;
|
||||
@ -568,20 +605,41 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
// this is the last secondary ip to nic
|
||||
lastIp = true;
|
||||
}
|
||||
//check PF or static NAT is configured on this ip address
|
||||
String secondaryIp = ipVO.getIp4Address();
|
||||
List<PortForwardingRuleVO> pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp);
|
||||
if (pfRuleList.size() != 0) {
|
||||
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
|
||||
throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
|
||||
|
||||
DataCenter dc = _dcDao.findById(network.getDataCenterId());
|
||||
if (dc == null) {
|
||||
throw new InvalidParameterValueException("Invalid zone Id is given");
|
||||
}
|
||||
//check if the secondary ip associated with any static nat rule
|
||||
IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp);
|
||||
if (publicIpVO != null) {
|
||||
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
|
||||
throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
|
||||
|
||||
s_logger.debug("Calling the ip allocation ...");
|
||||
if (dc.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Isolated) {
|
||||
//check PF or static NAT is configured on this ip address
|
||||
String secondaryIp = secIpVO.getIp4Address();
|
||||
List<PortForwardingRuleVO> pfRuleList = _portForwardingDao.listByDestIpAddr(secondaryIp);
|
||||
if (pfRuleList.size() != 0) {
|
||||
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the port forwarding rule");
|
||||
throw new InvalidParameterValueException("Can't remove the secondary ip " + secondaryIp + " is associate with the port forwarding rule");
|
||||
}
|
||||
//check if the secondary ip associated with any static nat rule
|
||||
IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp);
|
||||
if (publicIpVO != null) {
|
||||
s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
|
||||
throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
|
||||
}
|
||||
} else if (dc.getNetworkType() == NetworkType.Basic) {
|
||||
IPAddressVO ip = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secIpVO.getIp4Address());
|
||||
if (ip != null) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
_networkMgr.markIpAsUnavailable(ip.getId());
|
||||
_ipAddressDao.unassignIpAddress(ip.getId());
|
||||
txn.commit();
|
||||
}
|
||||
} else if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && dc.getNetworkType() == NetworkType.Advanced) {
|
||||
throw new InvalidParameterValueException("Not supported for this network now");
|
||||
}
|
||||
success = removeNicSecondaryIP(ipVO, lastIp);
|
||||
|
||||
success = removeNicSecondaryIP(secIpVO, lastIp);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@ -66,4 +66,6 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
|
||||
IPAddressVO findByVmIp(String vmIp);
|
||||
|
||||
IPAddressVO findByAssociatedVmIdAndVmIp(long vmId, String vmIp);
|
||||
|
||||
IPAddressVO findByIpAndNetworkId(long networkId, String ipAddress);
|
||||
}
|
||||
|
||||
@ -184,6 +184,14 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPAddressVO findByIpAndNetworkId(long networkId, String ipAddress) {
|
||||
SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("network", networkId);
|
||||
sc.setParameters("ipAddress", ipAddress);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPAddressVO findByIpAndDcId(long dcId, String ipAddress) {
|
||||
SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package com.cloud.network.guru;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -54,7 +56,9 @@ import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.vm.Nic.ReservationStrategy;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
@ -79,7 +83,9 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
|
||||
UserIpv6AddressDao _ipv6Dao;
|
||||
@Inject
|
||||
Ipv6AddressManager _ipv6Mgr;
|
||||
|
||||
@Inject
|
||||
NicSecondaryIpDao _nicSecondaryIpDao;
|
||||
|
||||
private static final TrafficType[] _trafficTypes = {TrafficType.Guest};
|
||||
|
||||
@Override
|
||||
@ -230,6 +236,16 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
|
||||
txn.start();
|
||||
_networkMgr.markIpAsUnavailable(ip.getId());
|
||||
_ipAddressDao.unassignIpAddress(ip.getId());
|
||||
//unassign nic secondary ip address
|
||||
s_logger.debug("remove nic " + nic.getId() + " secondary ip ");
|
||||
List<String> nicSecIps = null;
|
||||
nicSecIps = _nicSecondaryIpDao.getSecondaryIpAddressesForNic(nic.getId());
|
||||
for (String secIp: nicSecIps) {
|
||||
IPAddressVO pubIp = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), secIp);
|
||||
_networkMgr.markIpAsUnavailable(pubIp.getId());
|
||||
_ipAddressDao.unassignIpAddress(pubIp.getId());
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,8 +46,10 @@ import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupI
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.amazonaws.services.identitymanagement.model.User;
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.NetworkRulesSystemVmCommand;
|
||||
import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand;
|
||||
import com.cloud.agent.api.SecurityGroupRulesCmd;
|
||||
import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
@ -67,12 +69,6 @@ import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.security.SecurityGroupWork.Step;
|
||||
import com.cloud.network.security.SecurityRule.SecurityRuleType;
|
||||
import com.cloud.network.security.dao.SecurityGroupDao;
|
||||
import com.cloud.network.security.dao.SecurityGroupRuleDao;
|
||||
import com.cloud.network.security.dao.SecurityGroupRulesDao;
|
||||
import com.cloud.network.security.dao.SecurityGroupVMMapDao;
|
||||
import com.cloud.network.security.dao.SecurityGroupWorkDao;
|
||||
import com.cloud.network.security.dao.VmRulesetLogDao;
|
||||
import com.cloud.network.security.dao.*;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
@ -97,6 +93,8 @@ import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.*;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
@ -149,6 +147,10 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
ProjectManager _projectMgr;
|
||||
@Inject
|
||||
ResourceTagDao _resourceTagDao;
|
||||
@Inject
|
||||
NicDao _nicDao;
|
||||
@Inject
|
||||
NicSecondaryIpDao _nicSecIpDao;
|
||||
|
||||
ScheduledExecutorService _executorPool;
|
||||
ScheduledExecutorService _cleanupExecutor;
|
||||
@ -489,7 +491,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
return affectedVms;
|
||||
}
|
||||
|
||||
protected SecurityGroupRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map<PortAndProto, Set<String>> ingressRules, Map<PortAndProto, Set<String>> egressRules) {
|
||||
protected SecurityGroupRulesCmd generateRulesetCmd(String vmName, String guestIp, String guestMac, Long vmId, String signature, long seqnum, Map<PortAndProto, Set<String>> ingressRules, Map<PortAndProto, Set<String>> egressRules, List<String> secIps) {
|
||||
List<IpPortAndProto> ingressResult = new ArrayList<IpPortAndProto>();
|
||||
List<IpPortAndProto> egressResult = new ArrayList<IpPortAndProto>();
|
||||
for (PortAndProto pAp : ingressRules.keySet()) {
|
||||
@ -506,7 +508,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
egressResult.add(ipPortAndProto);
|
||||
}
|
||||
}
|
||||
return new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, ingressResult.toArray(new IpPortAndProto[ingressResult.size()]), egressResult.toArray(new IpPortAndProto[egressResult.size()]));
|
||||
return new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqnum, ingressResult.toArray(new IpPortAndProto[ingressResult.size()]), egressResult.toArray(new IpPortAndProto[egressResult.size()]), secIps);
|
||||
}
|
||||
|
||||
protected void handleVmStopped(VMInstanceVO vm) {
|
||||
@ -947,8 +949,19 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
Map<PortAndProto, Set<String>> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule);
|
||||
agentId = vm.getHostId();
|
||||
if (agentId != null) {
|
||||
// get nic secondary ip address
|
||||
String privateIp = vm.getPrivateIpAddress();
|
||||
NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId());
|
||||
List<String> nicSecIps = null;
|
||||
if (nic != null) {
|
||||
if (nic.getSecondaryIp()) {
|
||||
//get secondary ips of the vm
|
||||
long networkId = nic.getNetworkId();
|
||||
nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId());
|
||||
}
|
||||
}
|
||||
SecurityGroupRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(ingressRules, egressRules), seqnum,
|
||||
ingressRules, egressRules);
|
||||
ingressRules, egressRules, nicSecIps);
|
||||
Commands cmds = new Commands(cmd);
|
||||
try {
|
||||
_agentMgr.send(agentId, cmds, _answerListener);
|
||||
@ -1272,4 +1285,66 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean securityGroupRulesForVmSecIp(Long nicId, Long networkId,
|
||||
String secondaryIp, boolean ruleAction) {
|
||||
|
||||
String vmMac = null;
|
||||
String vmName = null;
|
||||
|
||||
if (secondaryIp == null || nicId == null || networkId == null) {
|
||||
throw new InvalidParameterValueException("Vm nicId or networkId or secondaryIp can't be null");
|
||||
}
|
||||
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
Long vmId = nic.getInstanceId();
|
||||
|
||||
// Validate parameters
|
||||
List<SecurityGroupVO> vmSgGrps = getSecurityGroupsForVm(vmId);
|
||||
if (vmSgGrps == null) {
|
||||
s_logger.debug("Vm is not in any Security group ");
|
||||
return true;
|
||||
}
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
for (SecurityGroupVO securityGroup: vmSgGrps) {
|
||||
Account owner = _accountMgr.getAccount(securityGroup.getAccountId());
|
||||
if (owner == null) {
|
||||
throw new InvalidParameterValueException("Unable to find security group owner by id=" + securityGroup.getAccountId());
|
||||
}
|
||||
// Verify permissions
|
||||
_accountMgr.checkAccess(caller, null, true, securityGroup);
|
||||
}
|
||||
|
||||
UserVm vm = _userVMDao.findById(vmId);
|
||||
if (vm.getType() != VirtualMachine.Type.User) {
|
||||
throw new InvalidParameterValueException("Can't configure the SG ipset, arprules rules for the non user vm");
|
||||
}
|
||||
|
||||
if (vm != null) {
|
||||
vmMac = vm.getPrivateMacAddress();
|
||||
vmName = vm.getInstanceName();
|
||||
if (vmMac == null || vmName == null) {
|
||||
throw new InvalidParameterValueException("vm name or vm mac can't be null");
|
||||
}
|
||||
}
|
||||
|
||||
//create command for the to add ip in ipset and arptables rules
|
||||
NetworkRulesVmSecondaryIpCommand cmd = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, ruleAction);
|
||||
s_logger.debug("Asking agent to configure rules for vm secondary ip");
|
||||
Commands cmds = null;
|
||||
|
||||
cmds = new Commands(cmd);
|
||||
try {
|
||||
_agentMgr.send(vm.getHostId(), cmds);
|
||||
} catch (AgentUnavailableException e) {
|
||||
s_logger.debug(e.toString());
|
||||
} catch (OperationTimedoutException e) {
|
||||
s_logger.debug(e.toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Profiler;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.mgmt.JmxUtil;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.network.security.SecurityRule.SecurityRuleType;
|
||||
|
||||
@ -169,9 +170,19 @@ public class SecurityGroupManagerImpl2 extends SecurityGroupManagerImpl{
|
||||
Map<PortAndProto, Set<String>> egressRules = generateRulesForVM(userVmId, SecurityRuleType.EgressRule);
|
||||
Long agentId = vm.getHostId();
|
||||
if (agentId != null) {
|
||||
String privateIp = vm.getPrivateIpAddress();
|
||||
NicVO nic = _nicDao.findByIp4AddressAndVmId(privateIp, vm.getId());
|
||||
List<String> nicSecIps = null;
|
||||
if (nic != null) {
|
||||
if (nic.getSecondaryIp()) {
|
||||
//get secondary ips of the vm
|
||||
long networkId = nic.getNetworkId();
|
||||
nicSecIps = _nicSecIpDao.getSecondaryIpAddressesForNic(nic.getId());
|
||||
}
|
||||
}
|
||||
SecurityGroupRulesCmd cmd = generateRulesetCmd(vm.getInstanceName(), vm.getPrivateIpAddress(),
|
||||
vm.getPrivateMacAddress(), vm.getId(), null,
|
||||
work.getLogsequenceNumber(), ingressRules, egressRules);
|
||||
work.getLogsequenceNumber(), ingressRules, egressRules, nicSecIps);
|
||||
cmd.setMsId(_serverId);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("SecurityGroupManager v2: sending ruleset update for vm " + vm.getInstanceName() +
|
||||
|
||||
@ -1360,13 +1360,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
+ " as a part of vm id=" + vmId
|
||||
+ " expunge because resource is unavailable", e);
|
||||
}
|
||||
//remove vm secondary ip addresses
|
||||
if (_networkMgr.removeVmSecondaryIps(vmId)) {
|
||||
s_logger.debug("Removed vm " + vmId + " secondary ip address of the VM Nics as a part of expunge process");
|
||||
} else {
|
||||
success = false;
|
||||
s_logger.warn("Fail to remove secondary ip address of vm " + vmId + " Nics as a part of expunge process");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -60,4 +60,6 @@ public interface NicDao extends GenericDao<NicVO, Long> {
|
||||
NicVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, long instanceId, String ip4Address);
|
||||
|
||||
List<NicVO> listByVmIdAndNicId(Long vmId, Long nicId);
|
||||
|
||||
NicVO findByIp4AddressAndVmId(String ip4Address, long instance);
|
||||
}
|
||||
|
||||
@ -212,4 +212,13 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
|
||||
sc.setParameters("nicid", nicId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicVO findByIp4AddressAndVmId(String ip4Address, long instance) {
|
||||
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("address", ip4Address);
|
||||
sc.setParameters("instance", instance);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
@ -854,11 +855,6 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVmSecondaryIps(long vmId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Nic> listVmNics(Long vmId, Long nicId) {
|
||||
@ -871,4 +867,18 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc,
|
||||
Pod pod, Account caller, String requestedIp)
|
||||
throws InsufficientAddressCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVmSecondaryIpsOfNic(long nicId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
@ -1365,12 +1366,6 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean removeVmSecondaryIps(long vmId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1390,4 +1385,30 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String allocatePublicIpForGuestNic(Long networkId, DataCenter dc,
|
||||
Pod pod, Account caller, String requestedIp)
|
||||
throws InsufficientAddressCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean removeVmSecondaryIpsOfNic(long nicId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user