Merge branch 'master' into vim51_win8

This commit is contained in:
Min Chen 2013-01-31 14:04:38 -08:00
commit 8f33229fc1
78 changed files with 2945 additions and 259 deletions

View File

@ -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

View File

@ -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;

View File

@ -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";

View File

@ -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();

View File

@ -226,4 +226,8 @@ public class NetworkProfile implements Network {
return vpcId;
}
@Override
public void setTrafficType(TrafficType type) {
this.trafficType = type;
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
/**

View File

@ -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";

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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());

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -56,6 +56,10 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd {
return ipAddressId;
}
public FirewallRule.TrafficType getTrafficType () {
return FirewallRule.TrafficType.Ingress;
}
public Long getId() {
return id;
}

View File

@ -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

View File

@ -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());

View File

@ -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.");
}
}
}

View File

@ -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");
}
}
}

View File

@ -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");
}
}
}

View File

@ -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.");
}
}
}

View File

@ -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;
}

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -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>

View File

@ -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>

View 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>

View File

@ -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>

View 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>

View File

@ -102,4 +102,11 @@ KfEEuzcCUIxtJYTahJ1pvlFkQ8anpuxjSEDp8x/18bq3
<programlisting>ssh -i ~/.ssh/keypair-doc &lt;ip address&gt;</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>

View File

@ -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>

View File

@ -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]

View File

@ -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"

View 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

View File

@ -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;
}

View File

@ -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: "

View File

@ -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) {

View File

@ -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

View File

@ -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 $?

View File

@ -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();

View File

@ -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>");
}

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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());
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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) {

View File

@ -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);

View File

@ -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) {
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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)
*/

View File

@ -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

View File

@ -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)
*/

View 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

View File

@ -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__)

View File

@ -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" />',

View File

@ -867,9 +867,9 @@
hiddenTabs.push("addloadBalancer");
}
// if (isVPC || isAdvancedSGZone || hasSRXFirewall) {
if (isVPC || isAdvancedSGZone || hasSRXFirewall) {
hiddenTabs.push('egressRules');
// }
}
return hiddenTabs;
},

View File

@ -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({});
}
},