mirror of
https://github.com/apache/cloudstack
synced 2026-08-02 05:26:35 +00:00
Merge branch 'master' into vim51_win8
This commit is contained in:
commit
8f33229fc1
@ -52,8 +52,9 @@ server are available and not blocked by any local firewall. Following ports are
|
||||
used by Apache CloudStack and its entities:
|
||||
|
||||
8787: Apache CloudStack (Tomcat) debug socket
|
||||
9090, 8250: Apache CloudStack Management Server, User/Client API
|
||||
9090, 8250, 8080: Apache CloudStack Management Server, User/Client API
|
||||
8096: User/Client to CloudStack Management Server (unauthenticated)
|
||||
7080: AWS API Server
|
||||
3306: MySQL Server
|
||||
3922, 8250, 80/443, 111/2049, 53: Secondary Storage VM
|
||||
3922, 8250, 53: Console Proxy VM
|
||||
|
||||
@ -50,7 +50,7 @@ public class FirewallRuleTO implements InternalIdentity {
|
||||
FirewallRule.Purpose purpose;
|
||||
private Integer icmpType;
|
||||
private Integer icmpCode;
|
||||
|
||||
private FirewallRule.TrafficType trafficType;
|
||||
|
||||
protected FirewallRuleTO() {
|
||||
}
|
||||
@ -85,6 +85,7 @@ public class FirewallRuleTO implements InternalIdentity {
|
||||
this.sourceCidrList = sourceCidr;
|
||||
this.icmpType = icmpType;
|
||||
this.icmpCode = icmpCode;
|
||||
this.trafficType = null;
|
||||
}
|
||||
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp) {
|
||||
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(),rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
@ -93,6 +94,23 @@ public class FirewallRuleTO implements InternalIdentity {
|
||||
public FirewallRuleTO(FirewallRule rule, String srcIp) {
|
||||
this(rule.getId(),null, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(),rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
}
|
||||
|
||||
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose) {
|
||||
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
}
|
||||
|
||||
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType) {
|
||||
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
this.trafficType = trafficType;
|
||||
}
|
||||
|
||||
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, boolean revokeState, boolean alreadyAdded) {
|
||||
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
|
||||
}
|
||||
|
||||
public FirewallRule.TrafficType getTrafficType(){
|
||||
return trafficType;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
|
||||
@ -26,6 +26,7 @@ public class EventTypes {
|
||||
public static final String EVENT_VM_UPDATE = "VM.UPDATE";
|
||||
public static final String EVENT_VM_UPGRADE = "VM.UPGRADE";
|
||||
public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
|
||||
public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
|
||||
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
|
||||
public static final String EVENT_VM_MOVE = "VM.MOVE";
|
||||
public static final String EVENT_VM_RESTORE = "VM.RESTORE";
|
||||
@ -63,6 +64,11 @@ public class EventTypes {
|
||||
public static final String EVENT_FIREWALL_OPEN = "FIREWALL.OPEN";
|
||||
public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
|
||||
|
||||
//NIC Events
|
||||
public static final String EVENT_NIC_CREATE = "NIC.CREATE";
|
||||
public static final String EVENT_NIC_DELETE = "NIC.DELETE";
|
||||
public static final String EVENT_NIC_UPDATE = "NIC.UPDATE";
|
||||
|
||||
// Load Balancers
|
||||
public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE";
|
||||
public static final String EVENT_REMOVE_FROM_LOAD_BALANCER_RULE = "LB.REMOVE.FROM.RULE";
|
||||
|
||||
@ -47,8 +47,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
|
||||
public static final Service Dhcp = new Service("Dhcp");
|
||||
public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification);
|
||||
public static final Service Gateway = new Service("Gateway");
|
||||
public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols,
|
||||
Capability.MultipleIps, Capability.TrafficStatistics);
|
||||
public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols,
|
||||
Capability.MultipleIps, Capability.TrafficStatistics, Capability.SupportedTrafficDirection, Capability.SupportedEgressProtocols);
|
||||
public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation,
|
||||
Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps,
|
||||
Capability.SupportedStickinessMethods, Capability.ElasticLb);
|
||||
@ -173,6 +173,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
|
||||
public static final Capability ElasticLb = new Capability("ElasticLb");
|
||||
public static final Capability AutoScaleCounters = new Capability("AutoScaleCounters");
|
||||
public static final Capability InlineMode = new Capability("InlineMode");
|
||||
public static final Capability SupportedTrafficDirection = new Capability("SupportedTrafficDirection");
|
||||
public static final Capability SupportedEgressProtocols = new Capability("SupportedEgressProtocols");
|
||||
|
||||
private String name;
|
||||
|
||||
@ -287,6 +289,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
|
||||
|
||||
void setPhysicalNetworkId(Long physicalNetworkId);
|
||||
|
||||
public void setTrafficType(TrafficType type);
|
||||
|
||||
ACLType getAclType();
|
||||
|
||||
boolean isRestartRequired();
|
||||
|
||||
@ -226,4 +226,8 @@ public class NetworkProfile implements Network {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrafficType(TrafficType type) {
|
||||
this.trafficType = type;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,4 +30,5 @@ public interface UserDataServiceProvider extends NetworkElement {
|
||||
public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
|
||||
boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws ResourceUnavailableException;
|
||||
boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws ResourceUnavailableException;
|
||||
boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String SSHPublicKey) throws ResourceUnavailableException;
|
||||
}
|
||||
|
||||
@ -27,7 +27,8 @@ import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
public interface FirewallService {
|
||||
FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
|
||||
FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
|
||||
FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
|
||||
|
||||
Pair<List<? extends FirewallRule>, Integer> listFirewallRules(ListFirewallRulesCmd cmd);
|
||||
|
||||
@ -40,7 +41,8 @@ public interface FirewallService {
|
||||
*/
|
||||
boolean revokeFirewallRule(long ruleId, boolean apply);
|
||||
|
||||
boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException;
|
||||
boolean applyEgressFirewallRules (FirewallRule rule, Account caller) throws ResourceUnavailableException;
|
||||
boolean applyIngressFirewallRules(long Ipid , Account caller) throws ResourceUnavailableException;
|
||||
|
||||
FirewallRule getFirewallRule(long ruleId);
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
|
||||
|
||||
@ -88,6 +89,15 @@ public interface UserVmService {
|
||||
*/
|
||||
UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* Resets the SSH Key of a virtual machine.
|
||||
*
|
||||
* @param cmd
|
||||
* - the command specifying vmId, Keypair name
|
||||
* @return the VM if reset worked successfully, null otherwise
|
||||
*/
|
||||
UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* Attaches the specified volume to the specified VM
|
||||
*
|
||||
@ -113,6 +123,27 @@ public interface UserVmService {
|
||||
|
||||
UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* Adds a NIC on the given network to the virtual machine
|
||||
* @param cmd the command object that defines the vm and the given network
|
||||
* @return the vm object if successful, null otherwise
|
||||
*/
|
||||
UserVm addNicToVirtualMachine(AddNicToVMCmd cmd);
|
||||
|
||||
/**
|
||||
* Removes a NIC on the given network from the virtual machine
|
||||
* @param cmd the command object that defines the vm and the given network
|
||||
* @return the vm object if successful, null otherwise
|
||||
*/
|
||||
UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd);
|
||||
|
||||
/**
|
||||
* Updates default Nic to the given network for given virtual machine
|
||||
* @param cmd the command object that defines the vm and the given network
|
||||
* @return the vm object if successful, null otherwise
|
||||
*/
|
||||
UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd);
|
||||
|
||||
UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
|
||||
@ -224,6 +224,7 @@ public class ApiConstants {
|
||||
public static final String NETWORK_OFFERING_ID = "networkofferingid";
|
||||
public static final String NETWORK_IDS = "networkids";
|
||||
public static final String NETWORK_ID = "networkid";
|
||||
public static final String NIC_ID = "nicid";
|
||||
public static final String SPECIFY_VLAN = "specifyvlan";
|
||||
public static final String IS_DEFAULT = "isdefault";
|
||||
public static final String IS_SYSTEM = "issystem";
|
||||
|
||||
@ -289,14 +289,14 @@ public abstract class BaseCmd {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
||||
// JSON response
|
||||
sb.append("{ \"" + getCommandName() + "\" : { " + "\"@attributes\":{\"cloudstack-version\":\"" + _mgr.getVersion() + "\"},");
|
||||
sb.append("{ \"" + getCommandName() + "\" : { " + "\"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},");
|
||||
sb.append("\"errorcode\" : \"" + apiException.getErrorCode() + "\", \"description\" : \"" + apiException.getDescription() + "\" } }");
|
||||
} else {
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
||||
sb.append("<" + getCommandName() + ">");
|
||||
sb.append("<errorcode>" + apiException.getErrorCode() + "</errorcode>");
|
||||
sb.append("<description>" + escapeXml(apiException.getDescription()) + "</description>");
|
||||
sb.append("</" + getCommandName() + " cloudstack-version=\"" + _mgr.getVersion() + "\">");
|
||||
sb.append("</" + getCommandName() + " cloud-stack-version=\"" + _mgr.getVersion() + "\">");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@ -307,10 +307,10 @@ public abstract class BaseCmd {
|
||||
|
||||
// set up the return value with the name of the response
|
||||
if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
||||
prefixSb.append("{ \"" + getCommandName() + "\" : { \"@attributes\":{\"cloudstack-version\":\"" + _mgr.getVersion() + "\"},");
|
||||
prefixSb.append("{ \"" + getCommandName() + "\" : { \"@attributes\":{\"cloud-stack-version\":\"" + _mgr.getVersion() + "\"},");
|
||||
} else {
|
||||
prefixSb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
||||
prefixSb.append("<" + getCommandName() + " cloudstack-version=\"" + _mgr.getVersion() + "\">");
|
||||
prefixSb.append("<" + getCommandName() + " cloud-stack-version=\"" + _mgr.getVersion() + "\">");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
@ -0,0 +1,341 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.FirewallResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@APICommand(name = "createEgressFirewallRule", description = "Creates a egress firewall rule for a given network ", responseObject = FirewallResponse.class)
|
||||
public class CreateEgressFirewallRuleCmd extends BaseAsyncCreateCmd implements FirewallRule {
|
||||
public static final Logger s_logger = Logger.getLogger(CreateEgressFirewallRuleCmd.class.getName());
|
||||
|
||||
private static final String s_name = "createegressfirewallruleresponse";
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ////////////// API parameters /////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Parameter (name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the network id of the port forwarding rule")
|
||||
private Long networkId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the firewall rule. Valid values are TCP/UDP/ICMP.")
|
||||
private String protocol;
|
||||
|
||||
@Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of firewall rule")
|
||||
private Integer publicStartPort;
|
||||
|
||||
@Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of firewall rule")
|
||||
private Integer publicEndPort;
|
||||
|
||||
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from")
|
||||
private List<String> cidrlist;
|
||||
|
||||
@Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the icmp message being sent")
|
||||
private Integer icmpType;
|
||||
|
||||
@Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message")
|
||||
private Integer icmpCode;
|
||||
|
||||
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "type of firewallrule: system/user")
|
||||
private String type;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
public Long getIpAddressId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol.trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSourceCidrList() {
|
||||
if (cidrlist != null) {
|
||||
return cidrlist;
|
||||
} else {
|
||||
List<String> oneCidrList = new ArrayList<String>();
|
||||
oneCidrList.add(_networkService.getNetwork(networkId).getCidr());
|
||||
return oneCidrList;
|
||||
}
|
||||
}
|
||||
|
||||
public Long getVpcId() {
|
||||
Network network = _networkService.getNetwork(getNetworkId());
|
||||
if (network == null) {
|
||||
throw new InvalidParameterValueException("Invalid networkId is given");
|
||||
}
|
||||
|
||||
Long vpcId = network.getVpcId();
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> cidrs){
|
||||
cidrlist = cidrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
UserContext callerContext = UserContext.current();
|
||||
boolean success = false;
|
||||
FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
success = _firewallService.applyEgressFirewallRules (rule, callerContext.getCaller());
|
||||
// State is different after the rule is applied, so get new object here
|
||||
rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
FirewallResponse fwResponse = new FirewallResponse();
|
||||
if (rule != null) {
|
||||
fwResponse = _responseGenerator.createFirewallResponse(rule);
|
||||
setResponseObject(fwResponse);
|
||||
}
|
||||
fwResponse.setResponseName(getCommandName());
|
||||
} finally {
|
||||
if (!success || rule == null) {
|
||||
_firewallService.revokeFirewallRule(getEntityId(), true);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create firewall rule");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
throw new UnsupportedOperationException("database id can only provided by VO objects");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getXid() {
|
||||
// FIXME: We should allow for end user to specify Xid.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSourceIpAddressId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSourcePortStart() {
|
||||
if (publicStartPort != null) {
|
||||
return publicStartPort.intValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSourcePortEnd() {
|
||||
if (publicEndPort == null) {
|
||||
if (publicStartPort != null) {
|
||||
return publicStartPort.intValue();
|
||||
}
|
||||
} else {
|
||||
return publicEndPort.intValue();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Purpose getPurpose() {
|
||||
return Purpose.Firewall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
throw new UnsupportedOperationException("Should never call me to find the state");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = UserContext.current().getCaller();
|
||||
|
||||
if (account != null) {
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
Network network =_networkService.getNetwork(networkId);
|
||||
return network.getDomainId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
if (getSourceCidrList() != null) {
|
||||
String guestCidr = _networkService.getNetwork(getNetworkId()).getCidr();
|
||||
|
||||
for (String cidr: getSourceCidrList()){
|
||||
if (!NetUtils.isValidCIDR(cidr)){
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr);
|
||||
}
|
||||
if (cidr.equals(NetUtils.ALL_CIDRS)) {
|
||||
continue;
|
||||
}
|
||||
if(!NetUtils.isNetworkAWithinNetworkB(cidr, guestCidr)) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, cidr + "is not within the guest cidr " + guestCidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getProtocol().equalsIgnoreCase(NetUtils.ALL_PROTO)) {
|
||||
if (getSourcePortStart() != null && getSourcePortEnd() != null) {
|
||||
throw new InvalidParameterValueException("Do not pass ports to protocol ALL, porotocol ALL do not require ports. Unable to create "
|
||||
+"firewall rule for the network id=" + networkId);
|
||||
}
|
||||
}
|
||||
|
||||
if (getVpcId() != null ){
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule for the network id=" + networkId +
|
||||
" as firewall egress rule can be created only for non vpc networks.");
|
||||
}
|
||||
|
||||
try {
|
||||
FirewallRule result = _firewallService.createEgressFirewallRule(this);
|
||||
setEntityId(result.getId());
|
||||
} catch (NetworkRuleConflictException ex) {
|
||||
s_logger.info("Network rule conflict: " + ex.getMessage());
|
||||
s_logger.trace("Network Rule Conflict: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_FIREWALL_OPEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
Network network = _networkService.getNetwork(networkId);
|
||||
return ("Creating firewall rule for network: " + network + " for protocol:" + this.getProtocol());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
Network network = _networkService.getNetwork(networkId);
|
||||
return network.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return BaseAsyncCmd.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return getNetworkId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
if (icmpCode != null) {
|
||||
return icmpCode;
|
||||
} else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
|
||||
return -1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIcmpType() {
|
||||
if (icmpType != null) {
|
||||
return icmpType;
|
||||
} else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
|
||||
return -1;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getRelated() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRuleType getType() {
|
||||
if (type != null && type.equalsIgnoreCase("system")) {
|
||||
return FirewallRuleType.System;
|
||||
} else {
|
||||
return FirewallRuleType.User;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncJob.Type getInstanceType() {
|
||||
return AsyncJob.Type.FirewallRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrafficType getTrafficType() {
|
||||
return TrafficType.Egress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -122,7 +122,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
||||
FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
try {
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
success = _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
success = _firewallService.applyIngressFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
|
||||
|
||||
// State is different after the rule is applied, so get new object here
|
||||
rule = _entityMgr.findById(FirewallRule.class, getEntityId());
|
||||
@ -238,7 +238,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
||||
}
|
||||
|
||||
try {
|
||||
FirewallRule result = _firewallService.createFirewallRule(this);
|
||||
FirewallRule result = _firewallService.createIngressFirewallRule(this);
|
||||
setEntityId(result.getId());
|
||||
setEntityUuid(result.getUuid());
|
||||
} catch (NetworkRuleConflictException ex) {
|
||||
|
||||
@ -163,7 +163,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
success = success && _firewallService.applyFirewallRules(ipAddressId, callerContext.getCaller());
|
||||
success = success && _firewallService.applyIngressFirewallRules(ipAddressId, callerContext.getCaller());
|
||||
}
|
||||
|
||||
success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCaller());
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.user.UserContext;
|
||||
|
||||
@APICommand(name = "deleteEgressFirewallRule", description="Deletes an ggress firewall rule", responseObject=SuccessResponse.class)
|
||||
public class DeleteEgressFirewallRuleCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeleteEgressFirewallRuleCmd.class.getName());
|
||||
private static final String s_name = "deleteegressfirewallruleresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the firewall rule")
|
||||
private Long id;
|
||||
|
||||
// unexposed parameter needed for events logging
|
||||
@Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG, expose=false)
|
||||
private Long ownerId;
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_FIREWALL_CLOSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return ("Deleting egress firewall rule id=" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
if (ownerId == null) {
|
||||
FirewallRule rule = _entityMgr.findById(FirewallRule.class, id);
|
||||
if (rule == null) {
|
||||
throw new InvalidParameterValueException("Unable to find egress firewall rule by id");
|
||||
} else {
|
||||
ownerId = _entityMgr.findById(FirewallRule.class, id).getAccountId();
|
||||
}
|
||||
}
|
||||
return ownerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException {
|
||||
UserContext.current().setEventDetails("Rule Id: " + id);
|
||||
boolean result = _firewallService.revokeFirewallRule(id, true);
|
||||
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete egress firewall rule");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSyncObjType() {
|
||||
return BaseAsyncCmd.networkSyncObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return _firewallService.getFirewallRule(id).getNetworkId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncJob.Type getInstanceType() {
|
||||
return AsyncJob.Type.FirewallRule;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
package org.apache.cloudstack.api.command.user.firewall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.FirewallResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
@APICommand(name = "listEgressFirewallRules", description="Lists all egress firewall rules for network id.", responseObject=FirewallResponse.class)
|
||||
public class ListEgressFirewallRulesCmd extends ListFirewallRulesCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListEgressFirewallRulesCmd.class.getName());
|
||||
private static final String s_name = "listegressfirewallrulesresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="Lists rule with the specified ID.")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="the id network network for the egress firwall services")
|
||||
private Long networkId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public FirewallRule.TrafficType getTrafficType () {
|
||||
return FirewallRule.TrafficType.Egress;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
Pair<List<? extends FirewallRule>, Integer> result = _firewallService.listFirewallRules(this);
|
||||
ListResponse<FirewallResponse> response = new ListResponse<FirewallResponse>();
|
||||
List<FirewallResponse> fwResponses = new ArrayList<FirewallResponse>();
|
||||
|
||||
for (FirewallRule fwRule : result.first()) {
|
||||
FirewallResponse ruleData = _responseGenerator.createFirewallResponse(fwRule);
|
||||
ruleData.setObjectName("firewallrule");
|
||||
fwResponses.add(ruleData);
|
||||
}
|
||||
response.setResponses(fwResponses, result.second());
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
}
|
||||
@ -56,6 +56,10 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd {
|
||||
return ipAddressId;
|
||||
}
|
||||
|
||||
public FirewallRule.TrafficType getTrafficType () {
|
||||
return FirewallRule.TrafficType.Ingress;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements
|
||||
UserContext.current().setEventDetails("Rule Id: " + getEntityId());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
success = success && _firewallService.applyFirewallRules(getSourceIpAddressId(), callerContext.getCaller());
|
||||
success = success && _firewallService.applyIngressFirewallRules(getSourceIpAddressId(), callerContext.getCaller());
|
||||
}
|
||||
|
||||
// State might be different after the rule is applied, so get new object here
|
||||
|
||||
@ -115,7 +115,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
||||
UserContext.current().setEventDetails("Rule Id: "+ getEntityId());
|
||||
|
||||
if (getOpenFirewall()) {
|
||||
result = result && _firewallService.applyFirewallRules(ipAddressId, UserContext.current().getCaller());
|
||||
result = result && _firewallService.applyIngressFirewallRules(ipAddressId, UserContext.current().getCaller());
|
||||
}
|
||||
|
||||
result = result && _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
||||
@APICommand(name = "addNicToVirtualMachine", description="Adds VM to specified network by creating a NIC", responseObject=UserVmResponse.class)
|
||||
|
||||
public class AddNicToVMCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(AddNicToVMCmd.class);
|
||||
private static final String s_name = "addnictovirtualmachineresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
|
||||
required=true, description="Virtual Machine ID")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class,
|
||||
required=true, description="Network ID")
|
||||
private Long netId;
|
||||
|
||||
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="IP Address for the new network")
|
||||
private String ipaddr;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getNetworkId() {
|
||||
return netId;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipaddr;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public static String getResultObjectName() {
|
||||
return "virtualmachine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_NIC_CREATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Adding network " + getNetworkId() + " to user vm: " + getVmId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmById(getVmId());
|
||||
if (vm == null) {
|
||||
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
UserContext.current().setEventDetails("Vm Id: " + getVmId() + " Network Id: " + getNetworkId());
|
||||
UserVm result = _userVmService.addNicToVirtualMachine(this);
|
||||
ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
|
||||
dc.add(VMDetails.valueOf("nics"));
|
||||
EnumSet<VMDetails> details = EnumSet.copyOf(dc);
|
||||
if (result != null){
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", details, result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add NIC to vm. Refer to server logs for details.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.NicResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
||||
@APICommand(name = "removeNicFromVirtualMachine", description="Removes VM from specified network by deleting a NIC", responseObject=UserVmResponse.class)
|
||||
|
||||
public class RemoveNicFromVMCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(RemoveNicFromVMCmd.class);
|
||||
private static final String s_name = "removenicfromvirtualmachineresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
|
||||
required=true, description="Virtual Machine ID")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType=NicResponse.class,
|
||||
required=true, description="NIC ID")
|
||||
private Long nicId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getNicId() {
|
||||
return nicId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public static String getResultObjectName() {
|
||||
return "virtualmachine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_NIC_DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Removing NIC " + getNicId() + " from user vm: " + getVmId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmById(getVmId());
|
||||
if (vm == null) {
|
||||
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
UserContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId());
|
||||
UserVm result = _userVmService.removeNicFromVirtualMachine(this);
|
||||
ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
|
||||
dc.add(VMDetails.valueOf("nics"));
|
||||
EnumSet<VMDetails> details = EnumSet.copyOf(dc);
|
||||
if (result != null){
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", details, result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove NIC from vm, see error log for details");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import com.cloud.async.AsyncJob;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
|
||||
@APICommand(name = "resetSSHKeyForVirtualMachine", responseObject = UserVmResponse.class, description = "Resets the SSH Key for virtual machine. " +
|
||||
"The virtual machine must be in a \"Stopped\" state. [async]")
|
||||
public class ResetVMSSHKeyCmd extends BaseAsyncCmd {
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(ResetVMSSHKeyCmd.class.getName());
|
||||
|
||||
private static final String s_name = "resetSSHKeyforvirtualmachineresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "The ID of the virtual machine")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.SSH_KEYPAIR, type = CommandType.STRING, required = true, description = "name of the ssh key pair used to login to the virtual machine")
|
||||
private String name;
|
||||
|
||||
|
||||
//Owner information
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the ssh key. Must be used with domainId.")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the ssh key")
|
||||
private Long projectId;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_RESETSSHKEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "resetting SSHKey for vm: " + getId();
|
||||
}
|
||||
|
||||
public AsyncJob.Type getInstanceType() {
|
||||
return AsyncJob.Type.VirtualMachine;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmById(getId());
|
||||
if (vm != null) {
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
|
||||
public Long getInstanceId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException,
|
||||
InsufficientCapacityException {
|
||||
|
||||
UserContext.current().setEventDetails("Vm Id: " + getId());
|
||||
UserVm result = _userVmService.resetVMSSHKey(this);
|
||||
|
||||
if (result != null) {
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to reset vm SSHKey");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.*;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.NicResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
||||
@APICommand(name = "updateDefaultNicForVirtualMachine", description="Changes the default NIC on a VM", responseObject=UserVmResponse.class)
|
||||
|
||||
public class UpdateDefaultNicForVMCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(UpdateDefaultNicForVMCmd.class);
|
||||
private static final String s_name = "updatedefaultnicforvirtualmachineresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.UUID, entityType=UserVmResponse.class,
|
||||
required=true, description="Virtual Machine ID")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name=ApiConstants.NIC_ID, type=CommandType.UUID, entityType=NicResponse.class,
|
||||
required=true, description="NIC ID")
|
||||
private Long nicId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getNicId() {
|
||||
return nicId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public static String getResultObjectName() {
|
||||
return "virtualmachine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_NIC_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Updating NIC " + getNicId() + " on user vm: " + getVmId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm vm = _responseGenerator.findUserVmById(getVmId());
|
||||
if (vm == null) {
|
||||
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
return vm.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
UserContext.current().setEventDetails("Vm Id: "+getVmId() + " Nic Id: " + getNicId());
|
||||
UserVm result = _userVmService.updateDefaultNicForVirtualMachine(this);
|
||||
ArrayList<VMDetails> dc = new ArrayList<VMDetails>();
|
||||
dc.add(VMDetails.valueOf("nics"));
|
||||
EnumSet<VMDetails> details = EnumSet.copyOf(dc);
|
||||
if (result != null){
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", details, result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to set default nic for VM. Refer to server logs for details.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,9 @@ public class FirewallResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the firewall rule")
|
||||
private Long publicIpAddressId;
|
||||
|
||||
@SerializedName(ApiConstants.NETWORK_ID) @Param(description="the network id of the firewall rule")
|
||||
private Long networkId;
|
||||
|
||||
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the firewall rule")
|
||||
private String publicIpAddress;
|
||||
|
||||
@ -82,6 +85,10 @@ public class FirewallResponse extends BaseResponse {
|
||||
this.publicIpAddress = publicIpAddress;
|
||||
}
|
||||
|
||||
public void setNetworkId(Long networkId) {
|
||||
this.networkId = networkId;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@ -17,11 +17,14 @@
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value=Nic.class)
|
||||
public class NicResponse extends BaseResponse {
|
||||
|
||||
@SerializedName("id") @Param(description="the ID of the nic")
|
||||
|
||||
@ -1215,6 +1215,7 @@ label.network.offering.id=Network Offering ID
|
||||
label.network.offering.name=Network Offering Name
|
||||
label.network.offering=Network Offering
|
||||
label.network.rate=Network Rate
|
||||
label.network.rate.megabytes=Network Rate (Mb/s)
|
||||
label.network.read=Network Read
|
||||
label.network.type=Network Type
|
||||
label.network.write=Network Write
|
||||
|
||||
@ -60,6 +60,7 @@ rebootVirtualMachine=15
|
||||
startVirtualMachine=15
|
||||
stopVirtualMachine=15
|
||||
resetPasswordForVirtualMachine=15
|
||||
resetSSHKeyForVirtualMachine=15
|
||||
updateVirtualMachine=15
|
||||
listVirtualMachines=15
|
||||
getVMPassword=15
|
||||
@ -320,6 +321,11 @@ listNetworks=15
|
||||
restartNetwork=15
|
||||
updateNetwork=15
|
||||
|
||||
#### nic commands ####
|
||||
addNicToVirtualMachine=15
|
||||
removeNicFromVirtualMachine=15
|
||||
updateDefaultNicForVirtualMachine=15
|
||||
|
||||
#### SSH key pair commands
|
||||
registerSSHKeyPair=15
|
||||
createSSHKeyPair=15
|
||||
@ -345,6 +351,11 @@ createFirewallRule=15
|
||||
deleteFirewallRule=15
|
||||
listFirewallRules=15
|
||||
|
||||
####
|
||||
createEgressFirewallRule=15
|
||||
deleteEgressFirewallRule=15
|
||||
listEgressFirewallRules=15
|
||||
|
||||
#### hypervisor capabilities commands
|
||||
updateHypervisorCapabilities=1
|
||||
listHypervisorCapabilities=1
|
||||
|
||||
@ -197,7 +197,6 @@
|
||||
|
||||
<!-- Listen on 6443 instead of 8443 because tomcat6 will change 8443 to a random one when CATALINA_HOME is not /usr/share/tomcat6 -->
|
||||
<Connector executor="tomcatThreadPool-internal" port="5443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
|
||||
>>>>>>> bcfd64a... CS-15373: Awsapi port change to 7080.
|
||||
maxThreads="150" scheme="https" secure="true"
|
||||
clientAuth="false" sslProtocol="TLS"
|
||||
keystoreType="JKS"
|
||||
|
||||
@ -69,12 +69,14 @@ import com.cloud.agent.api.routing.SetStaticRouteCommand;
|
||||
import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
|
||||
import com.cloud.agent.api.routing.VmDataCommand;
|
||||
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
|
||||
import com.cloud.agent.api.to.FirewallRuleTO;
|
||||
import com.cloud.agent.api.to.IpAddressTO;
|
||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||
import com.cloud.agent.api.to.StaticNatRuleTO;
|
||||
import com.cloud.exception.InternalErrorException;
|
||||
import com.cloud.network.HAProxyConfigurator;
|
||||
import com.cloud.network.LoadBalancerConfigurator;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
@ -214,11 +216,18 @@ public class VirtualRoutingResource implements Manager {
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
|
||||
FirewallRuleTO[] allrules = cmd.getRules();
|
||||
FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
|
||||
|
||||
String[][] rules = cmd.generateFwRules();
|
||||
final Script command = new Script(_firewallPath, _timeout, s_logger);
|
||||
command.add(routerIp);
|
||||
command.add("-F");
|
||||
|
||||
|
||||
if (trafficType == FirewallRule.TrafficType.Egress){
|
||||
command.add("-E");
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String[] fwRules = rules[0];
|
||||
if (fwRules.length > 0) {
|
||||
|
||||
@ -24,7 +24,12 @@
|
||||
|
||||
<section id="about-security-groups">
|
||||
<title>About Security Groups</title>
|
||||
<para>Security groups provide a way to isolate traffic to VMs. A security group is a group of VMs that filter their incoming and outgoing traffic according to a set of rules, called ingress and egress rules. These rules filter network traffic according to the IP address that is attempting to communicate with the VM. Security groups are particularly useful in zones that use basic networking, because there is a single guest network for all guest VMs. In &PRODUCT; 3.0.3 - 3.0.5, security groups are supported only in zones that use basic networking.</para>
|
||||
<para>Security groups provide a way to isolate traffic to VMs. A security group is a group of
|
||||
VMs that filter their incoming and outgoing traffic according to a set of rules, called
|
||||
ingress and egress rules. These rules filter network traffic according to the IP address
|
||||
that is attempting to communicate with the VM. Security groups are particularly useful in
|
||||
zones that use basic networking, because there is a single guest network for all guest VMs.
|
||||
In advanced zones, security groups are supported only on the KVM hypervisor.</para>
|
||||
<note><para>In a zone that uses advanced networking, you can instead define multiple guest networks to isolate traffic to VMs.</para>
|
||||
</note>
|
||||
<para></para>
|
||||
|
||||
@ -31,6 +31,5 @@
|
||||
<listitem><para>The Management Server cluster runs low on CPU, memory, or storage resources</para></listitem>
|
||||
<listitem><para>The Management Server loses heartbeat from a Host for more than 3 minutes</para></listitem>
|
||||
<listitem><para>The Host cluster runs low on CPU, memory, or storage resources</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
52
docs/en-US/security-groups-advanced-zones.xml
Normal file
52
docs/en-US/security-groups-advanced-zones.xml
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
||||
%BOOK_ENTITIES;
|
||||
]>
|
||||
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<section id="security-groups-advanced-zones">
|
||||
<title>Security Groups in Advanced Zones (KVM Only)</title>
|
||||
<para>&PRODUCT; provides the ability to use security groups to provide isolation between
|
||||
guests on a single shared, zone-wide network in an advanced zone where KVM is the
|
||||
hypervisor. Using security groups in advanced zones rather than multiple VLANs allows a greater range
|
||||
of options for setting up guest isolation in a cloud.</para>
|
||||
<formalpara>
|
||||
<title>Limitations</title>
|
||||
<para>The following are not supported for this feature:</para>
|
||||
</formalpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Two IP ranges with the same VLAN and different gateway or netmask in security
|
||||
group-enabled shared network.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Two IP ranges with the same VLAN and different gateway or netmask in
|
||||
account-specific shared networks.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Multiple VLAN ranges in security group-enabled shared network.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Multiple VLAN ranges in account-specific shared networks.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Security groups must be enabled in the zone in order for this feature to be used.</para>
|
||||
</section>
|
||||
@ -25,7 +25,8 @@
|
||||
<section id="security-groups">
|
||||
<title>Security Groups</title>
|
||||
<xi:include href="about-security-groups.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="add-security-group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="security-groups-advanced-zones.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="enable-security-groups.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="add-security-group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="add-ingress-egress-rules.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
</section>
|
||||
|
||||
45
docs/en-US/snapshot-throttling.xml
Normal file
45
docs/en-US/snapshot-throttling.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "file:///C:/Program%20Files%20(x86)/Publican/DocBook_DTD/docbookx.dtd" [
|
||||
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
||||
%BOOK_ENTITIES;
|
||||
]>
|
||||
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<section id="snapshot-throttling">
|
||||
<title>Snapshot Job Throttling</title>
|
||||
<para>When a snapshot of a virtual machine is requested, the snapshot job runs on the same
|
||||
host where the VM is running or, in the case of a stopped VM, the host where it ran last. If
|
||||
many snapshots are requested for VMs on a single host, this can lead to problems with too
|
||||
many snapshot jobs overwhelming the resources of the host.</para>
|
||||
<para>To address this situation, the cloud's root administrator can throttle how many snapshot
|
||||
jobs are executed simultaneously on the hosts in the cloud by using the global configuration
|
||||
setting concurrent.snapshots.threshold.perhost. By using this setting, the administrator can
|
||||
better ensure that snapshot jobs do not time out and hypervisor hosts do not experience
|
||||
performance issues due to hosts being overloaded with too many snapshot requests.</para>
|
||||
<para>Set concurrent.snapshots.threshold.perhost to a value that represents a best guess about
|
||||
how many snapshot jobs the hypervisor hosts can execute at one time, given the current
|
||||
resources of the hosts and the number of VMs running on the hosts. If a given host has more
|
||||
snapshot requests, the additional requests are placed in a waiting queue. No new snapshot
|
||||
jobs will start until the number of currently executing snapshot jobs falls below the
|
||||
configured limit.</para>
|
||||
<para>The admin can also set job.expire.minutes to place a maximum on how long a snapshot
|
||||
request will wait in the queue. If this limit is reached, the snapshot request fails and
|
||||
returns an error message. </para>
|
||||
</section>
|
||||
@ -102,4 +102,11 @@ KfEEuzcCUIxtJYTahJ1pvlFkQ8anpuxjSEDp8x/18bq3
|
||||
<programlisting>ssh -i ~/.ssh/keypair-doc <ip address></programlisting>
|
||||
<para>The -i parameter tells the ssh client to use a ssh key found at ~/.ssh/keypair-doc.</para>
|
||||
</section>
|
||||
<section id="reset-ssh">
|
||||
<title>Resetting SSH Keys</title>
|
||||
<para>With the API command resetSSHKeyForVirtualMachine, a user can set or reset the SSH keypair
|
||||
assigned to a virtual machine. A lost or compromised SSH keypair
|
||||
can be changed, and the user can access the VM by using the new keypair. Just create or register a
|
||||
new keypair, then call resetSSHKeyForVirtualMachine.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@ -29,4 +29,5 @@
|
||||
<para>Snapshots may be taken for volumes, including both root and data disks. The administrator places a limit on the number of stored snapshots per user. Users can create new volumes from the snapshot for recovery of particular files and they can create templates from snapshots to boot from a restored disk.</para>
|
||||
<para>Users can create snapshots manually or by setting up automatic recurring snapshot policies. Users can also create disk volumes from snapshots, which may be attached to a VM like any other disk volume. Snapshots of both root disks and data disks are supported. However, &PRODUCT; does not currently support booting a VM from a recovered root disk. A disk recovered from snapshot of a root disk is treated as a regular data disk; the data on recovered disk can be accessed by attaching the disk to a VM.</para>
|
||||
<para>A completed snapshot is copied from primary storage to secondary storage, where it is stored until deleted or purged by newer snapshot.</para>
|
||||
<xi:include href="snapshot-throttling.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
</section>
|
||||
|
||||
@ -24,6 +24,7 @@ COMMIT
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD DROP [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:FW_OUTBOUND - [0:0]
|
||||
-A INPUT -d 224.0.0.18/32 -j ACCEPT
|
||||
-A INPUT -d 225.0.0.50/32 -j ACCEPT
|
||||
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
@ -37,10 +38,11 @@ COMMIT
|
||||
-A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT
|
||||
-A INPUT -i eth0 -p tcp -m state --state NEW --dport 80 -j ACCEPT
|
||||
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -i eth0 -o eth2 -j ACCEPT
|
||||
-A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -i eth0 -o eth0 -m state --state NEW -j ACCEPT
|
||||
-A FORWARD -i eth0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -i eth0 -o eth2 -j FW_OUTBOUND
|
||||
-I FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
COMMIT
|
||||
*mangle
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
|
||||
@ -212,9 +212,9 @@ add_first_ip() {
|
||||
ip_addr_add $ethDev $pubIp
|
||||
|
||||
sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo iptables -D FORWARD -i eth0 -o $ethDev -j ACCEPT
|
||||
sudo iptables -D FORWARD -i eth0 -o $ethDev -j FW_OUTBOUND
|
||||
sudo iptables -A FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo iptables -A FORWARD -i eth0 -o $ethDev -j ACCEPT
|
||||
sudo iptables -A FORWARD -i eth0 -o $ethDev -j FW_OUTBOUND
|
||||
|
||||
add_snat $1
|
||||
if [ $? -gt 0 -a $? -ne 2 ]
|
||||
@ -246,7 +246,7 @@ remove_first_ip() {
|
||||
[ "$mask" == "" ] && mask="32"
|
||||
|
||||
sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo iptables -D FORWARD -i eth0 -o $ethDev -j ACCEPT
|
||||
sudo iptables -D FORWARD -i eth0 -o $ethDev -j FW_OUTBOUND
|
||||
remove_snat $1
|
||||
|
||||
sudo ip addr del dev $ethDev "$ipNoMask/$mask"
|
||||
|
||||
171
patches/systemvm/debian/config/root/firewallRule_egress.sh
Executable file
171
patches/systemvm/debian/config/root/firewallRule_egress.sh
Executable file
@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env bash
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# $Id: firewallRule_egress.sh 9947 2013-01-17 19:34:24Z manuel $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/patches/xenserver/root/firewallRule_egress.sh $
|
||||
# firewallRule_egress.sh -- allow some ports / protocols from vm instances
|
||||
# @VERSION@
|
||||
|
||||
source /root/func.sh
|
||||
|
||||
lock="biglock"
|
||||
locked=$(getLockFile $lock)
|
||||
if [ "$locked" != "1" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
#set -x
|
||||
usage() {
|
||||
printf "Usage: %s: -a protocol:startport:endport:sourcecidrs> \n" $(basename $0) >&2
|
||||
printf "sourcecidrs format: cidr1-cidr2-cidr3-...\n"
|
||||
}
|
||||
|
||||
fw_egress_remove_backup() {
|
||||
sudo iptables -D FW_OUTBOUND -j _FW_EGRESS_RULES
|
||||
sudo iptables -F _FW_EGRESS_RULES
|
||||
sudo iptables -X _FW_EGRESS_RULES
|
||||
}
|
||||
|
||||
fw_egress_save() {
|
||||
sudo iptables -E FW_EGRESS_RULES _FW_EGRESS_RULES
|
||||
}
|
||||
|
||||
fw_egress_chain () {
|
||||
#supress errors 2>/dev/null
|
||||
fw_egress_remove_backup
|
||||
fw_egress_save
|
||||
sudo iptables -N FW_EGRESS_RULES
|
||||
sudo iptables -A FW_OUTBOUND -j FW_EGRESS_RULES
|
||||
}
|
||||
|
||||
fw_egress_backup_restore() {
|
||||
sudo iptables -A FW_OUTBOUND -j FW_EGRESS_RULES
|
||||
sudo iptables -E _FW_EGRESS_RULES FW_EGRESS_RULES
|
||||
fw_egress_remove_backup
|
||||
}
|
||||
|
||||
|
||||
fw_entry_for_egress() {
|
||||
local rule=$1
|
||||
|
||||
local prot=$(echo $rule | cut -d: -f2)
|
||||
local sport=$(echo $rule | cut -d: -f3)
|
||||
local eport=$(echo $rule | cut -d: -f4)
|
||||
local cidrs=$(echo $rule | cut -d: -f5 | sed 's/-/ /g')
|
||||
if [ "$sport" == "0" -a "$eport" == "0" ]
|
||||
then
|
||||
DPORT=""
|
||||
else
|
||||
DPORT="--dport $sport:$eport"
|
||||
fi
|
||||
logger -t cloud "$(basename $0): enter apply fw egress rules for guest $prot:$sport:$eport:$cidrs"
|
||||
|
||||
for lcidr in $cidrs
|
||||
do
|
||||
[ "$prot" == "reverted" ] && continue;
|
||||
if [ "$prot" == "icmp" ]
|
||||
then
|
||||
typecode="$sport/$eport"
|
||||
[ "$eport" == "-1" ] && typecode="$sport"
|
||||
[ "$sport" == "-1" ] && typecode="any"
|
||||
sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr --icmp-type $typecode \
|
||||
-j ACCEPT
|
||||
result=$?
|
||||
elif [ "$prot" == "all" ]
|
||||
then
|
||||
sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr -j ACCEPT
|
||||
result=$?
|
||||
else
|
||||
sudo iptables -A FW_EGRESS_RULES -p $prot -s $lcidr \
|
||||
$DPORT -j ACCEPT
|
||||
result=$?
|
||||
fi
|
||||
|
||||
[ $result -gt 0 ] &&
|
||||
logger -t cloud "Error adding iptables entry for guest network $prot:$sport:$eport:$cidrs" &&
|
||||
break
|
||||
done
|
||||
|
||||
logger -t cloud "$(basename $0): exit apply egress firewall rules for guest network"
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
aflag=0
|
||||
rules=""
|
||||
rules_list=""
|
||||
ip=""
|
||||
dev=""
|
||||
shift
|
||||
shift
|
||||
while getopts 'a:' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
a) aflag=1
|
||||
rules="$OPTARG"
|
||||
;;
|
||||
?) usage
|
||||
unlock_exit 2 $lock $locked
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$aflag" != "1" ]
|
||||
then
|
||||
usage
|
||||
unlock_exit 2 $lock $locked
|
||||
fi
|
||||
|
||||
if [ -n "$rules" ]
|
||||
then
|
||||
rules_list=$(echo $rules | cut -d, -f1- --output-delimiter=" ")
|
||||
fi
|
||||
|
||||
# rule format
|
||||
# protocal:sport:eport:cidr
|
||||
#-a tcp:80:80:0.0.0.0/0::tcp:220:220:0.0.0.0/0:,tcp:222:222:192.168.10.0/24-75.57.23.0/22-88.100.33.1/32
|
||||
# if any entry is reverted , entry will be in the format reverted:0:0:0
|
||||
# example : tcp:80:80:0.0.0.0/0:, tcp:220:220:0.0.0.0/0:,200.1.1.2:reverted:0:0:0
|
||||
|
||||
success=0
|
||||
|
||||
fw_egress_chain
|
||||
for r in $rules_list
|
||||
do
|
||||
fw_entry_for_egress $r
|
||||
success=$?
|
||||
if [ $success -gt 0 ]
|
||||
then
|
||||
logger -t cloud "failure to apply fw egress rules "
|
||||
break
|
||||
else
|
||||
logger -t cloud "successful in applying fw egress rules"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $success -gt 0 ]
|
||||
then
|
||||
logger -t cloud "restoring from backup for guest network"
|
||||
fw_egress_backup_restore
|
||||
else
|
||||
logger -t cloud "deleting backup for guest network"
|
||||
fi
|
||||
|
||||
fw_egress_remove_backup
|
||||
|
||||
unlock_exit $success $lock $locked
|
||||
|
||||
|
||||
@ -92,6 +92,12 @@ public class BaremetalUserdataElement extends AdapterBase implements NetworkElem
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String SSHPublicKey) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Service, Map<Capability, String>> getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@ -153,6 +153,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.DestroyCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.FirewallRuleTO;
|
||||
import com.cloud.agent.api.to.IpAddressTO;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||
@ -190,6 +191,7 @@ import com.cloud.network.HAProxyConfigurator;
|
||||
import com.cloud.network.LoadBalancerConfigurator;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.storage.Storage;
|
||||
@ -618,10 +620,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
|
||||
String controlIp = getRouterSshControlIp(cmd);
|
||||
String[] results = new String[cmd.getRules().length];
|
||||
FirewallRuleTO[] allrules = cmd.getRules();
|
||||
FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
|
||||
|
||||
String[][] rules = cmd.generateFwRules();
|
||||
String args = "";
|
||||
args += " -F ";
|
||||
if (trafficType == FirewallRule.TrafficType.Egress){
|
||||
args+= " -E ";
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String[] fwRules = rules[0];
|
||||
if (fwRules.length > 0) {
|
||||
@ -634,13 +642,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
try {
|
||||
VmwareManager mgr = getServiceContext().getStockObject(
|
||||
VmwareManager.CONTEXT_STOCK_NAME);
|
||||
Pair<Boolean, String> result = SshHelper.sshExecute(controlIp,
|
||||
|
||||
Pair<Boolean, String> result = null;
|
||||
|
||||
if (trafficType == FirewallRule.TrafficType.Egress){
|
||||
result = SshHelper.sshExecute(controlIp,
|
||||
DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
|
||||
null, "/root/firewallRule_egress.sh " + args);
|
||||
} else {
|
||||
result = SshHelper.sshExecute(controlIp,
|
||||
DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
|
||||
null, "/root/firewall_rule.sh " + args);
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled())
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
if (trafficType == FirewallRule.TrafficType.Egress){
|
||||
s_logger.debug("Executing script on domain router " + controlIp
|
||||
+ ": /root/firewallRule_egress.sh " + args);
|
||||
} else {
|
||||
s_logger.debug("Executing script on domain router " + controlIp
|
||||
+ ": /root/firewall_rule.sh " + args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.first()) {
|
||||
s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: "
|
||||
|
||||
@ -53,6 +53,8 @@ import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import com.cloud.agent.api.to.*;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
import org.w3c.dom.Document;
|
||||
@ -7182,14 +7184,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
String callResult;
|
||||
Connection conn = getConnection();
|
||||
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
|
||||
|
||||
FirewallRuleTO[] allrules = cmd.getRules();
|
||||
FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
|
||||
if (routerIp == null) {
|
||||
return new SetFirewallRulesAnswer(cmd, false, results);
|
||||
}
|
||||
|
||||
String[][] rules = cmd.generateFwRules();
|
||||
String args = "";
|
||||
args += routerIp + " -F ";
|
||||
args += routerIp + " -F";
|
||||
if (trafficType == FirewallRule.TrafficType.Egress){
|
||||
args+= " -E";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String[] fwRules = rules[0];
|
||||
if (fwRules.length > 0) {
|
||||
|
||||
@ -277,6 +277,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan
|
||||
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
|
||||
firewallCapabilities.put(Capability.MultipleIps, "true");
|
||||
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
|
||||
firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress");
|
||||
capabilities.put(Service.Firewall, firewallCapabilities);
|
||||
|
||||
// Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work
|
||||
|
||||
@ -46,28 +46,25 @@ then
|
||||
exit 1
|
||||
fi
|
||||
fflag=
|
||||
while getopts ':F' OPTION
|
||||
eflag=
|
||||
while getopts ':FE' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
F) fflag=1
|
||||
;;
|
||||
;;
|
||||
E) eflag=1
|
||||
;;
|
||||
\?) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$fflag" ]
|
||||
if [ -n "$eflag" ]
|
||||
then
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewallRule_egress.sh $*"
|
||||
elif [ -n "$fflag" ]
|
||||
then
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall_rule.sh $*"
|
||||
else
|
||||
ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall.sh $*"
|
||||
fi
|
||||
exit $?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2313,10 +2313,15 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
|
||||
List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
|
||||
response.setCidrList(StringUtils.join(cidrs, ","));
|
||||
|
||||
IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
|
||||
response.setPublicIpAddressId(ip.getId());
|
||||
response.setPublicIpAddress(ip.getAddress().addr());
|
||||
|
||||
if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) {
|
||||
IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
|
||||
response.setPublicIpAddressId(ip.getId());
|
||||
response.setPublicIpAddress(ip.getAddress().addr());
|
||||
} else if (fwRule.getTrafficType() == FirewallRule.TrafficType.Egress) {
|
||||
response.setPublicIpAddress(null);
|
||||
response.setNetworkId(fwRule.getNetworkId());
|
||||
}
|
||||
|
||||
FirewallRule.State state = fwRule.getState();
|
||||
String stateToSet = state.toString();
|
||||
|
||||
@ -402,13 +402,10 @@ public class ApiServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(" }");
|
||||
sb.append(", \"cloudstack-version\": \"");
|
||||
sb.append(ApiDBUtils.getVersion());
|
||||
sb.append("\" }");
|
||||
sb.append(" } }");
|
||||
} else {
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
||||
sb.append("<loginresponse cloudstack-version=\"" + ApiDBUtils.getVersion() + "\">");
|
||||
sb.append("<loginresponse cloud-stack-version=\"" + ApiDBUtils.getVersion() + "\">");
|
||||
sb.append("<timeout>" + inactiveInterval + "</timeout>");
|
||||
Enumeration attrNames = session.getAttributeNames();
|
||||
if (attrNames != null) {
|
||||
@ -435,13 +432,10 @@ public class ApiServlet extends HttpServlet {
|
||||
private String getLogoutSuccessResponse(String responseType) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
|
||||
sb.append("{ \"logoutresponse\" : { \"description\" : \"success\" }");
|
||||
sb.append(", \"cloudstack-version\": \"");
|
||||
sb.append(ApiDBUtils.getVersion());
|
||||
sb.append("\" }");
|
||||
sb.append("{ \"logoutresponse\" : { \"description\" : \"success\" } }");
|
||||
} else {
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
|
||||
sb.append("<logoutresponse cloudstack-version=\"" + ApiDBUtils.getVersion() + "\">");
|
||||
sb.append("<logoutresponse cloud-stack-version=\"" + ApiDBUtils.getVersion() + "\">");
|
||||
sb.append("<description>success</description>");
|
||||
sb.append("</logoutresponse>");
|
||||
}
|
||||
|
||||
@ -1893,23 +1893,23 @@ public class QueryManagerImpl implements QueryService, Manager {
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
sc.setParameters("name", SearchCriteria.Op.LIKE, "%" + name + "%");
|
||||
sc.setParameters("name", "%" + name + "%");
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
sc.setParameters("path", SearchCriteria.Op.EQ, path);
|
||||
sc.setParameters("path", path);
|
||||
}
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("dataCenterId", SearchCriteria.Op.EQ, zoneId);
|
||||
sc.setParameters("dataCenterId", zoneId);
|
||||
}
|
||||
if (pod != null) {
|
||||
sc.setParameters("podId", SearchCriteria.Op.EQ, pod);
|
||||
sc.setParameters("podId", pod);
|
||||
}
|
||||
if (address != null) {
|
||||
sc.setParameters("hostAddress", SearchCriteria.Op.EQ, address);
|
||||
sc.setParameters("hostAddress", address);
|
||||
}
|
||||
if (cluster != null) {
|
||||
sc.setParameters("clusterId", SearchCriteria.Op.EQ, cluster);
|
||||
sc.setParameters("clusterId", cluster);
|
||||
}
|
||||
|
||||
// search Pool details by ids
|
||||
|
||||
@ -122,9 +122,7 @@ public class ApiResponseSerializer {
|
||||
sb.append("{ }");
|
||||
}
|
||||
}
|
||||
sb.append(", \"cloudstack-version\": \"");
|
||||
sb.append(ApiDBUtils.getVersion());
|
||||
sb.append("\" }");
|
||||
sb.append(" }");
|
||||
return sb.toString();
|
||||
}
|
||||
return null;
|
||||
@ -133,7 +131,7 @@ public class ApiResponseSerializer {
|
||||
private static String toXMLSerializedString(ResponseObject result) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
sb.append("<").append(result.getResponseName()).append(" cloudstack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
|
||||
sb.append("<").append(result.getResponseName()).append(" cloud-stack-version=\"").append(ApiDBUtils.getVersion()).append("\">");
|
||||
|
||||
if (result instanceof ListResponse) {
|
||||
Integer count = ((ListResponse) result).getCount();
|
||||
|
||||
@ -144,6 +144,8 @@ public interface NetworkManager {
|
||||
|
||||
UserDataServiceProvider getPasswordResetProvider(Network network);
|
||||
|
||||
UserDataServiceProvider getSSHKeyResetProvider(Network network);
|
||||
|
||||
boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException;
|
||||
|
||||
boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List<? extends PublicIpAddress> publicIps) throws ResourceUnavailableException;
|
||||
@ -262,7 +264,7 @@ public interface NetworkManager {
|
||||
* @throws InsufficientCapacityException
|
||||
* @throws ResourceUnavailableException
|
||||
*/
|
||||
NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfileImpl<VMInstanceVO> vmProfile, boolean prepare) throws InsufficientVirtualNetworkCapcityException,
|
||||
NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare) throws InsufficientVirtualNetworkCapcityException,
|
||||
InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
|
||||
|
||||
|
||||
|
||||
@ -2285,20 +2285,23 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
|
||||
boolean success = true;
|
||||
Network network = _networksDao.findById(rules.get(0).getNetworkId());
|
||||
FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
|
||||
// get the list of public ip's owned by the network
|
||||
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
if (userIps != null && !userIps.isEmpty()) {
|
||||
for (IPAddressVO userIp : userIps) {
|
||||
if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
|
||||
// get the list of public ip's owned by the network
|
||||
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
if (userIps != null && !userIps.isEmpty()) {
|
||||
for (IPAddressVO userIp : userIps) {
|
||||
PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
|
||||
publicIps.add(publicIp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rules can not programmed unless IP is associated with network service provider, so run IP assoication for
|
||||
// the network so as to ensure IP is associated before applying rules (in add state)
|
||||
applyIpAssociations(network, false, continueOnError, publicIps);
|
||||
}
|
||||
|
||||
try {
|
||||
applier.applyRules(network, purpose, rules);
|
||||
@ -2310,8 +2313,10 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
success = false;
|
||||
}
|
||||
|
||||
// if all the rules configured on public IP are revoked then dis-associate IP with network service provider
|
||||
applyIpAssociations(network, true, continueOnError, publicIps);
|
||||
if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) ) {
|
||||
// if all the rules configured on public IP are revoked then dis-associate IP with network service provider
|
||||
applyIpAssociations(network, true, continueOnError, publicIps);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -2460,9 +2465,15 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
}
|
||||
|
||||
// apply firewall rules
|
||||
List<FirewallRuleVO> firewallRulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
|
||||
if (!_firewallMgr.applyFirewallRules(firewallRulesToApply, false, caller)) {
|
||||
s_logger.warn("Failed to reapply firewall rule(s) as a part of network id=" + networkId + " restart");
|
||||
List<FirewallRuleVO> firewallIngressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
|
||||
if (!_firewallMgr.applyFirewallRules(firewallIngressRulesToApply, false, caller)) {
|
||||
s_logger.warn("Failed to reapply Ingress firewall rule(s) as a part of network id=" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewallEgressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
|
||||
if (!_firewallMgr.applyFirewallRules(firewallEgressRulesToApply, false, caller)) {
|
||||
s_logger.warn("Failed to reapply firewall Egress rule(s) as a part of network id=" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
|
||||
@ -2626,6 +2637,18 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(passwordProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDataServiceProvider getSSHKeyResetProvider(Network network) {
|
||||
String SSHKeyProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
|
||||
|
||||
if (SSHKeyProvider == null) {
|
||||
s_logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
|
||||
return null;
|
||||
}
|
||||
|
||||
return (UserDataServiceProvider)_networkModel.getElementImplementingProvider(SSHKeyProvider);
|
||||
}
|
||||
|
||||
protected boolean isSharedNetworkOfferingWithServices(long networkOfferingId) {
|
||||
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
|
||||
if ( (networkOffering.getGuestType() == Network.GuestType.Shared) && (
|
||||
@ -3015,23 +3038,43 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
}
|
||||
|
||||
// revoke all firewall rules for the network w/o applying them on the DB
|
||||
List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
|
||||
List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Releasing " + firewallRules.size() + " firewall rules for network id=" + networkId + " as a part of shutdownNetworkRules");
|
||||
s_logger.debug("Releasing " + firewallRules.size() + " firewall ingress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
|
||||
}
|
||||
|
||||
for (FirewallRuleVO firewallRule : firewallRules) {
|
||||
s_logger.trace("Marking firewall rule " + firewallRule + " with Revoke state");
|
||||
s_logger.trace("Marking firewall ingress rule " + firewallRule + " with Revoke state");
|
||||
firewallRule.setState(FirewallRule.State.Revoke);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!_firewallMgr.applyRules(firewallRules, true, false)) {
|
||||
s_logger.warn("Failed to cleanup firewall rules as a part of shutdownNetworkRules");
|
||||
s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules");
|
||||
success = false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to cleanup firewall rules as a part of shutdownNetworkRules due to ", ex);
|
||||
s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules due to ", ex);
|
||||
success = false;
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> firewallEgressRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Releasing " + firewallEgressRules.size() + " firewall egress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
|
||||
}
|
||||
|
||||
for (FirewallRuleVO firewallRule : firewallEgressRules) {
|
||||
s_logger.trace("Marking firewall egress rule " + firewallRule + " with Revoke state");
|
||||
firewallRule.setState(FirewallRule.State.Revoke);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!_firewallMgr.applyRules(firewallEgressRules, true, false)) {
|
||||
s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules");
|
||||
success = false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules due to ", ex);
|
||||
success = false;
|
||||
}
|
||||
|
||||
@ -3355,20 +3398,19 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfileImpl<VMInstanceVO> vmProfile, boolean prepare)
|
||||
public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context, VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
|
||||
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
|
||||
ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
|
||||
|
||||
VirtualMachine vm = vmProfile.getVirtualMachine();
|
||||
NetworkVO networkVO = _networksDao.findById(network.getId());
|
||||
DataCenter dc = _configMgr.getZone(network.getDataCenterId());
|
||||
Host host = _hostDao.findById(vm.getHostId());
|
||||
DeployDestination dest = new DeployDestination(dc, null, null, host);
|
||||
|
||||
NicProfile nic = getNicProfileForVm(network, requested, vm);
|
||||
|
||||
//1) allocate nic (if needed)
|
||||
if (nic == null) {
|
||||
//1) allocate nic (if needed) Always allocate if it is a user vm
|
||||
if (nic == null || (vmProfile.getType() == VirtualMachine.Type.User)) {
|
||||
int deviceId = _nicDao.countNics(vm.getId());
|
||||
|
||||
nic = allocateNic(requested, network, false,
|
||||
@ -3383,6 +3425,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
|
||||
|
||||
//2) prepare nic
|
||||
if (prepare) {
|
||||
NetworkVO networkVO = _networksDao.findById(network.getId());
|
||||
nic = prepareNic(vmProfile, dest, context, nic.getId(), networkVO);
|
||||
s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network);
|
||||
}
|
||||
|
||||
@ -1692,6 +1692,9 @@ public class NetworkModelImpl implements NetworkModel, Manager{
|
||||
} else {
|
||||
nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId());
|
||||
}
|
||||
if (nic == null) {
|
||||
return null;
|
||||
}
|
||||
NetworkVO network = _networksDao.findById(networkId);
|
||||
Integer networkRate = getNetworkRate(network.getId(), vm.getId());
|
||||
|
||||
@ -1836,4 +1839,4 @@ public class NetworkModelImpl implements NetworkModel, Manager{
|
||||
return offering.isInline();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
|
||||
long countRulesByIpId(long sourceIpId);
|
||||
|
||||
List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType);
|
||||
|
||||
List<FirewallRuleVO> listByNetworkPurposeTrafficType(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType);
|
||||
|
||||
List<FirewallRuleVO> listByIpAndPurposeWithState(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
|
||||
AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
|
||||
AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ);
|
||||
AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
NotRevokedSearch = createSearchBuilder();
|
||||
@ -161,6 +162,20 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.Purpose purpose, TrafficType trafficType) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
if (purpose != null) {
|
||||
sc.setParameters("purpose", purpose);
|
||||
}
|
||||
sc.setParameters("trafficType", trafficType);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setStateToAdd(FirewallRuleVO rule) {
|
||||
SearchCriteria<FirewallRuleVO> sc = AllFieldsSearch.create();
|
||||
@ -275,10 +290,9 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, Purpose purpose, TrafficType trafficType) {
|
||||
SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
|
||||
public List<FirewallRuleVO> listByNetworkPurposeTrafficType(long networkId, Purpose purpose, TrafficType trafficType) {
|
||||
SearchCriteria<FirewallRuleVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
sc.setParameters("state", State.Revoke);
|
||||
|
||||
if (purpose != null) {
|
||||
sc.setParameters("purpose", purpose);
|
||||
@ -288,6 +302,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public boolean remove(Long id) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
|
||||
@ -251,6 +251,12 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String SSHPublicKey) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -565,6 +565,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
|
||||
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
|
||||
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
|
||||
firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all");
|
||||
firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
|
||||
firewallCapabilities.put(Capability.MultipleIps, "true");
|
||||
capabilities.put(Service.Firewall, firewallCapabilities);
|
||||
|
||||
@ -664,6 +666,24 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
return _routerMgr.savePasswordToRouter(network, nic, uservm, routers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String SSHPublicKey)
|
||||
throws ResourceUnavailableException {
|
||||
if (!canHandle(network, null)) {
|
||||
return false;
|
||||
}
|
||||
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
|
||||
if (routers == null || routers.isEmpty()) {
|
||||
s_logger.debug("Can't find virtual router element in network " + network.getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
VirtualMachineProfile<UserVm> uservm = (VirtualMachineProfile<UserVm>) vm;
|
||||
|
||||
return _routerMgr.saveSSHPublicKeyToRouter(network, nic, uservm, routers, SSHPublicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
|
||||
throws ResourceUnavailableException {
|
||||
@ -860,8 +880,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
|
||||
|
||||
// for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when
|
||||
// network.dns.basiczone.updates is set to "all"
|
||||
Long podId = dest.getPod().getId();
|
||||
if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) {
|
||||
Long podId = dest.getPod().getId();
|
||||
List<DomainRouterVO> allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(),
|
||||
podId, State.Running, Role.VIRTUAL_ROUTER);
|
||||
routers.addAll(allRunningRoutersOutsideThePod);
|
||||
|
||||
@ -29,6 +29,12 @@ import javax.naming.ConfigurationException;
|
||||
import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.mysql.jdbc.ConnectionPropertiesImpl;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd;
|
||||
import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
@ -43,8 +49,10 @@ import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IPAddressVO;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.NetworkRuleApplier;
|
||||
@ -166,32 +174,44 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
|
||||
public FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(),
|
||||
return createFirewallRule(null, caller, rule.getXid(), rule.getSourcePortStart(),
|
||||
rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(),
|
||||
rule.getIcmpType(), null, rule.getType(), rule.getNetworkId());
|
||||
rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType());
|
||||
}
|
||||
|
||||
public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
Long sourceIpAddressId = rule.getSourceIpAddressId();
|
||||
|
||||
return createFirewallRule(sourceIpAddressId, caller, rule.getXid(), rule.getSourcePortStart(),
|
||||
rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(),
|
||||
rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType());
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
|
||||
public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart,
|
||||
Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
|
||||
Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException {
|
||||
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
|
||||
// Validate ip address
|
||||
if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule; ip id=" + ipAddrId +
|
||||
" doesn't exist in the system");
|
||||
public FirewallRule createFirewallRule(Long ipAddrId, Account caller, String xId, Integer portStart,
|
||||
Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
|
||||
Long relatedRuleId, FirewallRule.FirewallRuleType type, Long networkId, FirewallRule.TrafficType trafficType) throws NetworkRuleConflictException {
|
||||
|
||||
IPAddressVO ipAddress = null;
|
||||
if (ipAddrId != null){
|
||||
// this for ingress firewall rule, for egress id is null
|
||||
ipAddress = _ipAddressDao.findById(ipAddrId);
|
||||
// Validate ip address
|
||||
if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule; " +
|
||||
"couldn't locate IP address by id in the system");
|
||||
}
|
||||
_networkModel.checkIpForService(ipAddress, Service.Firewall, null);
|
||||
}
|
||||
|
||||
_networkModel.checkIpForService(ipAddress, Service.Firewall, null);
|
||||
|
||||
validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type);
|
||||
|
||||
|
||||
validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type, networkId, trafficType);
|
||||
|
||||
// icmp code and icmp type can't be passed in for any other protocol rather than icmp
|
||||
if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
|
||||
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
|
||||
@ -205,15 +225,21 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
Long domainId = null;
|
||||
|
||||
if (ipAddress != null) {
|
||||
//Ingress firewall rule
|
||||
accountId = ipAddress.getAllocatedToAccountId();
|
||||
domainId = ipAddress.getAllocatedInDomainId();
|
||||
} else if (networkId != null) {
|
||||
//egress firewall rule
|
||||
Network network = _networkModel.getNetwork(networkId);
|
||||
accountId = network.getAccountId();
|
||||
domainId = network.getDomainId();
|
||||
}
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
|
||||
FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId,
|
||||
accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, null);
|
||||
accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, trafficType);
|
||||
newRule.setType(type);
|
||||
newRule = _firewallDao.persist(newRule);
|
||||
|
||||
@ -234,7 +260,9 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(ListFirewallRulesCmd cmd) {
|
||||
Long ipId = cmd.getIpAddressId();
|
||||
Long id = cmd.getId();
|
||||
Long networkId = null;
|
||||
Map<String, String> tags = cmd.getTags();
|
||||
FirewallRule.TrafficType trafficType = cmd.getTrafficType();
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
@ -258,7 +286,13 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
_accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
sb.and("id", sb.entity().getId(), Op.EQ);
|
||||
sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
|
||||
sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
|
||||
if (cmd instanceof ListEgressFirewallRulesCmd ) {
|
||||
networkId =((ListEgressFirewallRulesCmd)cmd).getNetworkId();
|
||||
sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
|
||||
} else {
|
||||
sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
|
||||
}
|
||||
sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
|
||||
|
||||
|
||||
@ -293,9 +327,14 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
|
||||
if (ipId != null) {
|
||||
sc.setParameters("ip", ipId);
|
||||
} else if (cmd instanceof ListEgressFirewallRulesCmd) {
|
||||
if (networkId != null) {
|
||||
sc.setParameters("networkId", networkId);
|
||||
}
|
||||
}
|
||||
|
||||
sc.setParameters("purpose", Purpose.Firewall);
|
||||
sc.setParameters("trafficType", trafficType);
|
||||
|
||||
Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
|
||||
return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
|
||||
@ -303,10 +342,17 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
|
||||
@Override
|
||||
public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
|
||||
List<FirewallRuleVO> rules;
|
||||
if(newRule.getSourceIpAddressId() != null){
|
||||
rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
|
||||
assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " +
|
||||
"network conflicts so we should at least have one rule at this point.";
|
||||
} else {
|
||||
// fetches only firewall egress rules.
|
||||
rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
|
||||
assert (rules.size() >= 1);
|
||||
}
|
||||
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
|
||||
assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " +
|
||||
"network conflicts so we should at least have one rule at this point.";
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
if (rule.getId() == newRule.getId()) {
|
||||
@ -394,7 +440,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
|
||||
@Override
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd,
|
||||
String proto, Purpose purpose, FirewallRuleType type) {
|
||||
String proto, Purpose purpose, FirewallRuleType type, Long networkId, FirewallRule.TrafficType trafficType ) {
|
||||
if (portStart != null && !NetUtils.isValidPort(portStart)) {
|
||||
throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
|
||||
}
|
||||
@ -411,38 +457,56 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate ip address
|
||||
_accountMgr.checkAccess(caller, null, true, ipAddress);
|
||||
|
||||
Long networkId = null;
|
||||
|
||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule ; ip id=" +
|
||||
ipAddress.getId() + " is not associated with any network");
|
||||
} else {
|
||||
networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
}
|
||||
|
||||
Network network = _networkModel.getNetwork(networkId);
|
||||
assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?";
|
||||
|
||||
// Verify that the network guru supports the protocol specified
|
||||
Map<Network.Capability, String> caps = null;
|
||||
|
||||
if (purpose == Purpose.LoadBalancing) {
|
||||
if (!_elbEnabled) {
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
|
||||
if (ipAddress!=null){
|
||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
|
||||
} else {
|
||||
networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
}
|
||||
} else if (purpose == Purpose.PortForwarding) {
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
|
||||
}
|
||||
|
||||
if (caps != null) {
|
||||
String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
|
||||
if (!supportedProtocols.contains(proto.toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
|
||||
} else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
|
||||
// Validate ip address
|
||||
_accountMgr.checkAccess(caller, null, true, ipAddress);
|
||||
|
||||
Network network = _networkModel.getNetwork(networkId);
|
||||
assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?";
|
||||
|
||||
if (trafficType == FirewallRule.TrafficType.Egress) {
|
||||
_accountMgr.checkAccess(caller, null, true, network);
|
||||
}
|
||||
|
||||
// Verify that the network guru supports the protocol specified
|
||||
Map<Network.Capability, String> caps = null;
|
||||
|
||||
if (purpose == Purpose.LoadBalancing) {
|
||||
if (!_elbEnabled) {
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
|
||||
}
|
||||
} else if (purpose == Purpose.PortForwarding) {
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
|
||||
}else if (purpose == Purpose.Firewall){
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(),Service.Firewall);
|
||||
}
|
||||
|
||||
if (caps != null) {
|
||||
String supportedProtocols;
|
||||
String supportedTrafficTypes = null;
|
||||
if (purpose == FirewallRule.Purpose.Firewall) {
|
||||
supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase();
|
||||
}
|
||||
|
||||
if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) {
|
||||
supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase();
|
||||
} else {
|
||||
supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
|
||||
}
|
||||
|
||||
if (!supportedProtocols.contains(proto.toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
|
||||
} else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
|
||||
} else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -536,11 +600,17 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
|
||||
public boolean applyIngressFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyEgressFirewallRules (FirewallRule rule, Account caller) throws ResourceUnavailableException {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
|
||||
|
||||
@ -588,10 +658,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
revokeRule(rule, caller, userId, false);
|
||||
|
||||
boolean success = false;
|
||||
Long networkId = rule.getNetworkId();
|
||||
|
||||
if (apply) {
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
// ingress firewall rule
|
||||
if (rule.getSourceIpAddressId() != null){
|
||||
//feteches ingress firewall, ingress firewall rules associated with the ip
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
//egress firewall rule
|
||||
} else if ( networkId != null){
|
||||
List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
|
||||
return applyFirewallRules(rules, false, caller);
|
||||
}
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
@ -686,7 +765,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
List<String> oneCidr = new ArrayList<String>();
|
||||
oneCidr.add(NetUtils.ALL_CIDRS);
|
||||
return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType,
|
||||
relatedRuleId, FirewallRule.FirewallRuleType.User, networkId);
|
||||
relatedRuleId, FirewallRule.FirewallRuleType.User, networkId, FirewallRule.TrafficType.Ingress);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -778,7 +857,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
for (Long ipId : ipsToReprogram) {
|
||||
s_logger.debug("Applying firewall rules for ip address id=" + ipId + " as a part of vm expunge");
|
||||
try {
|
||||
success = success && applyFirewallRules(ipId, _accountMgr.getSystemAccount());
|
||||
success = success && applyIngressFirewallRules(ipId, _accountMgr.getSystemAccount());
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId);
|
||||
success = false;
|
||||
@ -794,7 +873,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
|
||||
for (FirewallRuleVO rule : systemRules) {
|
||||
try {
|
||||
this.createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(),
|
||||
rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId());
|
||||
rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getTrafficType());
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
|
||||
}
|
||||
|
||||
@ -1054,9 +1054,6 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
|
||||
throw ex;
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(),
|
||||
Purpose.LoadBalancing, FirewallRuleType.User);
|
||||
|
||||
Long networkId = ipAddr.getAssociatedWithNetworkId();
|
||||
if (networkId == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network");
|
||||
@ -1064,6 +1061,10 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
|
||||
throw ex;
|
||||
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(),
|
||||
Purpose.LoadBalancing, FirewallRuleType.User, networkId, null);
|
||||
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
|
||||
_accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr);
|
||||
|
||||
@ -63,6 +63,9 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
|
||||
boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile<UserVm> profile,
|
||||
List<? extends VirtualRouter> routers) throws ResourceUnavailableException;
|
||||
|
||||
boolean saveSSHPublicKeyToRouter(Network network, NicProfile nic, VirtualMachineProfile<UserVm> profile,
|
||||
List<? extends VirtualRouter> routers, String SSHPublicKey) throws ResourceUnavailableException;
|
||||
|
||||
boolean saveUserDataToRouter(Network network, NicProfile nic, VirtualMachineProfile<UserVm> profile,
|
||||
List<? extends VirtualRouter> routers) throws ResourceUnavailableException;
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
|
||||
import com.cloud.agent.api.to.*;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -474,6 +474,28 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSSHPublicKeyToRouter(Network network, final NicProfile nic, VirtualMachineProfile<UserVm> profile, List<? extends VirtualRouter> routers, final String SSHPublicKey) throws ResourceUnavailableException {
|
||||
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
|
||||
|
||||
final VirtualMachineProfile<UserVm> updatedProfile = profile;
|
||||
|
||||
return applyRules(network, routers, "save SSHkey entry", false, null, false, new RuleApplier() {
|
||||
@Override
|
||||
public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException {
|
||||
// for basic zone, send vm data/password information only to the router in the same pod
|
||||
Commands cmds = new Commands(OnError.Stop);
|
||||
NicVO nicVo = _nicDao.findById(nic.getId());
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(updatedProfile.getTemplateId());
|
||||
if(template != null && template.getEnablePassword()) {
|
||||
createPasswordCommand(router, updatedProfile, nicVo, cmds);
|
||||
}
|
||||
createVmDataCommand(router, updatedProfile.getVirtualMachine(), nicVo, SSHPublicKey, cmds);
|
||||
return sendCommandsToRouter(router, cmds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUserDataToRouter(Network network, final NicProfile nic, VirtualMachineProfile<UserVm> profile, List<? extends VirtualRouter> routers) throws ResourceUnavailableException {
|
||||
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
|
||||
@ -2202,13 +2224,25 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
|
||||
|
||||
ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
|
||||
List<FirewallRule> firewallRulesEgress = new ArrayList<FirewallRule>();
|
||||
|
||||
// Fetch firewall Egress rules.
|
||||
if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
|
||||
firewallRulesEgress.addAll(_rulesDao.listByNetworkPurposeTrafficType(guestNetworkId, Purpose.Firewall,FirewallRule.TrafficType.Egress));
|
||||
}
|
||||
|
||||
// Re-apply firewall Egress rules
|
||||
s_logger.debug("Found " + firewallRulesEgress.size() + " firewall Egress rule(s) to apply as a part of domR " + router + " start.");
|
||||
if (!firewallRulesEgress.isEmpty()) {
|
||||
createFirewallRulesCommands(firewallRulesEgress, router, cmds, guestNetworkId);
|
||||
}
|
||||
|
||||
if (publicIps != null && !publicIps.isEmpty()) {
|
||||
List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
|
||||
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
|
||||
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
List<FirewallRule> firewallRules = new ArrayList<FirewallRule>();
|
||||
List<FirewallRule> firewallRulesIngress = new ArrayList<FirewallRule>();
|
||||
|
||||
//Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
|
||||
for (PublicIpAddress ip : publicIps) {
|
||||
@ -2219,7 +2253,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
|
||||
}
|
||||
if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
|
||||
firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
|
||||
firewallRulesIngress.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
|
||||
}
|
||||
|
||||
if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) {
|
||||
@ -2237,17 +2271,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Re-apply static nats
|
||||
|
||||
// Re-apply static nats
|
||||
s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
|
||||
if (!staticNats.isEmpty()) {
|
||||
createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId);
|
||||
}
|
||||
|
||||
//Re-apply firewall rules
|
||||
s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start.");
|
||||
if (!firewallRules.isEmpty()) {
|
||||
createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId);
|
||||
|
||||
// Re-apply firewall Ingress rules
|
||||
s_logger.debug("Found " + firewallRulesIngress.size() + " firewall Ingress rule(s) to apply as a part of domR " + router + " start.");
|
||||
if (!firewallRulesIngress.isEmpty()) {
|
||||
createFirewallRulesCommands(firewallRulesIngress, router, cmds, guestNetworkId);
|
||||
}
|
||||
|
||||
// Re-apply port forwarding rules
|
||||
@ -2904,7 +2938,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
int srcPort = rule.getSourcePortStart();
|
||||
List<LbDestination> destinations = rule.getDestinations();
|
||||
List<LbStickinessPolicy> stickinessPolicies = rule.getStickinessPolicies();
|
||||
LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, stickinessPolicies);
|
||||
LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies);
|
||||
lbs[i++] = lb;
|
||||
}
|
||||
String routerPublicIp = null;
|
||||
@ -3232,9 +3266,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
|
||||
if (rules != null) {
|
||||
rulesTO = new ArrayList<FirewallRuleTO>();
|
||||
for (FirewallRule rule : rules) {
|
||||
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
|
||||
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr());
|
||||
rulesTO.add(ruleTO);
|
||||
FirewallRule.TrafficType traffictype = rule.getTrafficType();
|
||||
if(traffictype == FirewallRule.TrafficType.Ingress){
|
||||
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
|
||||
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(),Purpose.Firewall,traffictype);
|
||||
rulesTO.add(ruleTO);
|
||||
}
|
||||
else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress){
|
||||
assert (rule.getSourceIpAddressId()==null) : "ipAddressId should be null for egress firewall rule. ";
|
||||
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null,"",Purpose.Firewall,traffictype);
|
||||
rulesTO.add(ruleTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ public interface FirewallManager extends FirewallService {
|
||||
void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException;
|
||||
|
||||
void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto,
|
||||
Purpose purpose, FirewallRuleType type);
|
||||
Purpose purpose, FirewallRuleType type, Long networkid, FirewallRule.TrafficType trafficType);
|
||||
|
||||
boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException;
|
||||
|
||||
@ -68,8 +68,8 @@ public interface FirewallManager extends FirewallService {
|
||||
*/
|
||||
boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId);
|
||||
|
||||
FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId,
|
||||
FirewallRule.FirewallRuleType type, long networkId)
|
||||
FirewallRule createFirewallRule(Long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId,
|
||||
FirewallRule.FirewallRuleType type, Long networkId, FirewallRule.TrafficType traffictype)
|
||||
throws NetworkRuleConflictException;
|
||||
|
||||
FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException;
|
||||
|
||||
@ -45,7 +45,7 @@ import org.apache.cloudstack.api.InternalIdentity;
|
||||
@Table(name="firewall_rules")
|
||||
@Inheritance(strategy=InheritanceType.JOINED)
|
||||
@DiscriminatorColumn(name="purpose", discriminatorType=DiscriminatorType.STRING, length=32)
|
||||
public class FirewallRuleVO implements FirewallRule {
|
||||
public class FirewallRuleVO implements Identity, FirewallRule {
|
||||
protected final FirewallRulesCidrsDaoImpl _firewallRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class);
|
||||
|
||||
@Id
|
||||
@ -87,8 +87,8 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
Date created;
|
||||
|
||||
@Column(name="network_id")
|
||||
long networkId;
|
||||
|
||||
Long networkId;
|
||||
|
||||
@Column(name="icmp_code")
|
||||
Integer icmpCode;
|
||||
|
||||
@ -209,11 +209,6 @@ public class FirewallRuleVO implements FirewallRule {
|
||||
}
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
|
||||
if (ipAddressId == null) {
|
||||
assert (purpose == Purpose.NetworkACL) : "ipAddressId can be null for " + Purpose.NetworkACL + " only";
|
||||
}
|
||||
|
||||
this.sourceIpAddressId = ipAddressId;
|
||||
this.sourcePortStart = portStart;
|
||||
this.sourcePortEnd = portEnd;
|
||||
|
||||
@ -204,7 +204,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
|
||||
try {
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(),
|
||||
rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User);
|
||||
rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User, networkId, rule.getTrafficType());
|
||||
|
||||
Long accountId = ipAddress.getAllocatedToAccountId();
|
||||
Long domainId = ipAddress.getAllocatedInDomainId();
|
||||
@ -323,7 +323,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
||||
throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
|
||||
}
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User);
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User,null, rule.getTrafficType() );
|
||||
|
||||
Long networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
Long accountId = ipAddress.getAllocatedToAccountId();
|
||||
|
||||
@ -269,7 +269,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
|
||||
//now apply vpn rules on the backend
|
||||
s_logger.debug("Reapplying firewall rules for ip id=" + ipId + " as a part of disable remote access vpn");
|
||||
success = _firewallMgr.applyFirewallRules(ipId, caller);
|
||||
success = _firewallMgr.applyIngressFirewallRules(ipId, caller);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
@ -383,7 +383,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
|
||||
try {
|
||||
boolean firewallOpened = true;
|
||||
if (openFirewall) {
|
||||
firewallOpened = _firewallMgr.applyFirewallRules(vpn.getServerAddressId(), caller);
|
||||
firewallOpened = _firewallMgr.applyIngressFirewallRules(vpn.getServerAddressId(), caller);
|
||||
}
|
||||
|
||||
if (firewallOpened) {
|
||||
|
||||
@ -1513,10 +1513,11 @@ public class ManagementServerImpl implements ManagementServer {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
_accountMgr.checkAccess(caller, domain);
|
||||
|
||||
// domain name is unique in the cloud
|
||||
// domain name is unique under the parent domain
|
||||
if (domainName != null) {
|
||||
SearchCriteria<DomainVO> sc = _domainDao.createSearchCriteria();
|
||||
sc.addAnd("name", SearchCriteria.Op.EQ, domainName);
|
||||
sc.addAnd("parent", SearchCriteria.Op.EQ, domain.getParent());
|
||||
List<DomainVO> domains = _domainDao.search(sc, null);
|
||||
|
||||
boolean sameDomain = (domains.size() == 1 && domains.get(0).getId() == domainId);
|
||||
|
||||
@ -22,12 +22,22 @@ import com.cloud.utils.script.Script;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* @author htrippaers
|
||||
*
|
||||
*/
|
||||
public class Upgrade40to41 implements DbUpgrade {
|
||||
final static Logger s_logger = Logger.getLogger(Upgrade40to41.class);
|
||||
|
||||
/**
|
||||
*
|
||||
@ -78,7 +88,8 @@ public class Upgrade40to41 implements DbUpgrade {
|
||||
*/
|
||||
@Override
|
||||
public void performDataMigration(Connection conn) {
|
||||
|
||||
upgradeEIPNetworkOfferings(conn);
|
||||
upgradeEgressFirewallRules(conn);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -89,4 +100,104 @@ public class Upgrade40to41 implements DbUpgrade {
|
||||
return new File[0];
|
||||
}
|
||||
|
||||
private void upgradeEIPNetworkOfferings(Connection conn) {
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
pstmt = conn.prepareStatement("select id, elastic_ip_service from `cloud`.`network_offerings` where traffic_type='Guest'");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong(1);
|
||||
// check if elastic IP service is enabled for network offering
|
||||
if (rs.getLong(2) != 0) {
|
||||
//update network offering with eip_associate_public_ip set to true
|
||||
pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings` set eip_associate_public_ip=? where id=?");
|
||||
pstmt.setBoolean(1, true);
|
||||
pstmt.setLong(2, id);
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to set elastic_ip_service for network offerings with EIP service enabled.", e);
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void upgradeEgressFirewallRules(Connection conn) {
|
||||
PreparedStatement pstmt = null;
|
||||
ResultSet rs = null;
|
||||
ResultSet rsId = null;
|
||||
ResultSet rsNw = null;
|
||||
try {
|
||||
// update the existing ingress rules traffic type
|
||||
pstmt = conn.prepareStatement("update `cloud`.`firewall_rules` set traffic_type='Ingress' where purpose='Firewall' and ip_address_id is not null and traffic_type is null");
|
||||
s_logger.debug("Updating firewall Ingress rule traffic type: " + pstmt);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("select network_id FROM `cloud`.`ntwk_service_map` where service='Firewall' and provider='VirtualRouter' ");
|
||||
rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
long netId = rs.getLong(1);
|
||||
//When upgraded from 2.2.14 to 3.0.6 guest_type is updated to Isolated in the 2214to30 clean up sql. clean up executes
|
||||
//after this. So checking for Isolated OR Virtual
|
||||
pstmt = conn.prepareStatement("select account_id, domain_id FROM `cloud`.`networks` where (guest_type='Isolated' OR guest_type='Virtual') and traffic_type='Guest' and vpc_id is NULL and (state='implemented' OR state='Shutdown') and id=? ");
|
||||
pstmt.setLong(1, netId);
|
||||
s_logger.debug("Getting account_id, domain_id from networks table: " + pstmt);
|
||||
rsNw = pstmt.executeQuery();
|
||||
|
||||
if(rsNw.next()) {
|
||||
long accountId = rsNw.getLong(1);
|
||||
long domainId = rsNw.getLong(2);
|
||||
|
||||
//Add new rule for the existing networks
|
||||
s_logger.debug("Adding default egress firewall rule for network " + netId);
|
||||
pstmt = conn.prepareStatement("INSERT INTO firewall_rules (uuid, state, protocol, purpose, account_id, domain_id, network_id, xid, created, traffic_type) VALUES (?, 'Active', 'all', 'Firewall', ?, ?, ?, ?, now(), 'Egress')");
|
||||
pstmt.setString(1, UUID.randomUUID().toString());
|
||||
pstmt.setLong(2, accountId);
|
||||
pstmt.setLong(3, domainId);
|
||||
pstmt.setLong(4, netId);
|
||||
pstmt.setString(5, UUID.randomUUID().toString());
|
||||
s_logger.debug("Inserting default egress firewall rule " + pstmt);
|
||||
pstmt.executeUpdate();
|
||||
|
||||
pstmt = conn.prepareStatement("select id from firewall_rules where protocol='all' and network_id=?");
|
||||
pstmt.setLong(1, netId);
|
||||
rsId = pstmt.executeQuery();
|
||||
|
||||
long firewallRuleId;
|
||||
if(rsId.next()) {
|
||||
firewallRuleId = rsId.getLong(1);
|
||||
pstmt = conn.prepareStatement("insert into firewall_rules_cidrs (firewall_rule_id,source_cidr) values (?, '0.0.0.0/0')");
|
||||
pstmt.setLong(1, firewallRuleId);
|
||||
s_logger.debug("Inserting rule for cidr 0.0.0.0/0 for the new Firewall rule id=" + firewallRuleId + " with statement " + pstmt);
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to set egress firewall rules ", e);
|
||||
} finally {
|
||||
try {
|
||||
if (rs != null) {
|
||||
rs.close();
|
||||
}
|
||||
if (pstmt != null) {
|
||||
pstmt.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,11 +17,16 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.AgentManager.OnError;
|
||||
import com.cloud.agent.api.*;
|
||||
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.agent.api.PlugNicAnswer;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.UnPlugNicAnswer;
|
||||
import com.cloud.agent.api.UnPlugNicCommand;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
@ -401,6 +406,116 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_RESETSSHKEY, eventDescription = "resetting Vm SSHKey", async = true)
|
||||
public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd)
|
||||
throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
|
||||
Account caller = UserContext.current().getCaller();
|
||||
Account owner = _accountMgr.finalizeOwner(caller, cmd.getAccountName(), cmd.getDomainId(), cmd.getProjectId());
|
||||
Long vmId = cmd.getId();
|
||||
|
||||
UserVmVO userVm = _vmDao.findById(cmd.getId());
|
||||
_vmDao.loadDetails(userVm);
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(userVm.getTemplateId());
|
||||
|
||||
// Do parameters input validation
|
||||
|
||||
if (userVm == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine by id" + cmd.getId());
|
||||
}
|
||||
|
||||
if (userVm.getState() == State.Error || userVm.getState() == State.Expunging) {
|
||||
s_logger.error("vm is not in the right state: " + vmId);
|
||||
throw new InvalidParameterValueException("Vm with specified id is not in the right state");
|
||||
}
|
||||
if (userVm.getState() != State.Stopped) {
|
||||
s_logger.error("vm is not in the right state: " + vmId);
|
||||
throw new InvalidParameterValueException("Vm " + userVm + " should be stopped to do SSH Key reset");
|
||||
}
|
||||
|
||||
SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName());
|
||||
if (s == null) {
|
||||
throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist for account " + owner.getAccountName() + " in specified domain id");
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, userVm);
|
||||
String password = null;
|
||||
String sshPublicKey = s.getPublicKey();
|
||||
if (template != null && template.getEnablePassword()) {
|
||||
password = generateRandomPassword();
|
||||
}
|
||||
|
||||
boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password);
|
||||
|
||||
if (result) {
|
||||
userVm.setDetail("SSH.PublicKey", sshPublicKey);
|
||||
if (template != null && template.getEnablePassword()) {
|
||||
userVm.setPassword(password);
|
||||
//update the encrypted password in vm_details table too
|
||||
if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
|
||||
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
|
||||
if (encryptedPasswd == null) {
|
||||
throw new CloudRuntimeException("Error encrypting password");
|
||||
}
|
||||
userVm.setDetail("Encrypted.Password", encryptedPasswd);
|
||||
}
|
||||
}
|
||||
_vmDao.saveDetails(userVm);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to reset SSH Key for the virtual machine ");
|
||||
}
|
||||
return userVm;
|
||||
}
|
||||
|
||||
private boolean resetVMSSHKeyInternal(Long vmId, String SSHPublicKey, String password) throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
Long userId = UserContext.current().getCallerUserId();
|
||||
VMInstanceVO vmInstance = _vmDao.findById(vmId);
|
||||
|
||||
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(vmInstance.getTemplateId());
|
||||
Nic defaultNic = _networkModel.getDefaultNic(vmId);
|
||||
if (defaultNic == null) {
|
||||
s_logger.error("Unable to reset SSH Key for vm " + vmInstance + " as the instance doesn't have default nic");
|
||||
return false;
|
||||
}
|
||||
|
||||
Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
|
||||
NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null,
|
||||
_networkModel.isSecurityGroupSupportedInNetwork(defaultNetwork),
|
||||
_networkModel.getNetworkTag(template.getHypervisorType(), defaultNetwork));
|
||||
|
||||
VirtualMachineProfile<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vmInstance);
|
||||
|
||||
if (template != null && template.getEnablePassword()) {
|
||||
vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
|
||||
}
|
||||
|
||||
UserDataServiceProvider element = _networkMgr.getSSHKeyResetProvider(defaultNetwork);
|
||||
if (element == null) {
|
||||
throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for SSH Key reset");
|
||||
}
|
||||
boolean result = element.saveSSHKey(defaultNetwork, defaultNicProfile, vmProfile, SSHPublicKey);
|
||||
|
||||
// Need to reboot the virtual machine so that the password gets redownloaded from the DomR, and reset on the VM
|
||||
if (!result) {
|
||||
s_logger.debug("Failed to reset SSH Key for the virutal machine; no need to reboot the vm");
|
||||
return false;
|
||||
} else {
|
||||
if (vmInstance.getState() == State.Stopped) {
|
||||
s_logger.debug("Vm " + vmInstance + " is stopped, not rebooting it as a part of SSH Key reset");
|
||||
return true;
|
||||
}
|
||||
if (rebootVirtualMachine(userId, vmId) == null) {
|
||||
s_logger.warn("Failed to reboot the vm " + vmInstance);
|
||||
return false;
|
||||
} else {
|
||||
s_logger.debug("Vm " + vmInstance + " is rebooted successfully as a part of SSH Key reset");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean stopVirtualMachine(long userId, long vmId) {
|
||||
boolean status = false;
|
||||
@ -916,6 +1031,237 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
||||
Long vmId = cmd.getVmId();
|
||||
Long networkId = cmd.getNetworkId();
|
||||
String ipAddress = cmd.getIpAddress();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
UserVmVO vmInstance = _vmDao.findById(vmId);
|
||||
if(vmInstance == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
NetworkVO network = _networkDao.findById(networkId);
|
||||
if(network == null) {
|
||||
throw new InvalidParameterValueException("unable to find a network with id " + networkId);
|
||||
}
|
||||
NicProfile profile = new NicProfile(null);
|
||||
if(ipAddress != null) {
|
||||
profile = new NicProfile(ipAddress);
|
||||
}
|
||||
|
||||
// Perform permission check on VM
|
||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||
|
||||
// Verify that zone is not Basic
|
||||
DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
|
||||
if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
|
||||
throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't add a new NIC to a VM on a Basic Network");
|
||||
}
|
||||
|
||||
// Perform account permission check on network
|
||||
if (network.getGuestType() != Network.GuestType.Shared) {
|
||||
// Check account permissions
|
||||
List<NetworkVO> networkMap = _networkDao.listBy(caller.getId(), network.getId());
|
||||
if ((networkMap == null || networkMap.isEmpty() ) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
|
||||
throw new PermissionDeniedException("Unable to modify a vm using network with id " + network.getId() + ", permission denied");
|
||||
}
|
||||
}
|
||||
|
||||
//ensure network belongs in zone
|
||||
if (network.getDataCenterId() != vmInstance.getDataCenterIdToDeployIn()) {
|
||||
throw new CloudRuntimeException(vmInstance + " is in zone:" + vmInstance.getDataCenterIdToDeployIn() + " but " + network + " is in zone:" + network.getDataCenterId());
|
||||
}
|
||||
|
||||
if(_networkModel.getNicInNetwork(vmInstance.getId(),network.getId()) != null){
|
||||
s_logger.debug(vmInstance + " already in " + network + " going to add another NIC");
|
||||
} else {
|
||||
//* get all vms hostNames in the network
|
||||
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(network.getId());
|
||||
//* verify that there are no duplicates
|
||||
if (hostNames.contains(vmInstance.getHostName())) {
|
||||
throw new CloudRuntimeException(network + " already has a vm with host name: '" + vmInstance.getHostName());
|
||||
}
|
||||
}
|
||||
|
||||
NicProfile guestNic = null;
|
||||
|
||||
try {
|
||||
guestNic = _itMgr.addVmToNetwork(vmInstance, network, profile);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
throw new CloudRuntimeException("Unable to add NIC to " + vmInstance + ": " + e);
|
||||
} catch (InsufficientCapacityException e) {
|
||||
throw new CloudRuntimeException("Insufficient capacity when adding NIC to " + vmInstance + ": " + e);
|
||||
} catch (ConcurrentOperationException e) {
|
||||
throw new CloudRuntimeException("Concurrent operations on adding NIC to " + vmInstance + ": " +e);
|
||||
}
|
||||
if (guestNic == null) {
|
||||
throw new CloudRuntimeException("Unable to add NIC to " + vmInstance);
|
||||
}
|
||||
|
||||
s_logger.debug("Successful addition of " + network + " from " + vmInstance);
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
||||
Long vmId = cmd.getVmId();
|
||||
Long nicId = cmd.getNicId();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
UserVmVO vmInstance = _vmDao.findById(vmId);
|
||||
if(vmInstance == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
if (nic == null){
|
||||
throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
|
||||
}
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
if(network == null) {
|
||||
throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId());
|
||||
}
|
||||
|
||||
// Perform permission check on VM
|
||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||
|
||||
// Verify that zone is not Basic
|
||||
DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
|
||||
if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
|
||||
throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't remove a NIC from a VM on a Basic Network");
|
||||
}
|
||||
|
||||
//check to see if nic is attached to VM
|
||||
if (nic.getInstanceId() != vmId) {
|
||||
throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance);
|
||||
}
|
||||
|
||||
// Perform account permission check on network
|
||||
if (network.getGuestType() != Network.GuestType.Shared) {
|
||||
// Check account permissions
|
||||
List<NetworkVO> networkMap = _networkDao.listBy(caller.getId(), network.getId());
|
||||
if ((networkMap == null || networkMap.isEmpty() ) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
|
||||
throw new PermissionDeniedException("Unable to modify a vm using network with id " + network.getId() + ", permission denied");
|
||||
}
|
||||
}
|
||||
|
||||
boolean nicremoved = false;
|
||||
|
||||
try {
|
||||
nicremoved = _itMgr.removeNicFromVm(vmInstance, nic);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance +": " + e);
|
||||
|
||||
} catch (ConcurrentOperationException e) {
|
||||
throw new CloudRuntimeException("Concurrent operations on removing " + network + " from " + vmInstance + ": " + e);
|
||||
}
|
||||
|
||||
if (!nicremoved) {
|
||||
throw new CloudRuntimeException("Unable to remove " + network + " from " + vmInstance );
|
||||
}
|
||||
|
||||
s_logger.debug("Successful removal of " + network + " from " + vmInstance);
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) throws InvalidParameterValueException, CloudRuntimeException {
|
||||
Long vmId = cmd.getVmId();
|
||||
Long nicId = cmd.getNicId();
|
||||
Account caller = UserContext.current().getCaller();
|
||||
|
||||
UserVmVO vmInstance = _vmDao.findById(vmId);
|
||||
if (vmInstance == null){
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
NicVO nic = _nicDao.findById(nicId);
|
||||
if (nic == null){
|
||||
throw new InvalidParameterValueException("unable to find a nic with id " + nicId);
|
||||
}
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
if (network == null){
|
||||
throw new InvalidParameterValueException("unable to find a network with id " + nic.getNetworkId());
|
||||
}
|
||||
|
||||
// Perform permission check on VM
|
||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||
|
||||
// Verify that zone is not Basic
|
||||
DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
|
||||
if (dc.getNetworkType() == DataCenter.NetworkType.Basic) {
|
||||
throw new CloudRuntimeException("Zone " + vmInstance.getDataCenterIdToDeployIn() + ", has a NetworkType of Basic. Can't change default NIC on a Basic Network");
|
||||
}
|
||||
|
||||
// no need to check permissions for network, we'll enumerate the ones they already have access to
|
||||
Network existingdefaultnet = _networkModel.getDefaultNetworkForVm(vmId);
|
||||
|
||||
//check to see if nic is attached to VM
|
||||
if (nic.getInstanceId() != vmId) {
|
||||
throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance);
|
||||
}
|
||||
// if current default equals chosen new default, Throw an exception
|
||||
if (nic.isDefaultNic()){
|
||||
throw new CloudRuntimeException("refusing to set default nic because chosen nic is already the default");
|
||||
}
|
||||
|
||||
//make sure the VM is Running or Stopped
|
||||
if ((vmInstance.getState() != State.Running) && (vmInstance.getState() != State.Stopped)) {
|
||||
throw new CloudRuntimeException("refusing to set default " + vmInstance + " is not Running or Stopped");
|
||||
}
|
||||
|
||||
NicProfile existing = null;
|
||||
List<NicProfile> nicProfiles = _networkMgr.getNicProfiles(vmInstance);
|
||||
for (NicProfile nicProfile : nicProfiles) {
|
||||
if(nicProfile.isDefaultNic() && nicProfile.getNetworkId() == existingdefaultnet.getId()){
|
||||
existing = nicProfile;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing == null){
|
||||
s_logger.warn("Failed to update default nic, no nic profile found for existing default network");
|
||||
throw new CloudRuntimeException("Failed to find a nic profile for the existing default network. This is bad and probably means some sort of configuration corruption");
|
||||
}
|
||||
|
||||
NicVO existingVO = _nicDao.findById(existing.id);
|
||||
Integer chosenID = nic.getDeviceId();
|
||||
Integer existingID = existing.getDeviceId();
|
||||
|
||||
nic.setDefaultNic(true);
|
||||
nic.setDeviceId(existingID);
|
||||
existingVO.setDefaultNic(false);
|
||||
existingVO.setDeviceId(chosenID);
|
||||
|
||||
nic = _nicDao.persist(nic);
|
||||
existingVO = _nicDao.persist(existingVO);
|
||||
|
||||
Network newdefault = null;
|
||||
newdefault = _networkModel.getDefaultNetworkForVm(vmId);
|
||||
|
||||
if (newdefault == null){
|
||||
nic.setDefaultNic(false);
|
||||
nic.setDeviceId(chosenID);
|
||||
existingVO.setDefaultNic(true);
|
||||
existingVO.setDeviceId(existingID);
|
||||
|
||||
nic = _nicDao.persist(nic);
|
||||
existingVO = _nicDao.persist(existingVO);
|
||||
|
||||
newdefault = _networkModel.getDefaultNetworkForVm(vmId);
|
||||
if (newdefault.getId() == existingdefaultnet.getId()) {
|
||||
throw new CloudRuntimeException("Setting a default nic failed, and we had no default nic, but we were able to set it back to the original");
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to change default nic to " + nic + " and now we have no default");
|
||||
} else if (newdefault.getId() == nic.getNetworkId()) {
|
||||
s_logger.debug("successfully set default network to " + network + " for " + vmInstance);
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
}
|
||||
|
||||
throw new CloudRuntimeException("something strange happened, new default network(" + newdefault.getId() + ") is not null, and is not equal to the network(" + nic.getNetworkId() + ") of the chosen nic");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds) throws CloudRuntimeException {
|
||||
@ -1069,14 +1415,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
|
||||
String time = configs.get("expunge.interval");
|
||||
_expungeInterval = NumbersUtil.parseInt(time, 86400);
|
||||
if ( _expungeInterval < 600 ) {
|
||||
_expungeInterval = 600;
|
||||
}
|
||||
|
||||
time = configs.get("expunge.delay");
|
||||
_expungeDelay = NumbersUtil.parseInt(time, _expungeInterval);
|
||||
if ( _expungeDelay < 600 ) {
|
||||
_expungeDelay = 600;
|
||||
}
|
||||
|
||||
_executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
|
||||
|
||||
_itMgr.registerGuru(VirtualMachine.Type.User, this);
|
||||
@ -3671,16 +4013,58 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm,
|
||||
ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException,
|
||||
InsufficientCapacityException {
|
||||
//not supported
|
||||
throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType());
|
||||
UserVmVO vmVO = _vmDao.findById(vm.getId());
|
||||
if (vmVO.getState() == State.Running) {
|
||||
try {
|
||||
PlugNicCommand plugNicCmd = new PlugNicCommand(nic,vm.getName());
|
||||
Commands cmds = new Commands(OnError.Stop);
|
||||
cmds.addCommand("plugnic",plugNicCmd);
|
||||
_agentMgr.send(dest.getHost().getId(),cmds);
|
||||
PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class);
|
||||
if (!(plugNicAnswer != null && plugNicAnswer.getResult())) {
|
||||
s_logger.warn("Unable to plug nic for " + vmVO);
|
||||
return false;
|
||||
}
|
||||
} catch (OperationTimedoutException e) {
|
||||
throw new AgentUnavailableException("Unable to plug nic for " + vmVO + " in network " + network, dest.getHost().getId(), e);
|
||||
}
|
||||
} else if (vmVO.getState() == State.Stopped || vmVO.getState() == State.Stopping) {
|
||||
s_logger.warn(vmVO + " is Stopped, not sending PlugNicCommand. Currently " + vmVO.getState());
|
||||
} else {
|
||||
s_logger.warn("Unable to plug nic, " + vmVO + " is not in the right state " + vmVO.getState());
|
||||
throw new ResourceUnavailableException("Unable to plug nic on the backend," +
|
||||
vmVO + " is not in the right state", DataCenter.class, vmVO.getDataCenterIdToDeployIn());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm,
|
||||
ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
//not supported
|
||||
throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
|
||||
UserVmVO vmVO = _vmDao.findById(vm.getId());
|
||||
if (vmVO.getState() == State.Running) {
|
||||
try {
|
||||
UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(nic,vm.getName());
|
||||
Commands cmds = new Commands(OnError.Stop);
|
||||
cmds.addCommand("unplugnic",unplugNicCmd);
|
||||
_agentMgr.send(dest.getHost().getId(),cmds);
|
||||
UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class);
|
||||
if (!(unplugNicAnswer != null && unplugNicAnswer.getResult())) {
|
||||
s_logger.warn("Unable to unplug nic for " + vmVO);
|
||||
return false;
|
||||
}
|
||||
} catch (OperationTimedoutException e) {
|
||||
throw new AgentUnavailableException("Unable to unplug nic for " + vmVO + " in network " + network, dest.getHost().getId(), e);
|
||||
}
|
||||
} else if (vmVO.getState() == State.Stopped || vmVO.getState() == State.Stopping) {
|
||||
s_logger.warn(vmVO + " is Stopped, not sending UnPlugNicCommand. Currently " + vmVO.getState());
|
||||
} else {
|
||||
s_logger.warn("Unable to unplug nic, " + vmVO + " is not in the right state " + vmVO.getState());
|
||||
throw new ResourceUnavailableException("Unable to unplug nic on the backend," +
|
||||
vmVO + " is not in the right state", DataCenter.class, vmVO.getDataCenterIdToDeployIn());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -152,6 +152,15 @@ public interface VirtualMachineManager extends Manager {
|
||||
NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* @param vm
|
||||
* @param nic
|
||||
* @return
|
||||
* @throws ResourceUnavailableException
|
||||
* @throws ConcurrentOperationException
|
||||
*/
|
||||
boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* @param vm
|
||||
* @param network
|
||||
|
||||
@ -2462,7 +2462,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
||||
ResourceUnavailableException, InsufficientCapacityException {
|
||||
|
||||
s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
|
||||
VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
||||
VMInstanceVO vmVO;
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
vmVO = _userVmDao.findById(vm.getId());
|
||||
} else {
|
||||
vmVO = _vmDao.findById(vm.getId());
|
||||
}
|
||||
ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM),
|
||||
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM));
|
||||
|
||||
@ -2506,7 +2511,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) {
|
||||
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType);
|
||||
@ -2515,6 +2519,61 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
||||
return nicTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
||||
NetworkVO network = _networkDao.findById(nic.getNetworkId());
|
||||
ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM),
|
||||
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM));
|
||||
|
||||
VirtualMachineProfileImpl<VMInstanceVO> vmProfile = new VirtualMachineProfileImpl<VMInstanceVO>(vmVO, null,
|
||||
null, null, null);
|
||||
|
||||
DataCenter dc = _configMgr.getZone(network.getDataCenterId());
|
||||
Host host = _hostDao.findById(vm.getHostId());
|
||||
DeployDestination dest = new DeployDestination(dc, null, null, host);
|
||||
VirtualMachineGuru<VMInstanceVO> vmGuru = getVmGuru(vmVO);
|
||||
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType());
|
||||
VirtualMachineTO vmTO = hvGuru.implement(vmProfile);
|
||||
|
||||
// don't delete default NIC on a user VM
|
||||
if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User ) {
|
||||
s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
|
||||
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
|
||||
}
|
||||
|
||||
NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
|
||||
_networkModel.getNetworkRate(network.getId(), vm.getId()),
|
||||
_networkModel.isSecurityGroupSupportedInNetwork(network),
|
||||
_networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
|
||||
|
||||
//1) Unplug the nic
|
||||
if (vm.getState() == State.Running) {
|
||||
NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
|
||||
s_logger.debug("Un-plugging nic " + nic + " for vm " + vm + " from network " + network);
|
||||
boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest);
|
||||
if (result) {
|
||||
s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network );
|
||||
} else {
|
||||
s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
|
||||
return false;
|
||||
}
|
||||
} else if (vm.getState() != State.Stopped) {
|
||||
s_logger.warn("Unable to remove vm " + vm + " from network " + network);
|
||||
throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state",
|
||||
DataCenter.class, vm.getDataCenterIdToDeployIn());
|
||||
}
|
||||
|
||||
//2) Release the nic
|
||||
_networkMgr.releaseNic(vmProfile, nic);
|
||||
s_logger.debug("Successfully released nic " + nic + "for vm " + vm);
|
||||
|
||||
//3) Remove the nic
|
||||
_networkMgr.removeNic(vmProfile, nic);
|
||||
_nicsDao.expunge(nic.getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
||||
@ -2538,21 +2597,38 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
||||
} else {
|
||||
nic = _networkModel.getNicInNetwork(vm.getId(), network.getId());
|
||||
}
|
||||
|
||||
if (nic == null){
|
||||
s_logger.warn("Could not get a nic with " + network);
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't delete default NIC on a user VM
|
||||
if (nic.isDefaultNic() && vm.getType() == VirtualMachine.Type.User ) {
|
||||
s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
|
||||
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
|
||||
}
|
||||
|
||||
NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
|
||||
_networkModel.getNetworkRate(network.getId(), vm.getId()),
|
||||
_networkModel.isSecurityGroupSupportedInNetwork(network),
|
||||
_networkModel.getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network));
|
||||
|
||||
//1) Unplug the nic
|
||||
NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
|
||||
s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network);
|
||||
boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest);
|
||||
if (result) {
|
||||
s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network );
|
||||
} else {
|
||||
s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
|
||||
return false;
|
||||
if (vm.getState() == State.Running) {
|
||||
NicTO nicTO = toNicTO(nicProfile, vmProfile.getVirtualMachine().getHypervisorType());
|
||||
s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network);
|
||||
boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest);
|
||||
if (result) {
|
||||
s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network );
|
||||
} else {
|
||||
s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network);
|
||||
return false;
|
||||
}
|
||||
} else if (vm.getState() != State.Stopped) {
|
||||
s_logger.warn("Unable to remove vm " + vm + " from network " + network);
|
||||
throw new ResourceUnavailableException("Unable to remove vm " + vm + " from network, is not in the right state",
|
||||
DataCenter.class, vm.getDataCenterIdToDeployIn());
|
||||
}
|
||||
|
||||
//2) Release the nic
|
||||
@ -2561,7 +2637,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
||||
|
||||
//3) Remove the nic
|
||||
_networkMgr.removeNic(vmProfile, nic);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.FirewallRule.FirewallRuleType;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRule.TrafficType;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Manager;
|
||||
@ -63,13 +64,6 @@ public class MockFirewallManagerImpl implements FirewallManager,
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createFirewallRule(FirewallRule rule)
|
||||
throws NetworkRuleConflictException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(
|
||||
ListFirewallRulesCmd cmd) {
|
||||
@ -83,13 +77,6 @@ public class MockFirewallManagerImpl implements FirewallManager,
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyFirewallRules(long ipId, Account caller)
|
||||
throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule getFirewallRule(long ruleId) {
|
||||
// TODO Auto-generated method stub
|
||||
@ -109,14 +96,6 @@ public class MockFirewallManagerImpl implements FirewallManager,
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress,
|
||||
Integer portStart, Integer portEnd, String proto, Purpose purpose,
|
||||
FirewallRuleType type) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyRules(List<? extends FirewallRule> rules,
|
||||
boolean continueOnError, boolean updateRulesInDB)
|
||||
@ -153,16 +132,6 @@ public class MockFirewallManagerImpl implements FirewallManager,
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createFirewallRule(long ipAddrId, Account caller,
|
||||
String xId, Integer portStart, Integer portEnd, String protocol,
|
||||
List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
|
||||
Long relatedRuleId, FirewallRuleType type, long networkId)
|
||||
throws NetworkRuleConflictException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller,
|
||||
Integer startPort, Integer endPort, String protocol,
|
||||
@ -197,6 +166,52 @@ public class MockFirewallManagerImpl implements FirewallManager,
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createFirewallRule(Long ipAddrId, Account caller,
|
||||
String xId, Integer portStart, Integer portEnd, String protocol,
|
||||
List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
|
||||
Long relatedRuleId, FirewallRuleType type, Long networkId,
|
||||
TrafficType traffictype) throws NetworkRuleConflictException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateFirewallRule(Account caller, IPAddressVO ipAddress,
|
||||
Integer portStart, Integer portEnd, String proto, Purpose purpose,
|
||||
FirewallRuleType type, Long networkid, TrafficType trafficType) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyEgressFirewallRules(FirewallRule rule, Account caller)
|
||||
throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyIngressFirewallRules(long Ipid, Account caller)
|
||||
throws ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createEgressFirewallRule(FirewallRule rule)
|
||||
throws NetworkRuleConflictException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRule createIngressFirewallRule(FirewallRule rule)
|
||||
throws NetworkRuleConflictException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -417,17 +417,18 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public UserDataServiceProvider getPasswordResetProvider(Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UserDataServiceProvider getSSHKeyResetProvider(Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List<String> enabledServices) {
|
||||
// TODO Auto-generated method stub
|
||||
@ -733,7 +734,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS
|
||||
*/
|
||||
@Override
|
||||
public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context,
|
||||
VirtualMachineProfileImpl<VMInstanceVO> vmProfile, boolean prepare)
|
||||
VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
|
||||
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
|
||||
ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -55,6 +55,8 @@ import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.exception.VirtualMachineMigrationException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.network.Network;
|
||||
@ -69,6 +71,7 @@ import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Local(value = { UserVmManager.class, UserVmService.class })
|
||||
public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Manager {
|
||||
@ -245,6 +248,12 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Volume attachVolumeToVM(AttachVolumeCmd cmd) {
|
||||
// TODO Auto-generated method stub
|
||||
@ -276,6 +285,24 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, CloudRuntimeException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd) throws InvalidParameterValueException, CloudRuntimeException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -270,6 +270,15 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI)
|
||||
*/
|
||||
@Override
|
||||
public boolean removeNicFromVm(VirtualMachine vm, NicVO nic) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI)
|
||||
*/
|
||||
|
||||
@ -867,10 +867,6 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.network.NetworkManager#getPasswordResetProvider(com.cloud.network.Network)
|
||||
*/
|
||||
@ -880,8 +876,11 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public UserDataServiceProvider getSSHKeyResetProvider(Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -1123,11 +1122,11 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean)
|
||||
* @see com.cloud.network.NetworkManager#createNicForVm(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.ReservationContext, com.cloud.vm.VirtualMachineProfileImpl, boolean, boolean)
|
||||
*/
|
||||
@Override
|
||||
public NicProfile createNicForVm(Network network, NicProfile requested, ReservationContext context,
|
||||
VirtualMachineProfileImpl<VMInstanceVO> vmProfile, boolean prepare)
|
||||
VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean prepare)
|
||||
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
|
||||
ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -74,6 +74,11 @@ public class MockVpcVirtualNetworkApplianceManager implements VpcVirtualNetworkA
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveSSHPublicKeyToRouter(Network network, NicProfile nic, VirtualMachineProfile<UserVm> profile, List<? extends VirtualRouter> routers, String SSHPublicKey) throws ResourceUnavailableException {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.network.router.VirtualNetworkApplianceManager#saveUserDataToRouter(com.cloud.network.Network, com.cloud.vm.NicProfile, com.cloud.vm.VirtualMachineProfile, java.util.List)
|
||||
*/
|
||||
|
||||
351
test/integration/smoke/test_nic.py
Normal file
351
test/integration/smoke/test_nic.py
Normal file
@ -0,0 +1,351 @@
|
||||
# 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.
|
||||
""" NIC tests for VM """
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from marvin.integration.lib.utils import *
|
||||
from marvin.integration.lib.base import *
|
||||
from marvin.integration.lib.common import *
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
|
||||
class Services:
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"disk_offering":{
|
||||
"displaytext": "Small",
|
||||
"name": "Small",
|
||||
"disksize": 1
|
||||
},
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended in create account to
|
||||
# ensure unique username generated each time
|
||||
"password": "password",
|
||||
},
|
||||
# Create a small virtual machine instance with disk offering
|
||||
"small": {
|
||||
"displayname": "testserver",
|
||||
"username": "root", # VM creds for SSH
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"service_offerings": {
|
||||
"tiny": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 128, # In MBs
|
||||
},
|
||||
},
|
||||
"network_offering": {
|
||||
"name": 'Test Network offering',
|
||||
"displaytext": 'Test Network offering',
|
||||
"guestiptype": 'Isolated',
|
||||
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding',
|
||||
"traffictype": 'GUEST',
|
||||
"availability": 'Optional',
|
||||
"serviceProviderList" : {
|
||||
"Dhcp": 'VirtualRouter',
|
||||
"Dns": 'VirtualRouter',
|
||||
"SourceNat": 'VirtualRouter',
|
||||
"PortForwarding": 'VirtualRouter',
|
||||
},
|
||||
},
|
||||
"network": {
|
||||
"name": "Test Network",
|
||||
"displaytext": "Test Network",
|
||||
"acltype": "Account",
|
||||
},
|
||||
# ISO settings for Attach/Detach ISO tests
|
||||
"iso": {
|
||||
"displaytext": "Test ISO",
|
||||
"name": "testISO",
|
||||
"url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
|
||||
# Source URL where ISO is located
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
"mode": 'HTTP_DOWNLOAD', # Downloading existing ISO
|
||||
},
|
||||
"template": {
|
||||
"displaytext": "Cent OS Template",
|
||||
"name": "Cent OS Template",
|
||||
"passwordenabled": True,
|
||||
},
|
||||
"diskdevice": '/dev/xvdd',
|
||||
# Disk device where ISO is attached to instance
|
||||
"mount_dir": "/mnt/tmp",
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
#Migrate VM to hostid
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
# CentOS 5.3 (64-bit)
|
||||
}
|
||||
|
||||
class TestDeployVM(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.cleanup = []
|
||||
self.cleaning_up = 0
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
self.tearDown()
|
||||
sys.exit(0)
|
||||
|
||||
# assign the signal handler immediately
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
try:
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.services = Services().services
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
domain = get_domain(self.apiclient, self.services)
|
||||
zone = get_zone(self.apiclient, self.services)
|
||||
self.services['mode'] = zone.networktype
|
||||
|
||||
if self.services['mode'] != 'Advanced':
|
||||
self.debug("Cannot run this test with a basic zone, please use advanced!")
|
||||
return
|
||||
|
||||
#if local storage is enabled, alter the offerings to use localstorage
|
||||
#this step is needed for devcloud
|
||||
if zone.localstorageenabled == True:
|
||||
self.services["service_offerings"]["tiny"]["storagetype"] = 'local'
|
||||
|
||||
template = get_template(
|
||||
self.apiclient,
|
||||
zone.id,
|
||||
self.services["ostype"]
|
||||
)
|
||||
# Set Zones and disk offerings
|
||||
self.services["small"]["zoneid"] = zone.id
|
||||
self.services["small"]["template"] = template.id
|
||||
|
||||
self.services["iso"]["zoneid"] = zone.id
|
||||
self.services["network"]["zoneid"] = zone.id
|
||||
|
||||
# Create Account, VMs, NAT Rules etc
|
||||
self.account = Account.create(
|
||||
self.apiclient,
|
||||
self.services["account"],
|
||||
domainid=domain.id
|
||||
)
|
||||
self.cleanup.insert(0, self.account)
|
||||
|
||||
self.service_offering = ServiceOffering.create(
|
||||
self.apiclient,
|
||||
self.services["service_offerings"]["tiny"]
|
||||
)
|
||||
self.cleanup.insert(0, self.service_offering)
|
||||
|
||||
####################
|
||||
### Network offering
|
||||
self.network_offering = NetworkOffering.create(
|
||||
self.apiclient,
|
||||
self.services["network_offering"],
|
||||
)
|
||||
self.cleanup.insert(0, self.network_offering)
|
||||
self.network_offering.update(self.apiclient, state='Enabled') # Enable Network offering
|
||||
self.services["network"]["networkoffering"] = self.network_offering.id
|
||||
|
||||
################
|
||||
### Test Network
|
||||
self.test_network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
self.account.account.name,
|
||||
self.account.account.domainid,
|
||||
)
|
||||
self.cleanup.insert(0, self.test_network)
|
||||
except Exception as ex:
|
||||
self.debug("Exception during NIC test SETUP!: " + str(ex))
|
||||
self.assertEqual(True, False, "Exception during NIC test SETUP!: " + str(ex))
|
||||
|
||||
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
||||
def test_01_nic(self):
|
||||
if self.services['mode'] != 'Advanced':
|
||||
self.debug("Cannot run this test with a basic zone, please use advanced!")
|
||||
return
|
||||
try:
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
mode=self.services['mode']
|
||||
)
|
||||
self.cleanup.insert(0, self.virtual_machine)
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s" \
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_vm_response),
|
||||
0,
|
||||
"Check VM available in List Virtual Machines"
|
||||
)
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
|
||||
vm_response.id,
|
||||
self.virtual_machine.id,
|
||||
"Check virtual machine id in listVirtualMachines"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.name,
|
||||
self.virtual_machine.name,
|
||||
"Check virtual machine name in listVirtualMachines"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(vm_response.nic),
|
||||
1,
|
||||
"Verify we only start with one nic"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.nic[0].isdefault,
|
||||
True,
|
||||
"Verify initial adapter is set to default"
|
||||
)
|
||||
existing_nic_ip = vm_response.nic[0].ipaddress
|
||||
existing_nic_id = vm_response.nic[0].id
|
||||
|
||||
# 1. add a nic
|
||||
add_response = self.virtual_machine.add_nic(self.apiclient, self.test_network.id)
|
||||
|
||||
time.sleep(5)
|
||||
# now go get the vm list?
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(list_vm_response[0].nic),
|
||||
2,
|
||||
"Verify we have 2 NIC's now"
|
||||
)
|
||||
|
||||
new_nic_id = ""
|
||||
for nc in list_vm_response[0].nic:
|
||||
if nc.ipaddress != existing_nic_ip:
|
||||
new_nic_id = nc.id
|
||||
|
||||
self.virtual_machine.update_default_nic(self.apiclient, new_nic_id)
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
|
||||
# iterate as we don't know for sure what order our NIC's will be returned to us.
|
||||
for nc in list_vm_response[0].nic:
|
||||
if nc.ipaddress == existing_nic_ip:
|
||||
self.assertEqual(
|
||||
nc.isdefault,
|
||||
False,
|
||||
"Verify initial adapter is NOT set to default"
|
||||
)
|
||||
else:
|
||||
self.assertEqual(
|
||||
nc.isdefault,
|
||||
True,
|
||||
"Verify second adapter is set to default"
|
||||
)
|
||||
|
||||
sawException = False
|
||||
try:
|
||||
self.virtual_machine.remove_nic(self.apiclient, new_nic_id)
|
||||
except Exception as ex:
|
||||
sawException = True
|
||||
|
||||
self.assertEqual(sawException, True, "Make sure we cannot delete the default NIC")
|
||||
|
||||
self.virtual_machine.remove_nic(self.apiclient, existing_nic_id)
|
||||
time.sleep(5)
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(list_vm_response[0].nic),
|
||||
1,
|
||||
"Verify we are back to a signle NIC"
|
||||
)
|
||||
|
||||
return
|
||||
except Exception as ex:
|
||||
self.debug("Exception during NIC test!: " + str(ex))
|
||||
self.assertEqual(True, False, "Exception during NIC test!: " + str(ex))
|
||||
|
||||
def tearDown(self):
|
||||
if self.services['mode'] != 'Advanced':
|
||||
self.debug("Cannot run this test with a basic zone, please use advanced!")
|
||||
return
|
||||
|
||||
if self.cleaning_up == 1:
|
||||
return
|
||||
|
||||
self.cleaning_up = 1
|
||||
try:
|
||||
for obj in self.cleanup:
|
||||
try:
|
||||
obj.delete(self.apiclient)
|
||||
time.sleep(10)
|
||||
except Exception as ex:
|
||||
self.debug("Error deleting: " + str(obj) + ", exception: " + str(ex))
|
||||
|
||||
except Exception as e:
|
||||
self.debug("Warning! Exception in tearDown: %s" % e)
|
||||
self.cleaning_up = 0
|
||||
|
||||
@ -389,6 +389,27 @@ class VirtualMachine:
|
||||
cmd.id = volume.id
|
||||
return apiclient.detachVolume(cmd)
|
||||
|
||||
def add_nic(self, apiclient, networkId):
|
||||
"""Add a NIC to a VM"""
|
||||
cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd();
|
||||
cmd.virtualmachineid = self.id
|
||||
cmd.networkid = networkId
|
||||
return apiclient.addNicToVirtualMachine(cmd)
|
||||
|
||||
def remove_nic(self, apiclient, nicId):
|
||||
"""Remove a NIC to a VM"""
|
||||
cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd()
|
||||
cmd.nicid = nicId
|
||||
cmd.virtualmachineid = self.id
|
||||
return apiclient.removeNicFromVirtualMachine(cmd)
|
||||
|
||||
def update_default_nic(self, apiclient, nicId):
|
||||
"""Set a NIC to be the default network adapter for a VM"""
|
||||
cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd()
|
||||
cmd.nicid = nicId
|
||||
cmd.virtualmachineid = self.id
|
||||
return apiclient.updateDefaultNicForVirtualMachine(cmd)
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
"""List all VMs matching criteria"""
|
||||
@ -1115,7 +1136,7 @@ class DiskOffering:
|
||||
if domainid:
|
||||
cmd.domainid = domainid
|
||||
|
||||
if services["storagetype"]:
|
||||
if "storagetype" in services:
|
||||
cmd.storagetype = services["storagetype"]
|
||||
|
||||
return DiskOffering(apiclient.createDiskOffering(cmd).__dict__)
|
||||
|
||||
@ -884,6 +884,7 @@ dictionary = {
|
||||
'label.network.offering.name': '<fmt:message key="label.network.offering.name" />',
|
||||
'label.network.offering': '<fmt:message key="label.network.offering" />',
|
||||
'label.network.rate': '<fmt:message key="label.network.rate" />',
|
||||
'label.network.rate.megabytes': '<fmt:message key="label.network.rate.megabytes"/>',
|
||||
'label.network.read': '<fmt:message key="label.network.read" />',
|
||||
'label.network.type': '<fmt:message key="label.network.type" />',
|
||||
'label.network.write': '<fmt:message key="label.network.write" />',
|
||||
|
||||
@ -867,9 +867,9 @@
|
||||
hiddenTabs.push("addloadBalancer");
|
||||
}
|
||||
|
||||
// if (isVPC || isAdvancedSGZone || hasSRXFirewall) {
|
||||
if (isVPC || isAdvancedSGZone || hasSRXFirewall) {
|
||||
hiddenTabs.push('egressRules');
|
||||
// }
|
||||
}
|
||||
|
||||
return hiddenTabs;
|
||||
},
|
||||
|
||||
@ -379,9 +379,7 @@
|
||||
});
|
||||
};
|
||||
|
||||
//dataFns.zoneCount({});
|
||||
dataFns.podCount({}); //uncomment the line above and remove this line after "count" in listZones API is fixed.
|
||||
|
||||
dataFns.zoneCount({});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user