Merge branch 'master' into affinity_groups

Conflicts:
	engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java
	setup/db/db/schema-410to420.sql
This commit is contained in:
Prachi Damle 2013-04-10 11:34:30 -07:00
commit 4a1eaf45bd
167 changed files with 5056 additions and 2511 deletions

View File

@ -38,12 +38,10 @@ import java.util.UUID;
import javax.naming.ConfigurationException;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
import com.cloud.agent.Agent.ExitStatus;
@ -373,6 +371,7 @@ public class AgentShell implements IAgentShell {
throw new ConfigurationException("Unable to find the guid");
}
_guid = UUID.randomUUID().toString();
_properties.setProperty("guid", _guid);
}
return true;

View File

@ -235,14 +235,14 @@ public class ConsoleProxyResource extends ServerResourceBase implements
if (_eth1ip != null) {
params.put("private.network.device", "eth1");
} else {
s_logger.warn("WARNING: eth1ip parameter is not found!");
s_logger.info("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
}
String eth2ip = (String) params.get("eth2ip");
if (eth2ip != null) {
params.put("public.network.device", "eth2");
} else {
s_logger.warn("WARNING: eth2ip parameter is not found!");
s_logger.info("eth2ip parameter is not found, assuming that we are not inside a system vm");
}
super.configure(name, params);

View File

@ -23,6 +23,7 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.State;
import com.cloud.network.rules.FirewallRule.TrafficType;
import com.cloud.utils.net.NetUtils;
/**
@ -109,6 +110,11 @@ public class FirewallRuleTO implements InternalIdentity {
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
}
public FirewallRuleTO(FirewallRule rule, String guestVlanTag, FirewallRule.TrafficType trafficType) {
this(rule.getId(), guestVlanTag, null, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(), rule.getSourceCidrList(), rule.getIcmpType(), rule.getIcmpCode());
this.trafficType = trafficType;
}
public FirewallRule.TrafficType getTrafficType(){
return trafficType;
}

View File

@ -1,197 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.api.commands;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.Network;
import com.cloud.user.UserContext;
//@APICommand(description="Creates a private network", responseObject=NetworkResponse.class)
public class CreatePrivateNetworkCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreatePrivateNetworkCmd.class.getName());
private static final String s_name = "createnetworkresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the network")
private String name;
@Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of the network")
private String displayText;
@Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.UUID, entityType = PhysicalNetworkResponse.class,
required=true, description="the Physical Network ID the network belongs to")
private Long physicalNetworkId;
@Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway of the network")
private String gateway;
@Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the network")
private String netmask;
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the network IP range")
private String startIp;
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP" +
" range. If not specified, will be defaulted to startIP")
private String endIp;
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, required=true, description="the ID or VID of the network")
private String vlan;
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network")
private String accountName;
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
description="an optional project for the ssh key")
private Long projectId;
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType = DomainResponse.class,
description="domain ID of the account owning a network")
private Long domainId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getGateway() {
return gateway;
}
public String getVlan() {
return vlan;
}
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public String getNetmask() {
return netmask;
}
public String getStartIp() {
return startIp;
}
public String getNetworkName() {
return name;
}
public String getDisplayText() {
return displayText;
}
public Long getProjectId() {
return projectId;
}
public long getPhysicalNetworkId() {
return physicalNetworkId;
}
public String getEndIp() {
return endIp;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public void create() throws ResourceAllocationException {
Network result = null;
try {
result = _networkService.createPrivateNetwork(getNetworkName(), getDisplayText(), getPhysicalNetworkId(), getVlan(),
getStartIp(), getEndIp(), getGateway(), getNetmask(), getEntityOwnerId(), null);
} catch (InsufficientCapacityException ex){
s_logger.info(ex);
s_logger.trace(ex);
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
if (result != null) {
this.setEntityId(result.getId());
this.setEntityUuid(result.getUuid());
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a Private network");
}
}
@Override
public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{
Network result = _networkService.getNetwork(getEntityId());
if (result != null) {
NetworkResponse response = _responseGenerator.createNetworkResponse(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create private network");
}
}
@Override
public long getEntityOwnerId() {
Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
if (accountId == null) {
return UserContext.current().getCaller().getId();
}
return accountId;
}
@Override
public String getEventType() {
return EventTypes.EVENT_NETWORK_CREATE;
}
@Override
public String getEventDescription() {
return "creating private network";
}
}

View File

@ -1,93 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.api.commands;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
//@APICommand(description="Destroys console proxy", responseObject=SuccessResponse.class)
public class DestroyConsoleProxyCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DestroyConsoleProxyCmd.class.getName());
private static final String s_name = "destroyconsoleproxyresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="console proxy ID")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
Account 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 String getEventType() {
return EventTypes.EVENT_PROXY_DESTROY;
}
@Override
public String getEventDescription() {
return "destroying console proxy: " + getId();
}
@Override
public void execute(){
boolean result = _consoleProxyService.destroyConsoleProxy(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy console proxy");
}
}
}

View File

@ -142,6 +142,9 @@ public class EventTypes {
//registering SSH keypair events
public static final String EVENT_REGISTER_SSH_KEYPAIR = "REGISTER.SSH.KEYPAIR";
//register for user API and secret keys
public static final String EVENT_REGISTER_FOR_SECRET_API_KEY = "REGISTER.USER.KEY";
// Template Events
public static final String EVENT_TEMPLATE_CREATE = "TEMPLATE.CREATE";
public static final String EVENT_TEMPLATE_DELETE = "TEMPLATE.DELETE";

View File

@ -46,6 +46,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
public final static String QuickCloudNoServices = "QuickCloudNoServices";
public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";

View File

@ -33,7 +33,6 @@ import org.apache.cloudstack.usage.UsageService;
import org.apache.log4j.Logger;
import com.cloud.configuration.ConfigurationService;
import com.cloud.consoleproxy.ConsoleProxyService;
import com.cloud.dao.EntityManager;
import com.cloud.domain.Domain;
import com.cloud.exception.ConcurrentOperationException;
@ -110,7 +109,6 @@ public abstract class BaseCmd {
@Inject public TemplateService _templateService;
@Inject public SecurityGroupService _securityGroupService;
@Inject public SnapshotService _snapshotService;
@Inject public ConsoleProxyService _consoleProxyService;
@Inject public VpcVirtualNetworkApplianceService _routerService;
@Inject public ResponseGenerator _responseGenerator;
@Inject public EntityManager _entityMgr;

View File

@ -45,7 +45,7 @@ public class ListGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GlobalLoadBalancerResponse.class, description = "the ID of the global load balancer rule")
private Long id;
@Parameter(name = ApiConstants.REGION_ID, type = CommandType.UUID, entityType = RegionResponse.class, description = "region ID")
@Parameter(name = ApiConstants.REGION_ID, type = CommandType.INTEGER, entityType = RegionResponse.class, description = "region ID")
private Integer regionId;
// ///////////////////////////////////////////////////

View File

@ -34,7 +34,7 @@ import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import com.cloud.vm.snapshot.VMSnapshot;
@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class)
@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class, since="4.2.0")
public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger

View File

@ -32,7 +32,7 @@ import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.vm.snapshot.VMSnapshot;
@APICommand(name="deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class)
@APICommand(name="deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class, since="4.2.0")
public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger
.getLogger(DeleteVMSnapshotCmd.class.getName());

View File

@ -30,7 +30,7 @@ import org.apache.cloudstack.api.response.VMSnapshotResponse;
import com.cloud.vm.snapshot.VMSnapshot;
@APICommand(name="listVMSnapshot", description = "List virtual machine snapshot by conditions", responseObject = VMSnapshotResponse.class)
@APICommand(name="listVMSnapshot", description = "List virtual machine snapshot by conditions", responseObject = VMSnapshotResponse.class, since="4.2.0")
public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
private static final String s_name = "listvmsnapshotresponse";

View File

@ -37,7 +37,7 @@ import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
import com.cloud.vm.snapshot.VMSnapshot;
@APICommand(name = "revertToSnapshot",description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class)
@APICommand(name = "revertToSnapshot",description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class, since="4.2.0")
public class RevertToSnapshotCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger
.getLogger(RevertToSnapshotCmd.class.getName());

View File

@ -71,6 +71,18 @@ public class FirewallRuleResponse extends BaseResponse {
@SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with the rule", responseObject = ResourceTagResponse.class)
private List<ResourceTagResponse> tags;
@SerializedName(ApiConstants.VM_GUEST_IP) @Param(description="the vm ip address for the port forwarding rule")
private String destNatVmIp;
public String getDestNatVmIp() {
return destNatVmIp;
}
public void setDestNatVmIp(String destNatVmIp) {
this.destNatVmIp = destNatVmIp;
}
@Override
public String getObjectId() {

View File

@ -458,6 +458,22 @@
</target>
</configuration>
</execution>
<execution>
<id>process-quickcloud-spring-context</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target if="${quickcloud}">
<echo>quickcloud</echo>
<replaceregexp
file="${basedir}/target/generated-webapp/WEB-INF/classes/applicationContext.xml"
match="com.cloud.consoleproxy.ConsoleProxyManagerImpl"
replace="com.cloud.consoleproxy.StaticConsoleProxyManager" byline="true" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<!-- there are the jasypt libs requires by some of the python scripts -->

View File

@ -506,7 +506,7 @@
<property name="name" value="XCP Agent"/>
</bean>
<bean id="SecondaryStorageDiscoverer" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer">
<bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
<property name="name" value="SecondaryStorage"/>
</bean>
@ -737,7 +737,6 @@
<bean id="defaultEndPointSelector" class="org.apache.cloudstack.storage.endpoint.DefaultEndPointSelector" />
<bean id="defaultPrimaryDataStoreProviderManagerImpl" class="org.apache.cloudstack.storage.datastore.manager.DefaultPrimaryDataStoreProviderManagerImpl" />
<bean id="eventUtils" class="com.cloud.event.EventUtils" />
<bean id="globalLoadBalancingRulesServiceImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" />
<bean id="hypervsiorHostEndPointRpcServer" class="org.apache.cloudstack.storage.HypervsiorHostEndPointRpcServer" />
<bean id="iSCSI" class="org.apache.cloudstack.storage.datastore.type.ISCSI" />
<bean id="ISO" class="org.apache.cloudstack.storage.image.format.ISO" />

View File

@ -43,7 +43,12 @@
-->
<bean id="premiumDatabaseUpgradeChecker" class="com.cloud.upgrade.PremiumDatabaseUpgradeChecker"/>
<bean id="GlobalLoadBalancingRulesServiceImpl" class ="org.apache.cloudstack.region.gslb.GlobalLoadBalancingRulesServiceImpl" >
<property name="GslbServiceProvider">
<ref bean="Netscaler"/>
</property>
</bean>
<!--
DAO with customized configuration under non-OSS deployment
-->

View File

@ -62,6 +62,9 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities {
@Column(name="max_hosts_per_cluster")
private Integer maxHostsPerCluster;
@Column(name="vm_snapshot_enabled")
private Boolean vmSnapshotEnabled;
protected HypervisorCapabilitiesVO() {
this.uuid = UUID.randomUUID().toString();
}
@ -169,7 +172,15 @@ public class HypervisorCapabilitiesVO implements HypervisorCapabilities {
this.maxHostsPerCluster = maxHostsPerCluster;
}
@Override
public Boolean getVmSnapshotEnabled() {
return vmSnapshotEnabled;
}
public void setVmSnapshotEnabled(Boolean vmSnapshotEnabled) {
this.vmSnapshotEnabled = vmSnapshotEnabled;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HypervisorCapabilitiesVO) {
return ((HypervisorCapabilitiesVO)obj).getId() == this.getId();

View File

@ -80,7 +80,7 @@ public abstract class ServerResourceBase implements ServerResource {
_storageNic2 = getNetworkInterface(storageNic2);
if (_privateNic == null) {
s_logger.error("Nics are not configured!");
s_logger.warn("Nics are not specified in properties file/db, will try to autodiscover");
Enumeration<NetworkInterface> nics = null;
try {

View File

@ -5,9 +5,9 @@
# 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
@ -20,7 +20,7 @@
/etc/cloudstack/agent/log4j-cloud.xml
/etc/init.d/cloudstack-agent
/usr/bin/cloudstack-setup-agent
/usr/bin/cloud-ssh
/usr/bin/cloudstack-ssh
/var/log/cloudstack/agent
/usr/share/cloudstack-agent/lib/*
/usr/share/cloudstack-agent/plugins

View File

@ -5,9 +5,9 @@
# 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
@ -27,6 +27,6 @@
/usr/share/cloudstack-common/scripts/vm/hypervisor/versions.sh
/usr/share/cloudstack-common/scripts/vm/hypervisor/xenserver/*
/usr/share/cloudstack-common/lib/*
/usr/bin/cloud-set-guest-password
/usr/bin/cloud-set-guest-sshkey
/usr/bin/cloudstack-set-guest-password
/usr/bin/cloudstack-set-guest-sshkey
/usr/lib/python2.?/*-packages/*

View File

@ -25,8 +25,10 @@
/var/log/cloudstack/management
/var/lib/cloudstack/mnt
/var/lib/cloudstack/management
/usr/bin/cloud-update-xenserver-licenses
/usr/bin/cloud-setup-management
/usr/bin/cloud-setup-databases
/usr/bin/cloud-migrate-databases
/usr/bin/cloudstack-update-xenserver-licenses
/usr/bin/cloudstack-setup-management
/usr/bin/cloudstack-setup-databases
/usr/bin/cloudstack-migrate-databases
/usr/bin/cloudstack-setup-encryption
/usr/bin/cloudstack-sysvmadm
/usr/share/cloudstack-management/*

16
debian/rules vendored
View File

@ -69,7 +69,7 @@ install:
install -D plugins/hypervisors/kvm/target/dependencies/* $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/
install -D packaging/debian/init/cloud-agent $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-agent
install -D agent/bindir/cloud-setup-agent.in $(DESTDIR)/usr/bin/cloudstack-setup-agent
install -D agent/bindir/cloud-ssh.in $(DESTDIR)/usr/bin/cloud-ssh
install -D agent/bindir/cloud-ssh.in $(DESTDIR)/usr/bin/cloudstack-ssh
install -D agent/target/transformed/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/agent
# cloudstack-management
@ -100,7 +100,7 @@ install:
ln -s tomcat6-nonssl.conf $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/tomcat6.conf
ln -s server-nonssl.xml $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/management/server.xml
install -D packaging/debian/init/cloud-management $(DESTDIR)/$(SYSCONFDIR)/init.d/$(PACKAGE)-management
install -D client/bindir/cloud-update-xenserver-licenses.in $(DESTDIR)/usr/bin/cloud-update-xenserver-licenses
install -D client/bindir/cloud-update-xenserver-licenses.in $(DESTDIR)/usr/bin/cloudstack-update-xenserver-licenses
ln -s /usr/share/tomcat6/bin $(DESTDIR)/usr/share/$(PACKAGE)-management/bin
# Remove configuration in /ur/share/cloudstack-management/webapps/client/WEB-INF
# This should all be in /etc/cloudstack/management
@ -121,11 +121,13 @@ install:
cp -r scripts/storage $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts
cp -r scripts/util $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts
cp -r scripts/vm $(DESTDIR)/usr/share/$(PACKAGE)-common/scripts
install -D client/target/utilities/bin/cloud-migrate-databases $(DESTDIR)/usr/bin
install -D client/target/utilities/bin/cloud-set-guest-password $(DESTDIR)/usr/bin
install -D client/target/utilities/bin/cloud-set-guest-sshkey $(DESTDIR)/usr/bin
install -D client/target/utilities/bin/cloud-setup-databases $(DESTDIR)/usr/bin
install -D client/target/utilities/bin/cloud-setup-management $(DESTDIR)/usr/bin
install -D client/target/utilities/bin/cloud-migrate-databases $(DESTDIR)/usr/bin/cloudstack-migrate-databases
install -D client/target/utilities/bin/cloud-set-guest-password $(DESTDIR)/usr/bin/cloudstack-set-guest-password
install -D client/target/utilities/bin/cloud-set-guest-sshkey $(DESTDIR)/usr/bin/cloudstack-set-guest-sshkey
install -D client/target/utilities/bin/cloud-setup-databases $(DESTDIR)/usr/bin/cloudstack-setup-databases
install -D client/target/utilities/bin/cloud-setup-management $(DESTDIR)/usr/bin/cloudstack-setup-management
install -D client/target/utilities/bin/cloud-setup-encryption $(DESTDIR)/usr/bin/cloudstack-setup-encryption
install -D client/target/utilities/bin/cloud-sysvmadm $(DESTDIR)/usr/bin/cloudstack-sysvmadm
install -D services/console-proxy/server/dist/systemvm.iso $(DESTDIR)/usr/share/$(PACKAGE)-common/vms/systemvm.iso
# We need jasypt for cloud-install-sys-tmplt, so this is a nasty hack to get it into the right place
install -D agent/target/dependencies/jasypt-1.9.0.jar $(DESTDIR)/usr/share/$(PACKAGE)-common/lib

View File

@ -17,7 +17,6 @@
# under the License.
mvn install:install-file -Dfile=cloud-iControl.jar -DgroupId=com.cloud.com.f5 -DartifactId=icontrol -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=cloud-netscaler.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler -Dversion=1.0 -Dpackaging=jar
mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx -Dversion=1.0 -Dpackaging=jar
# From http://support.netapp.com/ (not available online, contact your support representative)
@ -25,18 +24,6 @@ mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.
if [ -e cloud-manageontap.jar ]; then mv cloud-manageontap.jar manageontap.jar; fi
mvn install:install-file -Dfile=manageontap.jar -DgroupId=com.cloud.com.netapp -DartifactId=manageontap -Dversion=4.0 -Dpackaging=jar
# From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSDK41
# Version: 4.1, Release-date: 2010-07-13, Build: 257238
if [ -e vmware-apputils.jar ]; then mv vmware-apputils.jar apputils.jar; fi
if [ -e vmware-vim.jar ]; then mv vmware-vim.jar vim.jar; fi
if [ -e vmware-vim25.jar ]; then mv vmware-vim25.jar vim25.jar; fi
mvn install:install-file -Dfile=vim25.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=4.1 -Dpackaging=jar
mvn install:install-file -Dfile=apputils.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-apputils -Dversion=4.1 -Dpackaging=jar
mvn install:install-file -Dfile=vim.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim -Dversion=4.1 -Dpackaging=jar
#
# From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSP510-WEBSDK-510
# Version: 5.1, Release-date: 2012-09-10, Build: 774886
mvn install:install-file -Dfile=vim25_51.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=5.1 -Dpackaging=jar

View File

@ -22,23 +22,26 @@
specific language governing permissions and limitations
under the License.
-->
<bookinfo id="book-release-notes-3.0.4">
<title>&PRODUCT; Guide</title>
<subtitle>Revised August 9, 2012 10:48 pm Pacific</subtitle>
<productname>Apache CloudStack</productname>
<productnumber>4.0.0</productnumber>
<edition>1</edition>
<pubsnumber/>
<abstract>
<para> Complete technical documentation of &PRODUCT;. </para>
</abstract>
<corpauthor>
<inlinemediaobject>
<imageobject>
<imagedata fileref="Common_Content/images/title_logo.svg" format="SVG"/>
</imageobject>
</inlinemediaobject>
</corpauthor>
<xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<title>&PRODUCT; Guide</title>
<subtitle>Revised August 9, 2012 10:48 pm Pacific</subtitle>
<productname>Apache CloudStack</productname>
<productnumber>4.0.0</productnumber>
<edition>1</edition>
<pubsnumber></pubsnumber>
<abstract>
<para>
Complete technical documentation of &PRODUCT;.
</para>
</abstract>
<corpauthor>
<inlinemediaobject>
<imageobject>
<imagedata fileref="Common_Content/images/title_logo.svg" format="SVG" />
</imageobject>
</inlinemediaobject>
</corpauthor>
<xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</bookinfo>

View File

@ -11,7 +11,9 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -71,7 +71,7 @@
<para>In Hypervisor, choose VMware.</para>
</listitem>
<listitem>
<para>Provide the following information in the dialog. The fields below make reference to
<para>Provide the following information in the dialog. The fields below make reference to the
values from vCenter.</para>
<mediaobject>
<imageobject>
@ -81,8 +81,6 @@
<phrase>addcluster.png: add a cluster</phrase>
</textobject>
</mediaobject>
<para>There might be a slight delay while the cluster is provisioned. It will automatically
display in the UI.</para>
<itemizedlist>
<listitem>
<para><emphasis role="bold">Cluster Name</emphasis>: Enter the name of the cluster you
@ -136,7 +134,7 @@
</listitem>
<listitem>
<para>Nexus dvSwitch Username: The username required to access the Nexus VSM
applicance.</para>
appliance.</para>
</listitem>
<listitem>
<para>Nexus dvSwitch Password: The password associated with the username specified
@ -151,7 +149,8 @@
<listitem>
<para><emphasis role="bold">Guest Traffic vSwitch Type</emphasis>: This option is
displayed only if you enable the Override Guest Traffic option. Select a desirable
switch. If the vmware.use.dvswitch global parameter is true, the default option will be
switch. </para>
<para>If the vmware.use.dvswitch global parameter is true, the default option will be
VMware vNetwork Distributed Virtual Switch.</para>
<para>If you have enabled Nexus dvSwitch in the environment, the following parameters for
dvSwitch configuration are displayed:</para>
@ -161,7 +160,7 @@
</listitem>
<listitem>
<para>Nexus dvSwitch Username: The username required to access the Nexus VSM
applicance.</para>
appliance.</para>
</listitem>
<listitem>
<para>Nexus dvSwitch Password: The password associated with the username specified

View File

@ -0,0 +1,43 @@
<?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="added-API-commands-4.2">
<title>Added API Commands in 4.2</title>
<itemizedlist>
<listitem>
<para>addIpToNic </para>
<para>Adds an IP address to the NIC from the guest subnet. The request parameters are: nicid,
ipaddress.</para>
<para>The response parameters are: nicid, ipaddress, networkid </para>
</listitem>
<listitem>
<para>removeIpFromNic</para>
<para> Removes the reserved IP for the NIC. The request parameters is: id.</para>
<para>The response parameters are: true, false</para>
</listitem>
<listitem>
<para>listNics</para>
<para>Lists the NIC details of the user VM; the API response also contains the Secondary IP
addresses of the NIC. The request parameters are: nicid, virtualmachineid.</para>
<para>The response parameters are: id, ipaddress, secondaryips, gateway, netmask, macaddr,
broadcasturi, isolationuri, isdefault,</para>
</listitem>
</itemizedlist>
</section>

View File

@ -87,7 +87,7 @@
<entry><para>suspendProject (Suspends a project)</para></entry>
<entry><para>listProjects (Lists projects and provides detailed information for listed
projects)</para></entry>
<entry><para>addAccountToProject (Adds acoount to a project)</para></entry>
<entry><para>addAccountToProject (Adds account to a project)</para></entry>
</row>
<row>
<entry><para>deleteAccountFromProject (Deletes account from the project)</para></entry>

View File

@ -45,7 +45,7 @@
<para>Available in fresh installations of &PRODUCT;. Not available through upgrade of previous versions.</para>
</listitem>
<listitem>
<para>Features such as Elastic IP (EIP) and Elastic Load Balacing (ELB) are only available in an infrastructure
<para>Features such as Elastic IP (EIP) and Elastic Load Balancing (ELB) are only available in an infrastructure
with a Citrix NetScaler device. Users accessing a Zone with a NetScaler device will need to use a
NetScaler-enabled network offering (DefaultSharedNetscalerEIP and ELBNetworkOffering).</para>
</listitem>

View File

@ -25,7 +25,7 @@
<section id="building-documentation">
<title>Building &PRODUCT; Documentation</title>
<para>To build a specific guide, go to the source tree of the documentation in /docs and identify the guide you want to build.</para>
<para>Currenlty there are four guides plus the release notes, all defined in publican configuration files:</para>
<para>Currently there are four guides plus the release notes, all defined in publican configuration files:</para>
<programlisting>
publican-adminguide.cfg
publican-devguide.cfg

View File

@ -27,7 +27,7 @@
<para>Marvin is built with Maven and is dependent on APIdoc. To build it do the following in the root tree of &PRODUCT;:</para>
<programlisting>mvn -P developer -pl :cloud-apidoc</programlisting>
<programlisting>mvn -P developer -pl :cloud-marvin</programlisting>
<para>If successfull the build will have created the cloudstackAPI Python package under tools/marvin/marvin/cloudstackAPI as well as a gziped Marvin package under tools/marvin dist. To install the Python Marvin module do the following in tools/marvin:</para>
<para>If successful the build will have created the cloudstackAPI Python package under tools/marvin/marvin/cloudstackAPI as well as a gziped Marvin package under tools/marvin dist. To install the Python Marvin module do the following in tools/marvin:</para>
<programlisting>sudo python ./setup.py install</programlisting>
<para>The dependencies will be downloaded the Python module installed and you should be able to use Marvin in Python. Check that you can import the module before starting to use it.</para>
<programlisting>$ python

View File

@ -52,7 +52,7 @@
how to <ulink url="http://rlandmann.fedorapeople.org/pug/sect-Users_Guide-Preparing_a_document_for_translation.html">prepare</ulink> a document for translation.</para>
<para>The basic command to execute to build the pot files for the developer guide is:</para>
<programlisting>publican update_pot --config=publican-devguide.cfg</programlisting>
<para>This will create a pot directory with pot files in it, one for each corresponding xml files needed to build the guide. Once genereated, all pots files need to be configured for translation using transifex this is best done by using the transifex client that you can install with the following command (For RHEL and its derivatives):</para>
<para>This will create a pot directory with pot files in it, one for each corresponding xml files needed to build the guide. Once generated, all pots files need to be configured for translation using transifex this is best done by using the transifex client that you can install with the following command (For RHEL and its derivatives):</para>
<programlisting>yum install transifex-client</programlisting>
<para>The transifex client is also available via PyPi and you can install it like this:</para>
<programlisting>easy_install transifex-client</programlisting>

View File

@ -32,7 +32,7 @@
<listitem><para>Generate a new 2048-bit private key</para><programlisting>openssl genrsa -des3 -out yourprivate.key 2048</programlisting></listitem>
<listitem><para>Generate a new certificate CSR</para><programlisting>openssl req -new -key yourprivate.key -out yourcertificate.csr</programlisting></listitem>
<listitem><para>Head to the website of your favorite trusted Certificate Authority, purchase an SSL certificate, and submit the CSR. You should receive a valid certificate in return</para></listitem>
<listitem><para>Convert your private key format into PKCS#8 encrypted format.</para><programlisting>openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encryped.key</programlisting></listitem>
<listitem><para>Convert your private key format into PKCS#8 encrypted format.</para><programlisting>openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encrypted.key</programlisting></listitem>
<listitem><para>Convert your PKCS#8 encrypted private key into the PKCS#8 format that is compliant with &PRODUCT;</para><programlisting>openssl pkcs8 -in yourprivate.pkcs8.encrypted.key -out yourprivate.pkcs8.key</programlisting></listitem>
</orderedlist>
</listitem>

View File

@ -62,7 +62,7 @@
support any system that is not up to date with patches.</para>
</listitem>
<listitem>
<para>All hosts within a cluster must be homogenous. The CPUs must be of the same type,
<para>All hosts within a cluster must be homogeneous. The CPUs must be of the same type,
count, and feature flags.</para>
</listitem>
<listitem>

View File

@ -33,7 +33,7 @@
If you didn't follow the steps to build your own packages from source
in the sections for <xref linkend="sect-source-buildrpm" /> or
<xref linkend="sect-source-builddebs" /> you may find pre-built
DEB and RPM packages for your convience linked from the
DEB and RPM packages for your convenience linked from the
<ulink url="http://cloudstack.apache.org/downloads.html">downloads</ulink>
page.
</para>

View File

@ -29,7 +29,7 @@
<listitem><para>In the left navigation, click Global Settings.</para></listitem>
<listitem><para>Set the following global configuration parameters.</para>
<itemizedlist>
<listitem><para>remote.access.vpn.client.ip.range The range of IP addressess to be allocated to remote access VPN clients. The first IP in the range is used by the VPN server.</para></listitem>
<listitem><para>remote.access.vpn.client.ip.range The range of IP addresses to be allocated to remote access VPN clients. The first IP in the range is used by the VPN server.</para></listitem>
<listitem><para>remote.access.vpn.psk.length Length of the IPSec key.</para></listitem>
<listitem><para>remote.access.vpn.user.limit Maximum number of VPN users per account.</para></listitem>
</itemizedlist></listitem></orderedlist>

View File

@ -95,7 +95,7 @@
</listitem>
<listitem>
<para>Convert your private key format into PKCS#8 encrypted format.</para>
<programlisting>openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encryped.key</programlisting>
<programlisting>openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encrypted.key</programlisting>
</listitem>
<listitem>
<para>Convert your PKCS#8 encrypted private key into the PKCS#8 format that is compliant

View File

@ -19,6 +19,8 @@
under the License.
-->
<chapter id="global-config">
<title>Global Configuration Parameters</title>
<section id="setting-global-config-parameters">
<title>Setting Global Configuration Parameters</title>
<para>&PRODUCT; provides parameters that you can set to control many aspects of the cloud. When
&PRODUCT; is first installed, and periodically thereafter, you might need to modify these
@ -51,4 +53,81 @@
must click the name of the hypervisor first to display the editing screen.</para>
</listitem>
</orderedlist>
</section>
<section id="about-global-config-parameters">
<title>About Global Configuration Parameters</title>
<para>&PRODUCT; provides a variety of settings you can use to set limits, configure features,
and enable or disable features in the cloud. Once your Management Server is running, you might
need to set some of these global configuration parameters, depending on what optional features
you are setting up.</para>
<para>To modify global configuration parameters, use the steps in "Setting Global Configuration
Parameters."</para>
<para>The documentation for each &PRODUCT; feature should direct you to the names of the applicable
parameters. Many of them are discussed in the &PRODUCT; Administration Guide. The following table
shows a few of the more useful parameters.</para>
<informaltable frame="all">
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colnum="1" colname="c1" colwidth="2*"/>
<colspec colnum="2" colname="c2" colwidth="1*"/>
<thead>
<row>
<entry><para>Field</para></entry>
<entry><para>Value</para></entry>
</row>
</thead>
<tbody>
<row>
<entry><para>management.network.cidr</para></entry>
<entry><para>A CIDR that describes the network that the management CIDRs reside on. This
variable must be set for deployments that use vSphere. It is recommended to be set for
other deployments as well. Example: 192.168.3.0/24.</para></entry>
</row>
<row>
<entry><para>xen.setup.multipath</para></entry>
<entry><para>For XenServer nodes, this is a true/false variable that instructs CloudStack to
enable iSCSI multipath on the XenServer Hosts when they are added. This defaults to false.
Set it to true if you would like CloudStack to enable multipath.</para>
<para>If this is true for a NFS-based deployment multipath will still be enabled on the
XenServer host. However, this does not impact NFS operation and is harmless.</para></entry>
</row>
<row>
<entry><para>secstorage.allowed.internal.sites</para></entry>
<entry><para>This is used to protect your internal network from rogue attempts to download
arbitrary files using the template download feature. This is a comma-separated list of CIDRs.
If a requested URL matches any of these CIDRs the Secondary Storage VM will use the private
network interface to fetch the URL. Other URLs will go through the public interface.
We suggest you set this to 1 or 2 hardened internal machines where you keep your templates.
For example, set it to 192.168.1.66/32.</para></entry>
</row>
<row>
<entry><para>use.local.storage</para></entry>
<entry><para>Determines whether CloudStack will use storage that is local to the Host for data
disks, templates, and snapshots. By default CloudStack will not use this storage. You should
change this to true if you want to use local storage and you understand the reliability and
feature drawbacks to choosing local storage.</para></entry>
</row>
<row>
<entry><para>host</para></entry>
<entry><para>This is the IP address of the Management Server. If you are using multiple
Management Servers you should enter a load balanced IP address that is reachable via
the private network.</para></entry>
</row>
<row>
<entry><para>default.page.size</para></entry>
<entry><para>Maximum number of items per page that can be returned by a CloudStack API command.
The limit applies at the cloud level and can vary from cloud to cloud. You can override this
with a lower value on a particular API call by using the page and pagesize API command parameters.
For more information, see the Developer's Guide. Default: 500.</para></entry>
</row>
<row>
<entry><para>ha.tag</para></entry>
<entry><para>The label you want to use throughout the cloud to designate certain hosts as dedicated
HA hosts. These hosts will be used only for HA-enabled VMs that are restarting due to the failure
of another host. For example, you could set this to ha_host. Specify the ha.tag value as a host tag
when you add a new host to the cloud.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</chapter>

View File

@ -34,7 +34,7 @@
<listitem><para>49152 - 49216 (libvirt live migration)</para></listitem>
</orderedlist>
<para>It depends on the firewall you are using how to open these ports. Below you'll find examples how to open these ports in RHEL/CentOS and Ubuntu.</para>
<section id="hypervisor-host-install-firewall-rhel">
<section>
<title>Open ports in RHEL/CentOS</title>
<para>RHEL and CentOS use iptables for firewalling the system, you can open extra ports by executing the following iptable commands:</para>
<programlisting language="Bash"><command>$ iptables -I INPUT -p tcp -m tcp --dport 22 -j ACCEPT</command></programlisting>
@ -45,7 +45,7 @@
<para>These iptable settings are not persistent accross reboots, we have to save them first.</para>
<programlisting language="Bash"><command>$ iptables-save > /etc/sysconfig/iptables</command></programlisting>
</section>
<section id="hypervisor-host-install-firewall-ubuntu">
<section>
<title>Open ports in Ubuntu</title>
<para>The default firewall under Ubuntu is UFW (Uncomplicated FireWall), which is a Python wrapper around iptables.</para>
<para>To open the required ports, execute the following commands:</para>

View File

@ -28,7 +28,7 @@
<orderedlist>
<listitem>
<para>In order to have live migration working libvirt has to listen for unsecured TCP connections. We also need to turn off libvirts attempt to use Multicast DNS advertising. Both of these settings are in <filename>/etc/libvirt/libvirtd.conf</filename></para>
<para>Set the following paramaters:</para>
<para>Set the following parameters:</para>
<programlisting>listen_tls = 0</programlisting>
<programlisting>listen_tcp = 1</programlisting>
<programlisting>tcp_port = "16509"</programlisting>

View File

@ -69,7 +69,7 @@
we can proceed to configuring the network.</para>
<para>First we configure eth0</para>
<programlisting language="Bash">vi /etc/sysconfig/network-scripts/ifcfg-eth0</programlisting>
<para>Make sure it looks similair to:</para>
<para>Make sure it looks similar to:</para>
<programlisting><![CDATA[DEVICE=eth0
HWADDR=00:04:xx:xx:xx:xx
ONBOOT=yes

View File

@ -29,7 +29,7 @@
<para>In order to forward traffic to your instances you will need at least two bridges: <emphasis>public</emphasis> and <emphasis>private</emphasis>.</para>
<para>By default these bridges are called <emphasis>cloudbr0</emphasis> and <emphasis>cloudbr1</emphasis>, but you do have to make sure they are available on each hypervisor.</para>
<para>The most important factor is that you keep the configuration consistent on all your hypervisors.</para>
<section id="hypervisor-host-install-network-vlan">
<section>
<title>Network example</title>
<para>There are many ways to configure your network. In the Basic networking mode you should have two (V)LAN's, one for your private network and one for the public network.</para>
<para>We assume that the hypervisor has one NIC (eth0) with three tagged VLAN's:</para>
@ -41,16 +41,16 @@
<para>On VLAN 100 we give the Hypervisor the IP-Address 192.168.42.11/24 with the gateway 192.168.42.1</para>
<note><para>The Hypervisor and Management server don't have to be in the same subnet!</para></note>
</section>
<section id="hypervisor-host-install-network-configure">
<section>
<title>Configuring the network bridges</title>
<para>It depends on the distribution you are using how to configure these, below you'll find examples for RHEL/CentOS and Ubuntu.</para>
<note><para>The goal is to have two bridges called 'cloudbr0' and 'cloudbr1' after this section. This should be used as a guideline only. The exact configuration will depend on your network layout.</para></note>
<section id="hypervisor-host-install-network-configure-rhel">
<section>
<title>Configure in RHEL or CentOS</title>
<para>The required packages were installed when libvirt was installed, we can proceed to configuring the network.</para>
<para>First we configure eth0</para>
<programlisting language="Bash">vi /etc/sysconfig/network-scripts/ifcfg-eth0</programlisting>
<para>Make sure it looks similair to:</para>
<para>Make sure it looks similar to:</para>
<programlisting><![CDATA[DEVICE=eth0
HWADDR=00:04:xx:xx:xx:xx
ONBOOT=yes
@ -89,7 +89,7 @@ VLAN=yes
BRIDGE=cloudbr1]]></programlisting>
<para>Now we have the VLAN interfaces configured we can add the bridges on top of them.</para>
<programlisting language="Bash">vi /etc/sysconfig/network-scripts/ifcfg-cloudbr0</programlisting>
<para>Now we just configure it is a plain bridge without an IP-Adress</para>
<para>Now we just configure it is a plain bridge without an IP-Address</para>
<programlisting><![CDATA[DEVICE=cloudbr0
TYPE=Bridge
ONBOOT=yes
@ -111,7 +111,7 @@ STP=yes]]></programlisting>
<para>With this configuration you should be able to restart the network, although a reboot is recommended to see if everything works properly.</para>
<warning><para>Make sure you have an alternative way like IPMI or ILO to reach the machine in case you made a configuration error and the network stops functioning!</para></warning>
</section>
<section id="hypervisor-host-install-network-configure-ubuntu">
<section>
<title>Configure in Ubuntu</title>
<para>All the required packages were installed when you installed libvirt, so we only have to configure the network.</para>
<programlisting language="Bash">vi /etc/network/interfaces</programlisting>

View File

@ -28,4 +28,5 @@
<xi:include href="citrix-xenserver-installation.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="vmware-install.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- <xi:include href="ovm-install.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> -->
<xi:include href="lxc-install.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</chapter>

110
docs/en-US/lxc-install.xml Normal file
View File

@ -0,0 +1,110 @@
<?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="lxc-install">
<title>LXC Installation and Configuration</title>
<section id="lxc-requirements">
<title>System Requirements for LXC Hosts</title>
<para>LXC requires the Linux kernel cgroups functionality which is available starting 2.6.24. Although you are not required to run these distributions, the following are recommended:</para>
<itemizedlist>
<listitem><para>CentOS / RHEL: 6.3</para></listitem>
<listitem><para>Ubuntu: 12.04(.1)</para></listitem>
</itemizedlist>
<para>The main requirement for LXC hypervisors is the libvirt and Qemu version. No matter what
Linux distribution you are using, make sure the following requirements are met:</para>
<itemizedlist>
<listitem><para>libvirt: 1.0.0 or higher</para></listitem>
<listitem><para>Qemu/KVM: 1.0 or higher</para></listitem>
</itemizedlist>
<para>The default bridge in &PRODUCT; is the Linux native bridge implementation (bridge module). &PRODUCT; includes an option to work with OpenVswitch, the requirements are listed below</para>
<itemizedlist>
<listitem><para>libvirt: 1.0.0 or higher</para></listitem>
<listitem><para>openvswitch: 1.7.1 or higher</para></listitem>
</itemizedlist>
<para>In addition, the following hardware requirements apply:</para>
<itemizedlist>
<listitem><para>Within a single cluster, the hosts must be of the same distribution version.</para></listitem>
<listitem><para>All hosts within a cluster must be homogenous. The CPUs must be of the same type, count, and feature flags.</para></listitem>
<listitem><para>Must support HVM (Intel-VT or AMD-V enabled)</para></listitem>
<listitem><para>64-bit x86 CPU (more cores results in better performance)</para></listitem>
<listitem><para>4 GB of memory</para></listitem>
<listitem><para>At least 1 NIC</para></listitem>
<listitem><para>When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running</para></listitem>
</itemizedlist>
</section>
<section id="lxc-install-overview">
<title>LXC Installation Overview</title>
<para>LXC does not have any native system VMs, instead KVM will be used to run system VMs. This means that your host will need to support both LXC and KVM, thus most of the installation and configuration will be identical to the KVM installation. The material in this section doesn't duplicate KVM installation docs. It provides the &PRODUCT;-specific steps that are needed to prepare a KVM host to work with &PRODUCT;.</para>
<warning><para>Before continuing, make sure that you have applied the latest updates to your host.</para></warning>
<warning><para>It is NOT recommended to run services on this host not controlled by &PRODUCT;.</para></warning>
<para>The procedure for installing an LXC Host is:</para>
<orderedlist>
<listitem><para>Prepare the Operating System</para></listitem>
<listitem><para>Install and configure libvirt</para></listitem>
<listitem><para>Configure Security Policies (AppArmor and SELinux)</para></listitem>
<listitem><para>Install and configure the Agent</para></listitem>
</orderedlist>
</section>
<section id="lxc-install-prepare-os">
<xi:include href="hypervisor-host-install-prepare-os.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
<section id="lxc-install-agent">
<title>Install and configure the Agent</title>
<para>To manage LXC instances on the host &PRODUCT; uses a Agent. This Agent communicates with the Management server and controls all the instances on the host.</para>
<para>First we start by installing the agent:</para>
<para>In RHEL or CentOS:</para>
<programlisting language="Bash"><command>$ yum install cloud-agent</command></programlisting>
<para>In Ubuntu:</para>
<programlisting language="Bash"><command>$ apt-get install cloud-agent</command></programlisting>
<para>Next step is to update the Agent configuration setttings. The settings are in <filename>/etc/cloudstack/agent/agent.properties</filename></para>
<orderedlist>
<listitem>
<para>Set the Agent to run in LXC mode:</para>
<programlisting>hypervisor.type=lxc</programlisting>
</listitem>
<listitem>
<para>Optional: If you would like to use direct networking (instead of the default bridge networking), configure these lines:</para>
<programlisting>libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.DirectVifDriver</programlisting>
<programlisting>network.direct.source.mode=private</programlisting>
<programlisting>network.direct.device=eth0</programlisting>
</listitem>
</orderedlist>
<para>The host is now ready to be added to a cluster. This is covered in a later section, see <xref linkend="host-add" />. It is recommended that you continue to read the documentation before adding the host!</para>
</section>
<section id="lxc-install-libvirt">
<xi:include href="hypervisor-host-install-libvirt.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
<section id="lxc-install-security-policies">
<xi:include href="hypervisor-host-install-security-policies.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
<section id="lxc-install-network">
<xi:include href="hypervisor-host-install-network.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
<section id="lxc-install-firewall">
<xi:include href="hypervisor-host-install-firewall.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
<section id="lxc-install-finish">
<xi:include href="hypervisor-host-install-finish.xml#xpointer(/section/*)" xmlns:xi="http://www.w3.org/2001/XInclude" />
</section>
</section>

View File

@ -0,0 +1,24 @@
<?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="lxc-topology-req">
<title>LXC Topology Requirements</title>
<para>The Management Servers communicate with LXC hosts on port 22 (ssh).</para>
</section>

View File

@ -30,7 +30,7 @@
<listitem>
<para>Check for a fully qualified hostname.</para>
<programlisting language="Bash">hostname --fqdn</programlisting>
<para>This should return a fully qualified hostname such as "managament1.lab.example.org". If it does not, edit /etc/hosts so that it does.</para>
<para>This should return a fully qualified hostname such as "management1.lab.example.org". If it does not, edit /etc/hosts so that it does.</para>
</listitem>
<listitem>
<para>Make sure that the machine can reach the Internet.</para>

View File

@ -53,6 +53,10 @@
<para>For KVM:</para>
<programlisting># /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s &lt;optional-management-server-secret-key&gt; -F</programlisting>
</listitem>
<listitem>
<para>For LXC:</para>
<programlisting># /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h lxc -s &lt;optional-management-server-secret-key&gt; -F</programlisting>
</listitem>
</itemizedlist>
<para>On Ubuntu, use the following path instead:</para>
<programlisting># /usr/lib/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt</programlisting>

View File

@ -58,7 +58,7 @@
</tbody>
</tgroup>
</informaltable>
<para>In addition to above settings, the adminstrator is responsible for setting the 'host' global
<para>In addition to above settings, the administrator is responsible for setting the 'host' global
config value from the management server IP to load balancer virtual IP address.
If the 'host' value is not set to the VIP for Port 8250 and one of your management servers crashes,
the UI is still available but the system VMs will not be able to contact the management server.

View File

@ -57,7 +57,7 @@
<listitem><note><para>If DHCP is used for hosts, ensure that no conflict occurs between DHCP server used for these hosts and the DHCP router created by &PRODUCT;.</para></note></listitem>
<listitem><para>Latest hotfixes applied to hypervisor software</para></listitem>
<listitem><para>When you deploy &PRODUCT;, the hypervisor host must not have any VMs already running</para></listitem>
<listitem><para>All hosts within a cluster must be homogenous. The CPUs must be of the same type, count, and feature flags.</para></listitem>
<listitem><para>All hosts within a cluster must be homogeneous. The CPUs must be of the same type, count, and feature flags.</para></listitem>
</itemizedlist>
<para>Hosts have additional requirements depending on the hypervisor. See the requirements listed at the top of the Installation section for your chosen hypervisor:</para>
<warning>
@ -68,6 +68,7 @@
<listitem><para><xref linkend="system-requirements-xenserver-hosts"/></para></listitem>
<listitem><para><xref linkend="vmware-requirements"/></para></listitem>
<!-- <listitem><para><xref linkend="ovm-requirements"/></para></listitem> -->
<listitem><para><xref linkend="lxc-requirements"/></para></listitem>
</itemizedlist>
</section>
</section>

View File

@ -0,0 +1,91 @@
<?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="multiple-ip-nic">
<title>Configuring Multiple IP Addresses on a Single NIC</title>
<para>&PRODUCT; now provides you the ability to associate multiple private IP addresses per guest
VM NIC. This feature is supported on all the network configurations&mdash;Basic, Advanced, and
VPC. Security Groups, Static NAT and Port forwarding services are supported on these additional
IPs. In addition to the primary IP, you can assign additional IPs to the guest VM NIC. Up to 256
IP addresses are allowed per NIC.</para>
<para>As always, you can specify an IP from the guest subnet; if not specified, an IP is
automatically picked up from the guest VM subnet. You can view the IPs associated with for each
guest VM NICs on the UI. You can apply NAT on these additional guest IPs by using firewall
configuration in the &PRODUCT; UI. You must specify the NIC to which the IP should be
associated.</para>
<para>This feature is supported on XenServer, KVM, and VMware hypervisors.</para>
<note>
<para>You need to configure the secondary IP address on the guest VM. &PRODUCT; will
not configure the acquired IP address on the VM. Ensure that you assign IPs to NIC each
time the VM reboots.</para>
</note>
<para>Some of the use cases are described below:</para>
<itemizedlist>
<listitem>
<para>Building network appliances: Network appliances, such as firewalls and load balancers,
generally work best when they have access to multiple IP addresses on the network
interface.</para>
</listitem>
<listitem>
<para>Moving private IP addresses between interfaces or instances. Applications that are bound
to specific IP addresses can be moved between instances. </para>
</listitem>
<listitem>
<para>Hosting multiple SSL Websites on a single instance. You can install multiple SSL
certificates on a single instance, each associated with a distinct IP address.</para>
</listitem>
</itemizedlist>
<section id="workflow-rn">
<title>Assigning Additional IPs to a VM</title>
<orderedlist>
<listitem>
<para>Log in to the &PRODUCT; UI.</para>
</listitem>
<listitem>
<para>In the left navigation bar, click Instances.</para>
</listitem>
<listitem>
<para>Click the name of the instance you want to work with.</para>
</listitem>
<listitem>
<para>In the Details tab, click NICs.</para>
</listitem>
<listitem>
<para>Click View All.</para>
</listitem>
<listitem>
<para>Click Acquire New IP, and click Yes in the confirmation dialog.</para>
<para>You are prompted for confirmation because, typically, IP addresses are a limited
resource. Within a few moments, the new IP address should appear with the state Allocated.
You can now use the IP address in Port Forwarding or StaticNAT rules.</para>
</listitem>
</orderedlist>
</section>
<section id="caveats">
<title>Port Forwarding and StaticNAT Services Changes</title>
<para>Because multiple IPs can be associated per NIC, you are allowed to select a desired IP for
the Port Forwarding and StaticNAT services. The default is the primary IP. To enable this
functionality, an extra optional parameter 'vmguestip' is added to the Port forwarding and
StaticNAT APIs (enableStaticNat, createIpForwardingRule) to indicate on what IP address NAT
need to be configured. If vmguestip is passed, NAT is configured on the specified private IP
of the VM. if not passed, NAT is configured on the primary IP of the VM.</para>
</section>
</section>

View File

@ -32,6 +32,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="using-multiple-guest-networks.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="reserved-ip-addresses-non-csvms.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="multiple-ip-nic.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="security-groups.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="external-firewalls-and-load-balancers.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>

View File

@ -60,6 +60,10 @@
<para>For KVM:</para>
<programlisting># /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h kvm -s &lt;optional-management-server-secret-key&gt; -F</programlisting>
</listitem>
<listitem>
<para>For LXC:</para>
<programlisting># /usr/lib64/cloud/common/scripts/storage/secondary/cloud-install-sys-tmplt -m /mnt/secondary -u http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2 -h lxc -s &lt;optional-management-server-secret-key&gt; -F</programlisting>
</listitem>
</itemizedlist>
</listitem>
<listitem>

View File

@ -28,4 +28,5 @@
<xi:include href="xenserver-topology-req.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="vmware-topology-req.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="kvm-topology-req.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
<xi:include href="lxc-topology-req.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>

View File

@ -32,7 +32,7 @@
<listitem><para>Using the Transifex client and pushing your translated strings to the website.</para></listitem>
</itemizedlist>
</para>
<para>Once a translation is complete, a site admin will pull the translated strings within the &PRODUCT; repository, build the documenation and publish it.</para>
<para>Once a translation is complete, a site admin will pull the translated strings within the &PRODUCT; repository, build the documentation and publish it.</para>
<para>For instructions on how to use the Transifex website see <ulink url="http://sebgoa.blogspot.ch/2012/11/translating-apache-cloudstack-docs-with.html">http://sebgoa.blogspot.ch/2012/11/translating-apache-cloudstack-docs-with.html</ulink></para>
<para>For instructions on how to use the Transifex client to translate from the command line see <ulink url="http://sebgoa.blogspot.ch/2012/12/using-transifex-client-to-translate.html">http://sebgoa.blogspot.ch/2012/12/using-transifex-client-to-translate.html</ulink></para>
</section>

View File

@ -92,7 +92,7 @@ KfEEuzcCUIxtJYTahJ1pvlFkQ8anpuxjSEDp8x/18bq3
<para>After you save the SSH keypair file, you must create an instance by using the template that you created at <xref linkend="create-ssh-template"/>. Ensure that you use the same SSH key name that you created at <xref linkend="create-ssh-keypair"/>.</para>
<note><para>You cannot create the instance by using the GUI at this time and associate the instance with the newly created SSH keypair.</para></note>
<para>A sample curl command to create a new instance is:</para>
<programlisting>curl --globoff http://localhost:&lt;port numbet&gt;/?command=deployVirtualMachine\&amp;zoneId=1\&amp;serviceOfferingId=18727021-7556-4110-9322-d625b52e0813\&amp;templateId=e899c18a-ce13-4bbf-98a9-625c5026e0b5\&amp;securitygroupids=ff03f02f-9e3b-48f8-834d-91b822da40c5\&amp;account=admin\&amp;domainid=1\&amp;keypair=keypair-doc</programlisting>
<programlisting>curl --globoff http://localhost:&lt;port number&gt;/?command=deployVirtualMachine\&amp;zoneId=1\&amp;serviceOfferingId=18727021-7556-4110-9322-d625b52e0813\&amp;templateId=e899c18a-ce13-4bbf-98a9-625c5026e0b5\&amp;securitygroupids=ff03f02f-9e3b-48f8-834d-91b822da40c5\&amp;account=admin\&amp;domainid=1\&amp;keypair=keypair-doc</programlisting>
<para>Substitute the template, service offering and security group IDs (if you are using the security group feature) that are in your cloud environment.</para>
</section>
<section id="logging-in-ssh">

View File

@ -47,11 +47,12 @@
</listitem>
<listitem>
<para>VMware VDS does not support multiple VDS per traffic type. If a user has many VDS
switches, only one can be used for Guest traffic and one for Public traffic.</para>
switches, only one can be used for Guest traffic and another one for Public
traffic.</para>
</listitem>
<listitem>
<para>Management and Storage network does not support VDS and use Standard Switch for these
networks.</para>
<para>Management and Storage network does not support VDS. Therefore, use Standard Switch
for these networks.</para>
</listitem>
</itemizedlist>
</section>
@ -64,7 +65,7 @@
Additionally, &PRODUCT; uses VDS for virtual network infrastructure if the value of
vmware.use.dvswitch parameter is true and the value of vmware.use.nexus.dvswitch parameter is
false.</para>
<para>&PRODUCT; supports configuring virtual networks in a deployment with a mix of Virtual
<para>&PRODUCT; supports orchestration of virtual networks in a deployment with a mix of Virtual
Distributed Switch, Standard Virtual Switch and Nexus 1000v Virtual Switch. </para>
</section>
<section id="config-dvswitch">
@ -100,8 +101,8 @@
</row>
<row>
<entry><para>vCenter Host</para></entry>
<entry><para>Enter the host name or the IP address of the vCenter host where you have
deployed the Nexus virtual switch.</para></entry>
<entry><para>Enter the name or the IP address of the vCenter host where you have deployed the VMware
VDS.</para></entry>
</row>
<row>
<entry><para>vCenter User name</para></entry>
@ -125,13 +126,13 @@
<row>
<entry><para>Public Traffic vSwitch Type</para></entry>
<entry><para>This option is displayed only if you enable the Override Public Traffic
option. Select VMware vNetwork Distributed Virtual Switch. If the
vmware.use.dvswitch global parameter is true, the default option will be VMware
vNetwork Distributed Virtual Switch.</para></entry>
option. Select VMware vNetwork Distributed Virtual Switch. </para>
<para>If the vmware.use.dvswitch global parameter is true, the default option will be
VMware vNetwork Distributed Virtual Switch.</para></entry>
</row>
<row>
<entry><para>Public Traffic vSwitch Name</para></entry>
<entry><para>Specify a name to identify the switch.</para></entry>
<entry><para>Name of virtual switch to be used for the public traffic.</para></entry>
</row>
<row>
<entry><para>Override Guest Traffic</para></entry>
@ -141,24 +142,24 @@
<row>
<entry><para>Guest Traffic vSwitch Type</para></entry>
<entry><para>This option is displayed only if you enable the Override Guest Traffic
option. Select VMware vNetwork Distributed Virtual Switch. If the
vmware.use.dvswitch global parameter is true, the default option will be VMware
vNetwork Distributed Virtual Switch.</para></entry>
option. Select VMware vNetwork Distributed Virtual Switch. </para>
<para>If the vmware.use.dvswitch global parameter is true, the default option will be
VMware vNetwork Distributed Virtual Switch.</para></entry>
</row>
<row>
<entry><para>Guest Traffic vSwitch Name</para></entry>
<entry><para>Specify a name to identify the switch.</para></entry>
<entry><para>Name of virtual switch to be used for guest traffic.</para></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section id="vmware-dvswitch-remove">
<title>Removing Nexus Virtual Switch</title>
<title>Removing VMware Virtual Switch</title>
<orderedlist>
<listitem>
<para>In the vCenter datacenter that is served by the VMware dvSwitch, ensure that you
delete all the hosts in the corresponding cluster.</para>
<para>In the vCenter datacenter that is served by the VDS, ensure that you delete all the
hosts in the corresponding cluster.</para>
</listitem>
<listitem>
<para>Log in with Admin permissions to the &PRODUCT; administrator UI.</para>

View File

@ -1,5 +1,5 @@
<?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" [
<!DOCTYPE chapter 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;
]>
@ -11,7 +11,9 @@
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

View File

@ -68,7 +68,7 @@
<listitem><para>vCenter must be configured to use the standard port 443 so that it can communicate with the &PRODUCT; Management Server.</para></listitem>
<listitem><para>You must re-install VMware ESXi if you are going to re-use a host from a previous install.</para></listitem>
<listitem><para>&PRODUCT; requires VMware vSphere 4.1 or 5.0. VMware vSphere 4.0 is not supported.</para></listitem>
<listitem><para>All hosts must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). All hosts within a cluster must be homogenous. That means the CPUs must be of the same type, count, and feature flags.</para></listitem>
<listitem><para>All hosts must be 64-bit and must support HVM (Intel-VT or AMD-V enabled). All hosts within a cluster must be homogeneous. That means the CPUs must be of the same type, count, and feature flags.</para></listitem>
<listitem><para>The &PRODUCT; management network must not be configured as a separate virtual network. The &PRODUCT; management network is the same as the vCenter management network, and will inherit its configuration. See <xref linkend="vmware-physical-host-networking-config-vcenter-mgt" />.</para></listitem>
<listitem><para>&PRODUCT; requires ESXi. ESX is not supported.</para></listitem>
<listitem><para>All resources used for &PRODUCT; must be used for &PRODUCT; only. &PRODUCT; cannot share instance of ESXi or storage with other management consoles. Do not share the same storage volumes that will be used by &PRODUCT; with a different set of ESXi servers that are not managed by &PRODUCT;.</para></listitem>

View File

@ -21,7 +21,11 @@
<chapter id="whats-new">
<title>What's New in the API?</title>
<para>The following describes any new major features of each &PRODUCT; version as it applies to
API usage.</para>
API usage.</para>
<section id="whats-new-in-api-4.2">
<title>What's New in the API for 4.2</title>
<xi:include href="added-API-commands-4.2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
</section>
<section id="whats-new-in-api-4.1">
<title>What's New in the API for 4.1</title>
<xi:include href="add-remove-nic.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>

View File

@ -82,7 +82,7 @@
<section id="building-documentation">
<title>Building &PRODUCT; Documentation</title>
<para>To build a specific guide, go to the source tree of the documentation in /docs and identify the guide you want to build.</para>
<para>Currenlty there are four guides plus the release notes, all defined in publican configuration files:</para>
<para>Currently there are four guides plus the release notes, all defined in publican configuration files:</para>
<programlisting>
publican-adminguide.cfg
publican-devguide.cfg
@ -96,5 +96,5 @@
</section>
]]>
</programlisting>
<para>Happy Publicaning and DocBooking.</para>
<para>Happy Publicating and DocBooking.</para>
</section>

View File

@ -16,6 +16,6 @@
# specific language governing permissions and limitations
# under the License.
doc_url: "http://incubator.apache.org/cloudstack/docs"
prod_url: "http://cloudstack.org"
doc_url: "http://cloudstack.apache.org/docs"
prod_url: "http://cloudstack.apache.org"

View File

@ -212,7 +212,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
}
DataCenterDeployment reservedPlan = new DataCenterDeployment(vm.getDataCenterId(), vmReservation.getPodId(), vmReservation.getClusterId(),
vmReservation.getHostId(), poolId , null);
vmReservation.getHostId(), null , null);
try{
VMInstanceVO vmDeployed = _itMgr.start(vm, params, _userDao.findById(new Long(caller)), _accountDao.findById(vm.getAccountId()), reservedPlan);
}catch(Exception ex){

View File

@ -704,7 +704,7 @@ setup_vpcrouter() {
fi
cat > /etc/network/interfaces << EOF
auto lo $1
auto lo eth0
iface lo inet loopback
EOF
setup_interface "0" $ETH0_IP $ETH0_MASK $GW

View File

@ -200,7 +200,8 @@ fi
pid=$(pidof dnsmasq)
if [ "$pid" != "" ]
then
service dnsmasq restart
#service dnsmasq restart
kill -HUP $pid
else
if [ $no_redundant -eq 1 ]
then

View File

@ -40,5 +40,10 @@
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-secondary-storage</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -20,6 +20,7 @@ import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
@ -35,7 +36,6 @@ import com.cloud.agent.manager.SimulatorManager;
import com.cloud.agent.manager.SimulatorManager.AgentType;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.storage.resource.SecondaryStorageResource;
import com.cloud.vm.SecondaryStorageVm;

View File

@ -24,6 +24,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -40,9 +41,7 @@ import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.secondary.SecondaryStorageDiscoverer;
import com.cloud.utils.exception.CloudRuntimeException;
import org.springframework.stereotype.Component;
@Local(value=Discoverer.class)

View File

@ -32,6 +32,11 @@
<artifactId>cloud-vmware-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-secondary-storage</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.cloud.com.vmware</groupId>
<artifactId>vmware-vim25</artifactId>

View File

@ -135,10 +135,9 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
if (!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO)){
// user vm
if (diskDeviceType != null){
details.remove(VmDetailConstants.ROOK_DISK_CONTROLLER);
if (diskDeviceType == null){
details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
}
details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
}
to.setDetails(details);

View File

@ -21,6 +21,8 @@ import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;

View File

@ -18,6 +18,7 @@ package com.cloud.storage.resource;
import java.util.List;
import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;

View File

@ -6380,7 +6380,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
String guestOSType = cmd.getGuestOSType();
boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
long timeout = 600;
long timeout = cmd.getWait();
Connection conn = getConnection();
VM vm = null;

View File

@ -274,7 +274,7 @@ PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, Junip
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
firewallCapabilities.put(Capability.MultipleIps, "true");
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress");
firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
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

@ -303,7 +303,7 @@ public class JuniperSrxResource implements ServerResource {
}
private enum Protocol {
tcp, udp, icmp, any;
tcp, udp, icmp, all, any;
}
private enum RuleMatchCondition {
@ -320,7 +320,8 @@ public class JuniperSrxResource implements ServerResource {
private enum SecurityPolicyType {
STATIC_NAT("staticnat"),
DESTINATION_NAT("destnat"),
VPN("vpn");
VPN("vpn"),
SECURITYPOLICY_EGRESS("egress");
private String identifier;
@ -776,6 +777,43 @@ public class JuniperSrxResource implements ServerResource {
s_logger.debug(msg);
}
private Map<String, ArrayList<FirewallRuleTO>> getActiveFirewallEgressRules(FirewallRuleTO[] allRules) {
Map<String, ArrayList<FirewallRuleTO>> activeRules = new HashMap<String, ArrayList<FirewallRuleTO>>();
for (FirewallRuleTO rule : allRules) {
String guestVlan;
guestVlan = rule.getSrcVlanTag();
ArrayList<FirewallRuleTO> activeRulesForNetwork = activeRules.get(guestVlan);
if (activeRulesForNetwork == null) {
activeRulesForNetwork = new ArrayList<FirewallRuleTO>();
}
if (!rule.revoked() || rule.isAlreadyAdded()) {
activeRulesForNetwork.add(rule);
}
activeRules.put(guestVlan, activeRulesForNetwork);
}
return activeRules;
}
private List<String> extractCidrs(List<FirewallRuleTO> rules) throws ExecutionException {
List<String> allCidrs = new ArrayList<String>();
List<String> cidrs = new ArrayList<String>();
for (FirewallRuleTO rule : rules) {
cidrs = (rule.getSourceCidrList());
for (String cidr: cidrs) {
if (!allCidrs.contains(cidr)) {
allCidrs.add(cidr);
}
}
}
return allCidrs;
}
/* security policies */
private synchronized Answer execute(SetFirewallRulesCommand cmd) {
@ -787,24 +825,39 @@ public class JuniperSrxResource implements ServerResource {
FirewallRuleTO[] rules = cmd.getRules();
try {
openConfiguration();
if (rules[0].getTrafficType() == FirewallRule.TrafficType.Egress) {
Map<String, ArrayList<FirewallRuleTO>> activeRules = getActiveFirewallEgressRules(rules);
Set<String> guestVlans = activeRules.keySet();
List<String> cidrs = new ArrayList();
for (FirewallRuleTO rule : rules) {
int startPort = 0, endPort = 0;
if (rule.getSrcPortRange() != null) {
startPort = rule.getSrcPortRange()[0];
endPort = rule.getSrcPortRange()[1];
for (String guestVlan : guestVlans) {
List<FirewallRuleTO> activeRulesForGuestNw = activeRules.get(guestVlan);
removeEgressSecurityPolicyAndApplications(SecurityPolicyType.SECURITYPOLICY_EGRESS, guestVlan, extractCidrs(activeRulesForGuestNw));
if (activeRulesForGuestNw.size() > 0) {
addEgressSecurityPolicyAndApplications(SecurityPolicyType.SECURITYPOLICY_EGRESS, guestVlan, extractApplications(activeRulesForGuestNw), extractCidrs(activeRulesForGuestNw));
}
}
FirewallFilterTerm term = new FirewallFilterTerm(genIpIdentifier(rule.getSrcIp()) + "-" + String.valueOf(rule.getId()), rule.getSourceCidrList(),
rule.getSrcIp(), rule.getProtocol(), startPort, endPort,
rule.getIcmpType(), rule.getIcmpCode(), genIpIdentifier(rule.getSrcIp()) + _usageFilterIPInput.getCounterIdentifier());
if (!rule.revoked()) {
manageFirewallFilter(SrxCommand.ADD, term, _publicZoneInputFilterName);
} else {
manageFirewallFilter(SrxCommand.DELETE, term, _publicZoneInputFilterName);
commitConfiguration();
} else {
for (FirewallRuleTO rule : rules) {
int startPort = 0, endPort = 0;
if (rule.getSrcPortRange() != null) {
startPort = rule.getSrcPortRange()[0];
endPort = rule.getSrcPortRange()[1];
FirewallFilterTerm term = new FirewallFilterTerm(genIpIdentifier(rule.getSrcIp()) + "-" + String.valueOf(rule.getId()), rule.getSourceCidrList(),
rule.getSrcIp(), rule.getProtocol(), startPort, endPort,
rule.getIcmpType(), rule.getIcmpCode(), genIpIdentifier(rule.getSrcIp()) + _usageFilterIPInput.getCounterIdentifier());
if (!rule.revoked()) {
manageFirewallFilter(SrxCommand.ADD, term, _publicZoneInputFilterName);
} else {
manageFirewallFilter(SrxCommand.DELETE, term, _publicZoneInputFilterName);
}
}
commitConfiguration();
}
}
commitConfiguration();
return new Answer(cmd);
} catch (ExecutionException e) {
s_logger.error(e);
@ -992,7 +1045,7 @@ public class JuniperSrxResource implements ServerResource {
// Delete all security policies
for (String securityPolicyName : getVpnObjectNames(SrxXml.SECURITY_POLICY_GETALL, accountId)) {
manageSecurityPolicy(SecurityPolicyType.VPN, SrxCommand.DELETE, accountId, null, null, null, securityPolicyName);
manageSecurityPolicy(SecurityPolicyType.VPN, SrxCommand.DELETE, accountId, null, null, null, null, securityPolicyName);
}
// Delete all address book entries
@ -1064,7 +1117,7 @@ public class JuniperSrxResource implements ServerResource {
manageAddressBookEntry(srxCmd, _privateZone , guestNetworkCidr, ipsecVpnName);
// Security policy
manageSecurityPolicy(SecurityPolicyType.VPN, srxCmd, null, null, guestNetworkCidr, null, ipsecVpnName);
manageSecurityPolicy(SecurityPolicyType.VPN, srxCmd, null, null, guestNetworkCidr, null, null, ipsecVpnName);
}
commitConfiguration();
@ -2455,38 +2508,44 @@ public class JuniperSrxResource implements ServerResource {
* Applications
*/
private String genApplicationName(Protocol protocol, int startPort, int endPort) {
private String genApplicationName(SecurityPolicyType type, Protocol protocol, int startPort, int endPort) {
if (protocol.equals(Protocol.any)) {
return Protocol.any.toString();
} else {
return genObjectName(protocol.toString(), String.valueOf(startPort), String.valueOf(endPort));
if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
return genObjectName(type.getIdentifier(), protocol.toString(), String.valueOf(startPort), String.valueOf(endPort));
} else {
return genObjectName(protocol.toString(), String.valueOf(startPort), String.valueOf(endPort));
}
}
}
private Object[] parseApplicationName(String applicationName) throws ExecutionException {
private Object[] parseApplicationName(SecurityPolicyType type, String applicationName) throws ExecutionException {
String errorMsg = "Invalid application: " + applicationName;
String[] applicationComponents = applicationName.split("-");
Protocol protocol;
Integer startPort;
Integer endPort;
int offset = 0;
try {
protocol = getProtocol(applicationComponents[0]);
startPort = Integer.parseInt(applicationComponents[1]);
endPort = Integer.parseInt(applicationComponents[2]);
} catch (Exception e) {
offset = type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS) ? 1 : 0;
protocol = getProtocol(applicationComponents[offset + 0]);
startPort = Integer.parseInt(applicationComponents[offset + 1]);
endPort = Integer.parseInt(applicationComponents[offset + 2]);
} catch (Exception e) {
throw new ExecutionException(errorMsg);
}
return new Object[]{protocol, startPort, endPort};
}
private boolean manageApplication(SrxCommand command, Protocol protocol, int startPort, int endPort) throws ExecutionException {
private boolean manageApplication(SecurityPolicyType type, SrxCommand command, Protocol protocol, int startPort, int endPort) throws ExecutionException {
if (protocol.equals(Protocol.any)) {
return true;
}
String applicationName = genApplicationName(protocol, startPort, endPort);
String applicationName = genApplicationName(type, protocol, startPort, endPort);
String xml;
switch (command) {
@ -2498,23 +2557,28 @@ public class JuniperSrxResource implements ServerResource {
return sendRequestAndCheckResponse(command, xml, "name", applicationName);
case ADD:
if (manageApplication(SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
if (manageApplication(type, SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
return true;
}
String icmpOrDestPort;
xml = SrxXml.APPLICATION_ADD.getXml();
xml = replaceXmlValue(xml, "name", applicationName);
xml = replaceXmlValue(xml, "protocol", protocol.toString());
String destPort;
if (startPort == endPort) {
destPort = String.valueOf(startPort);
if (protocol.toString() == Protocol.icmp.toString()) {
icmpOrDestPort = "<icmp-type>" + startPort + "</icmp-type>";
icmpOrDestPort += "<icmp-code>" + endPort + "</icmp-code>";
} else {
destPort = startPort + "-" + endPort;
String destPort;
if (startPort == endPort) {
destPort = String.valueOf(startPort);
} else {
destPort = startPort + "-" + endPort;
}
icmpOrDestPort = "<destination-port>" + destPort + "</destination-port>";
}
xml = replaceXmlValue(xml, "dest-port", destPort);
xml = replaceXmlValue(xml, "dest-port-icmp", icmpOrDestPort);
if (!sendRequestAndCheckResponse(command, xml)) {
throw new ExecutionException("Failed to add application " + applicationName);
} else {
@ -2522,7 +2586,7 @@ public class JuniperSrxResource implements ServerResource {
}
case DELETE:
if (!manageApplication(SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
if (!manageApplication(type, SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
return true;
}
@ -2543,13 +2607,13 @@ public class JuniperSrxResource implements ServerResource {
}
private List<String> getUnusedApplications(List<String> applications) throws ExecutionException {
private List<String> getUnusedApplications(List<String> applications, String fromZone, String toZone) throws ExecutionException {
List<String> unusedApplications = new ArrayList<String>();
// Check if any of the applications are unused by existing security policies
String xml = SrxXml.SECURITY_POLICY_GETALL.getXml();
xml = replaceXmlValue(xml, "from-zone", _publicZone);
xml = replaceXmlValue(xml, "to-zone", _privateZone);
xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", toZone);
String allPolicies = sendRequest(xml);
for (String application : applications) {
@ -2560,10 +2624,7 @@ public class JuniperSrxResource implements ServerResource {
return unusedApplications;
}
private List<String> getApplicationsForSecurityPolicy(SecurityPolicyType type, String privateIp) throws ExecutionException {
String fromZone = _publicZone;
String toZone = _privateZone;
private List<String> getApplicationsForSecurityPolicy(SecurityPolicyType type, String privateIp, String fromZone, String toZone) throws ExecutionException {
String policyName = genSecurityPolicyName(type, null, null, fromZone, toZone, privateIp);
String xml = SrxXml.SECURITY_POLICY_GETONE.getXml();
xml = setDelete(xml, false);
@ -2591,8 +2652,31 @@ public class JuniperSrxResource implements ServerResource {
for (FirewallRuleTO rule : rules) {
Object[] application = new Object[3];
application[0] = getProtocol(rule.getProtocol());
application[1] = rule.getSrcPortRange()[0];
application[2] = rule.getSrcPortRange()[1];
if (application[0] == Protocol.icmp) {
if (rule.getIcmpType() == -1) {
application[1] = 255;
} else {
application[1] = rule.getIcmpType();
}
if (rule.getIcmpCode() == -1) {
application[2] = 255;
} else {
application[2] = rule.getIcmpCode();
}
} else if (application[0] == Protocol.tcp || application[0] == Protocol.udp) {
if (rule.getSrcPortRange() != null) {
application[1] = rule.getSrcPortRange()[0];
application[2] = rule.getSrcPortRange()[1];
} else {
application[1] = 0;
application[2] = 65535;
}
} else if (application[0] == Protocol.all) {
application[1] = 0;
application[2] = 65535;
}
applications.add(application);
}
@ -2611,16 +2695,20 @@ public class JuniperSrxResource implements ServerResource {
}
}
private boolean manageSecurityPolicy(SecurityPolicyType type, SrxCommand command, Long accountId, String username, String privateIp, List<String> applicationNames, String ipsecVpnName) throws ExecutionException {
private boolean manageSecurityPolicy(SecurityPolicyType type, SrxCommand command, Long accountId, String username, String privateIp, List<String> applicationNames, List<String> cidrs, String ipsecVpnName) throws ExecutionException {
String fromZone = _publicZone;
String toZone = _privateZone;
String securityPolicyName;
String addressBookEntryName;
String addressBookEntryName = null;
if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) {
securityPolicyName = ipsecVpnName;
addressBookEntryName = ipsecVpnName;
securityPolicyName = ipsecVpnName;
addressBookEntryName = ipsecVpnName;
} else if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
fromZone = _privateZone;
toZone = _publicZone;
securityPolicyName = genSecurityPolicyName(type, accountId, username, fromZone, toZone, privateIp);
} else {
securityPolicyName = genSecurityPolicyName(type, accountId, username, fromZone, toZone, privateIp);
addressBookEntryName = genAddressBookEntryName(privateIp);
@ -2661,17 +2749,38 @@ public class JuniperSrxResource implements ServerResource {
return false;
case ADD:
if (!manageAddressBookEntry(SrxCommand.CHECK_IF_EXISTS, toZone, privateIp, ipsecVpnName)) {
throw new ExecutionException("No address book entry for policy: " + securityPolicyName);
if (!type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
if (!manageAddressBookEntry(SrxCommand.CHECK_IF_EXISTS, toZone, privateIp, addressBookEntryName)) {
throw new ExecutionException("No address book entry for policy: " + securityPolicyName);
}
}
String srcAddrs = "";
String dstAddrs = "";
xml = SrxXml.SECURITY_POLICY_ADD.getXml();
xml = replaceXmlValue(xml, "policy-name", securityPolicyName);
if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
xml = replaceXmlValue(xml, "from-zone", _privateZone);
xml = replaceXmlValue(xml, "to-zone", _publicZone);
if (cidrs == null) {
srcAddrs = "<source-address>any</source-address>";
} else {
for (String cidr : cidrs) {
srcAddrs += "<source-address>" + genAddressBookEntryName(cidr) + "</source-address>";
}
}
xml = replaceXmlValue(xml, "src-address", srcAddrs);
dstAddrs = "<destination-address>any</destination-address>";
xml = replaceXmlValue(xml, "dst-address", dstAddrs);
} else {
xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", toZone);
srcAddrs = "<source-address>any</source-address>";
xml = replaceXmlValue(xml, "src-address", srcAddrs);
dstAddrs = "<destination-address>" + addressBookEntryName + "</destination-address>";
xml = replaceXmlValue(xml, "dst-address", dstAddrs);
}
xml = SrxXml.SECURITY_POLICY_ADD.getXml();
xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", toZone);
xml = replaceXmlValue(xml, "policy-name", securityPolicyName);
xml = replaceXmlValue(xml, "src-address", "any");
xml = replaceXmlValue(xml, "dest-address", addressBookEntryName);
if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) {
xml = replaceXmlValue(xml, "tunnel", "<tunnel><ipsec-vpn>" + ipsecVpnName + "</ipsec-vpn></tunnel>");
} else {
@ -2679,7 +2788,7 @@ public class JuniperSrxResource implements ServerResource {
}
String applications;
if (applicationNames == null) {
if (applicationNames == null || applicationNames.size() == 0) {
applications = "<application>any</application>";
} else {
applications = "";
@ -2697,11 +2806,11 @@ public class JuniperSrxResource implements ServerResource {
}
case DELETE:
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, applicationNames, ipsecVpnName)) {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, applicationNames, cidrs, ipsecVpnName)) {
return true;
}
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, applicationNames, ipsecVpnName)) {
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, applicationNames, cidrs, ipsecVpnName)) {
return true;
}
@ -2757,42 +2866,42 @@ public class JuniperSrxResource implements ServerResource {
int startPort = application[1] != null ? ((Integer) application[1]) : -1;
int endPort = application[2] != null ? ((Integer) application[2]) : -1;
String applicationName = genApplicationName(protocol, startPort, endPort);
String applicationName = genApplicationName(type, protocol, startPort, endPort);
if (!applicationNames.contains(applicationName)) {
applicationNames.add(applicationName);
}
manageApplication(SrxCommand.ADD, protocol, startPort, endPort);
manageApplication(type, SrxCommand.ADD, protocol, startPort, endPort);
}
// Add a new security policy
manageSecurityPolicy(type, SrxCommand.ADD, null, null, privateIp, applicationNames, null);
manageSecurityPolicy(type, SrxCommand.ADD, null, null, privateIp, applicationNames, null, null);
return true;
}
private boolean removeSecurityPolicyAndApplications(SecurityPolicyType type, String privateIp) throws ExecutionException {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, null, null)) {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, null,null, null)) {
return true;
}
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, null, null)) {
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, null, null, null)) {
return true;
}
// Get a list of applications for this security policy
List<String> applications = getApplicationsForSecurityPolicy(type, privateIp);
List<String> applications = getApplicationsForSecurityPolicy(type, privateIp, _publicZone, _privateZone);
// Remove the security policy
manageSecurityPolicy(type, SrxCommand.DELETE, null, null, privateIp, null, null);
// Remove the security policy
manageSecurityPolicy(type, SrxCommand.DELETE, null, null, privateIp, null, null, null);
// Remove any applications for the removed security policy that are no longer in use
List<String> unusedApplications = getUnusedApplications(applications);
List<String> unusedApplications = getUnusedApplications(applications, _publicZone, _privateZone);
for (String application : unusedApplications) {
Object[] applicationComponents;
try {
applicationComponents = parseApplicationName(application);
applicationComponents = parseApplicationName(type, application);
} catch (ExecutionException e) {
s_logger.error("Found an invalid application: " + application + ". Not attempting to clean up.");
continue;
@ -2800,13 +2909,78 @@ public class JuniperSrxResource implements ServerResource {
Protocol protocol = (Protocol) applicationComponents[0];
Integer startPort = (Integer) applicationComponents[1];
Integer endPort = (Integer) applicationComponents[2];
manageApplication(SrxCommand.DELETE, protocol, startPort, endPort);
Integer endPort = (Integer) applicationComponents[2];
manageApplication(type, SrxCommand.DELETE, protocol, startPort, endPort);
}
return true;
}
private boolean removeEgressSecurityPolicyAndApplications(SecurityPolicyType type, String guestVlan, List <String> cidrs) throws ExecutionException {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, guestVlan, null, cidrs, null)) {
return true;
}
// Get a list of applications for this security policy
List<String> applications;
applications = getApplicationsForSecurityPolicy(type, guestVlan, _privateZone, _publicZone);
// Remove the security policy even if it is in use
manageSecurityPolicy(type, SrxCommand.DELETE, null, null, guestVlan, null, cidrs, null);
// Remove any applications for the removed security policy that are no longer in use
List<String> unusedApplications;
unusedApplications = getUnusedApplications(applications, _privateZone, _publicZone);
for (String application : unusedApplications) {
Object[] applicationComponents;
try {
applicationComponents = parseApplicationName(type, application);
} catch (ExecutionException e) {
s_logger.error("Found an invalid application: " + application + ". Not attempting to clean up.");
continue;
}
Protocol protocol = (Protocol) applicationComponents[0];
Integer startPort = (Integer) applicationComponents[1];
Integer endPort = (Integer) applicationComponents[2];
manageApplication(type, SrxCommand.DELETE, protocol, startPort, endPort);
}
for (String cidr: cidrs) {
manageAddressBookEntry(SrxCommand.DELETE, _publicZone, cidr, null);
}
return true;
}
private boolean addEgressSecurityPolicyAndApplications(SecurityPolicyType type, String guestVlan, List<Object[]> applications, List <String> cidrs) throws ExecutionException {
// Add all necessary applications
List<String> applicationNames = new ArrayList<String>();
for (Object[] application : applications) {
Protocol protocol = (Protocol) application[0];
if (!protocol.equals(Protocol.all)) {
int startPort = application[1] != null ? ((Integer) application[1]) : 0;
int endPort = application[2] != null ? ((Integer) application[2]) : 65535;
String applicationName = genApplicationName(type, protocol, startPort, endPort);
if (!applicationNames.contains(applicationName)) {
applicationNames.add(applicationName);
}
manageApplication(type, SrxCommand.ADD, protocol, startPort, endPort);
}
}
for (String cidr: cidrs) {
manageAddressBookEntry(SrxCommand.ADD, _privateZone, cidr, null);
}
// Add a new security policy
manageSecurityPolicy(type, SrxCommand.ADD, null, null, guestVlan, applicationNames, cidrs, null);
s_logger.debug("Added Egress firewall rule for guest network " + guestVlan);
return true;
}
/*
* Filter terms
*/

View File

@ -28,9 +28,9 @@
</parent>
<dependencies>
<dependency>
<groupId>com.cloud.com.citrix</groupId>
<artifactId>netscaler</artifactId>
<version>1.0</version>
<groupId>com.citrix.netscaler.nitro</groupId>
<artifactId>nitro</artifactId>
<version>10.0.e</version>
</dependency>
<dependency>
<groupId>com.cloud.com.citrix</groupId>

View File

@ -317,6 +317,10 @@
<exclude>deps/XenServerJava/Makefile</exclude>
<exclude>dist/console-proxy/js/jquery.js</exclude>
<exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
<exclude>services/console-proxy/server/conf/agent.properties</exclude>
<exclude>services/console-proxy/server/conf/environment.properties</exclude>
<exclude>services/secondary-storage/conf/agent.properties</exclude>
<exclude>services/secondary-storage/conf/environment.properties</exclude>
<exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
<exclude>tools/appliance/definitions/devcloud/*</exclude>
<exclude>tools/appliance/definitions/systemvmtemplate/*</exclude>

View File

@ -23,7 +23,7 @@ under the License.
<application>
<name>%name%</name>
<protocol>%protocol%</protocol>
<destination-port>%dest-port%</destination-port>
%dest-port-icmp%
</application>
</applications>
</configuration>

View File

@ -27,8 +27,8 @@ under the License.
<policy>
<name>%policy-name%</name>
<match>
<source-address>%src-address%</source-address>
<destination-address>%dest-address%</destination-address>
%src-address%
%dst-address%
%applications%
</match>
<then>

View File

@ -22,6 +22,7 @@
# $2 = new private key
#set -x
set -e
TMP=/tmp
MOUNTPATH=${HOME}/systemvm_mnt
@ -29,7 +30,7 @@ TMPDIR=${TMP}/cloud/systemvm
clean_up() {
sudo umount $MOUNTPATH
$SUDO umount $MOUNTPATH
}
inject_into_iso() {
@ -39,23 +40,23 @@ inject_into_iso() {
local tmpiso=${TMP}/$1
mkdir -p $MOUNTPATH
[ ! -f $isofile ] && echo "$(basename $0): Could not find systemvm iso patch file $isofile" && return 1
sudo mount -o loop $isofile $MOUNTPATH
$SUDO mount -o loop $isofile $MOUNTPATH
[ $? -ne 0 ] && echo "$(basename $0): Failed to mount original iso $isofile" && clean_up && return 1
diff -q $MOUNTPATH/authorized_keys $newpubkey &> /dev/null && clean_up && return 0
sudo cp -b $isofile $backup
$SUDO cp -b $isofile $backup
[ $? -ne 0 ] && echo "$(basename $0): Failed to backup original iso $isofile" && clean_up && return 1
rm -rf $TMPDIR
mkdir -p $TMPDIR
[ ! -d $TMPDIR ] && echo "$(basename $0): Could not find/create temporary dir $TMPDIR" && clean_up && return 1
sudo cp -fr $MOUNTPATH/* $TMPDIR/
$SUDO cp -fr $MOUNTPATH/* $TMPDIR/
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy from original iso $isofile" && clean_up && return 1
sudo cp $newpubkey $TMPDIR/authorized_keys
$SUDO cp $newpubkey $TMPDIR/authorized_keys
[ $? -ne 0 ] && echo "$(basename $0): Failed to copy key $newpubkey from original iso to new iso " && clean_up && return 1
mkisofs -quiet -r -o $tmpiso $TMPDIR
[ $? -ne 0 ] && echo "$(basename $0): Failed to create new iso $tmpiso from $TMPDIR" && clean_up && return 1
sudo umount $MOUNTPATH
$SUDO umount $MOUNTPATH
[ $? -ne 0 ] && echo "$(basename $0): Failed to unmount old iso from $MOUNTPATH" && return 1
sudo cp -f $tmpiso $isofile
$SUDO cp -f $tmpiso $isofile
[ $? -ne 0 ] && echo "$(basename $0): Failed to overwrite old iso $isofile with $tmpiso" && return 1
rm -rf $TMPDIR
}
@ -63,12 +64,17 @@ inject_into_iso() {
copy_priv_key() {
local newprivkey=$1
diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0
sudo cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
sudo chmod 644 $(dirname $0)/id_rsa.cloud
$SUDO cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
$SUDO chmod 644 $(dirname $0)/id_rsa.cloud
return $?
}
sudo mkdir -p $MOUNTPATH
if [[ "$EUID" -ne 0 ]]
then
SUDO="sudo "
fi
$SUDO mkdir -p $MOUNTPATH
[ $# -ne 3 ] && echo "Usage: $(basename $0) <new public key file> <new private key file> <systemvm iso path>" && exit 3
newpubkey=$1

View File

@ -995,6 +995,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setPublicIpAddress(ip.getAddress().addr());
if (ip != null && fwRule.getDestinationIpAddress() != null) {
response.setDestNatVmIp(fwRule.getDestinationIpAddress().toString());
UserVm vm = ApiDBUtils.findUserVmById(fwRule.getVirtualMachineId());
if (vm != null) {
response.setVirtualMachineId(vm.getUuid());

View File

@ -397,9 +397,7 @@ public enum Config {
// VMSnapshots
VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "600", "In second, timeout for create vm snapshot", null),
VMSnapshotExpungeInterval("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.expunge.interval", "60", "The interval (in seconds) to wait before running the expunge thread.", null),
VMSnapshotExpungeWorkers("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.expunge.workers", "1", "Number of workers performing expunge ", null),
VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", "default", " DNS name of the cloud", null);

View File

@ -23,48 +23,28 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.network.Network;
import com.cloud.keystore.KeystoreManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineGuru;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineName;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = { ConsoleProxyManager.class })
public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager, VirtualMachineGuru<ConsoleProxyVO>, AgentHook {
public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
@Inject
@ -85,9 +65,25 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
VirtualMachineManager _itMgr;
@Inject
protected ConsoleProxyDao _cpDao;
@Inject
protected KeystoreManager _ksMgr;
@Inject ConfigurationDao _configDao;
public class AgentBasedAgentHook extends AgentHookBase {
public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
KeystoreManager ksMgr, AgentManager agentMgr) {
super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
}
@Override
protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
return _hostDao.findByGuid(cmd.getGuid());
}
}
public int getVncPort(VMInstanceVO vm) {
if (vm.getHostId() == null) {
return -1;
@ -123,11 +119,10 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
_consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
_listener = new ConsoleProxyListener(this);
_listener =
new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
_agentMgr.registerForHostEvents(_listener, true, true, false);
_itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
if (s_logger.isInfoEnabled()) {
s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
}
@ -177,64 +172,8 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
return null;
}
@Override
public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
}
@Override
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
long vmId = 0;
if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Invalid vm id sent from proxy(happens when proxy session has terminated)");
}
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
try {
vmId = Long.parseLong(cmd.getVmId());
} catch (NumberFormatException e) {
s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication", e);
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
// TODO authentication channel between console proxy VM and management
// server needs to be secured,
// the data is now being sent through private network, but this is
// apparently not enough
VMInstanceVO vm = _instanceDao.findById(vmId);
if (vm == null) {
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (vm.getHostId() == null) {
s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
HostVO host = _hostDao.findById(vm.getHostId());
if (host == null) {
s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
String sid = cmd.getSid();
if (sid == null || !sid.equals(vm.getVncPassword())) {
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
return new ConsoleAccessAuthenticationAnswer(cmd, true);
}
@Override
public void onAgentConnect(HostVO host, StartupCommand cmd) {
}
@Override
public void onAgentDisconnect(long agentId, Status state) {
}
@Override
public ConsoleProxyVO startProxy(long proxyVmId) {
@ -269,91 +208,8 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
public void resumeLastManagementState() {
}
@Override
public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
}
@Override
public String getName() {
return _name;
}
@Override
public Long convertToId(String vmName) {
if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
return null;
}
return VirtualMachineName.getConsoleProxyId(vmName);
}
@Override
public ConsoleProxyVO findByName(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public ConsoleProxyVO findById(long id) {
// TODO Auto-generated method stub
return null;
}
@Override
public ConsoleProxyVO persist(ConsoleProxyVO vm) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
// TODO Auto-generated method stub
}
@Override
public void finalizeExpunge(ConsoleProxyVO proxy) {
}
@Override
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());
}
@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());
}
@Override
public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
}
}

View File

@ -0,0 +1,298 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.consoleproxy;
import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.keystore.KeystoreManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value = { ConsoleProxyManager.class })
public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
@Inject
protected HostDao _hostDao;
@Inject
protected UserVmDao _userVmDao;
private String _instance;
protected String _consoleProxyUrlDomain;
@Inject
private VMInstanceDao _instanceDao;
private ConsoleProxyListener _listener;
protected int _consoleProxyUrlPort = ConsoleProxyManager.DEFAULT_PROXY_URL_PORT;
protected int _consoleProxyPort = ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT;
protected boolean _sslEnabled = false;
@Inject
AgentManager _agentMgr;
@Inject
VirtualMachineManager _itMgr;
@Inject
protected ConsoleProxyDao _cpDao;
@Inject
protected KeystoreManager _ksMgr;
@Inject ConfigurationDao _configDao;
public class AgentBasedAgentHook extends AgentHookBase {
public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
KeystoreManager ksMgr, AgentManager agentMgr) {
super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
}
@Override
protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
return _hostDao.findByGuid(cmd.getGuid());
}
}
public int getVncPort(VMInstanceVO vm) {
if (vm.getHostId() == null) {
return -1;
}
GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getHostName()));
return (answer == null || !answer.getResult()) ? -1 : answer.getPort();
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
if (s_logger.isInfoEnabled()) {
s_logger.info("Start configuring AgentBasedConsoleProxyManager");
}
Map<String, String> configs = _configDao.getConfiguration("management-server", params);
String value = configs.get("consoleproxy.url.port");
if (value != null) {
_consoleProxyUrlPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_URL_PORT);
}
value = configs.get("consoleproxy.port");
if (value != null) {
_consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
}
value = configs.get("consoleproxy.sslEnabled");
if (value != null && value.equalsIgnoreCase("true")) {
_sslEnabled = true;
}
_instance = configs.get("instance.name");
_consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
_listener =
new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
_agentMgr.registerForHostEvents(_listener, true, true, false);
if (s_logger.isInfoEnabled()) {
s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
}
return true;
}
HostVO findHost(VMInstanceVO vm) {
return _hostDao.findById(vm.getHostId());
}
@Override
public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
UserVmVO userVm = _userVmDao.findById(userVmId);
if (userVm == null) {
s_logger.warn("User VM " + userVmId + " no longer exists, return a null proxy for user vm:" + userVmId);
return null;
}
HostVO host = findHost(userVm);
if (host != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Assign embedded console proxy running at " + host.getName() + " to user vm " + userVmId + " with public IP "
+ host.getPublicIpAddress());
}
// only private IP, public IP, host id have meaningful values, rest
// of all are place-holder values
String publicIp = host.getPublicIpAddress();
if (publicIp == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host " + host.getName() + "/" + host.getPrivateIpAddress()
+ " does not have public interface, we will return its private IP for cosole proxy.");
}
publicIp = host.getPrivateIpAddress();
}
int urlPort = _consoleProxyUrlPort;
if (host.getProxyPort() != null && host.getProxyPort().intValue() > 0) {
urlPort = host.getProxyPort().intValue();
}
return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain);
} else {
s_logger.warn("Host that VM is running is no longer available, console access to VM " + userVmId + " will be temporarily unavailable.");
}
return null;
}
@Override
public ConsoleProxyVO startProxy(long proxyVmId) {
return null;
}
@Override
public boolean destroyProxy(long proxyVmId) {
return false;
}
@Override
public boolean rebootProxy(long proxyVmId) {
return false;
}
@Override
public boolean stopProxy(long proxyVmId) {
return false;
}
@Override
public void setManagementState(ConsoleProxyManagementState state) {
}
@Override
public ConsoleProxyManagementState getManagementState() {
return null;
}
@Override
public void resumeLastManagementState() {
}
@Override
public String getName() {
return _name;
}
<<<<<<< HEAD
@Override
public Long convertToId(String vmName) {
if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
return null;
}
return VirtualMachineName.getConsoleProxyId(vmName);
}
@Override
public ConsoleProxyVO findByName(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public ConsoleProxyVO findById(long id) {
// TODO Auto-generated method stub
return null;
}
@Override
public ConsoleProxyVO persist(ConsoleProxyVO vm) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
// TODO Auto-generated method stub
}
@Override
public void finalizeExpunge(ConsoleProxyVO proxy) {
}
@Override
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());
}
@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());
}
@Override
public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
}
}
=======
}
>>>>>>> QuickCloud: refactor to avoid copy paste of authentication and startup code

View File

@ -0,0 +1,266 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.consoleproxy;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.keystore.KeystoreManager;
import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.utils.Ternary;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao;
/**
* Utility class to manage interactions with agent-based console access
* Extracted from ConsoleProxyManagerImpl so that other console proxy managers
* can reuse
*/
public abstract class AgentHookBase implements AgentHook {
private static final Logger s_logger = Logger.getLogger(AgentHookBase.class);
VMInstanceDao _instanceDao;
HostDao _hostDao;
ConfigurationDao _configDao;
AgentManager _agentMgr;
KeystoreManager _ksMgr;
final Random _random = new Random(System.currentTimeMillis());
private String _hashKey;
public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr,
AgentManager agentMgr) {
this._instanceDao = instanceDao;
this._hostDao = hostDao;
this._agentMgr = agentMgr;
this._configDao = cfgDao;
this._ksMgr = ksMgr;
}
public String getHashKey() {
// although we may have race condition here, database transaction
// serialization should give us the same key
if (_hashKey == null) {
_hashKey =
_configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), UUID
.randomUUID().toString());
}
return _hashKey;
}
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
Long vmId = null;
String ticketInUrl = cmd.getTicket();
if (ticketInUrl == null) {
s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: "
+ cmd.getVmId());
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-"
+ cmd.getVmId() + " is " + ticketInUrl);
}
if (!cmd.isReauthenticating()) {
String ticket =
ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":"
+ cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
}
if (!ticket.equals(ticketInUrl)) {
Date now = new Date();
// considering of minute round-up
String minuteEarlyTicket =
ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(),
new Date(now.getTime() - 60 * 1000));
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":"
+ cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
}
if (!minuteEarlyTicket.equals(ticketInUrl)) {
s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId()
+ "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
+ minuteEarlyTicket);
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
}
}
if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
}
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
if (vm == null) {
vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
}
if (vm == null) {
s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (vm.getHostId() == null) {
s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
HostVO host = _hostDao.findById(vm.getHostId());
if (host == null) {
s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
String sid = cmd.getSid();
if (sid == null || !sid.equals(vm.getVncPassword())) {
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (cmd.isReauthenticating()) {
ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
authenticationAnswer.setReauthenticating(true);
s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
GetVncPortAnswer answer =
(GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(),
new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
if (answer != null && answer.getResult()) {
Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: "
+ parsedHostInfo.second() + ", tunnel session: " + parsedHostInfo.third());
authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
authenticationAnswer.setTunnelSession(parsedHostInfo.third());
} else {
s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: "
+ parsedHostInfo.first() + ", port: " + answer.getPort());
authenticationAnswer.setHost(parsedHostInfo.first());
authenticationAnswer.setPort(answer.getPort());
}
} else {
s_logger.warn("Re-authentication request failed");
authenticationAnswer.setSuccess(false);
}
return authenticationAnswer;
}
return new ConsoleAccessAuthenticationAnswer(cmd, true);
}
public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
StartConsoleProxyAgentHttpHandlerCommand cmd = null;
if (_configDao.isPremium()) {
String storePassword = String.valueOf(_random.nextLong());
byte[] ksBits =
_ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME,
storePassword);
assert (ksBits != null);
if (ksBits == null) {
s_logger.error("Could not find and construct a valid SSL certificate");
}
cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
cmd.setEncryptorPassword(getHashKey());
} else {
cmd = new StartConsoleProxyAgentHttpHandlerCommand();
cmd.setEncryptorPassword(getHashKey());
}
try {
HostVO consoleProxyHost = findConsoleProxyHost(startupCmd);
assert (consoleProxyHost != null);
Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
} else {
s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
}
} catch (AgentUnavailableException e) {
s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:"
+ startupCmd.getProxyVmId(), e);
} catch (OperationTimedoutException e) {
s_logger.error(
"Unable to send http handling startup command(time out) to the console proxy resource for proxy:"
+ startupCmd.getProxyVmId(), e);
} catch (OutOfMemoryError e) {
s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
System.exit(1);
} catch (Exception e) {
s_logger.error(
"Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:"
+ startupCmd.getProxyVmId(), e);
}
}
protected abstract HostVO findConsoleProxyHost(StartupProxyCommand cmd);
@Override
public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
// no-op since we do not auto-scale
}
@Override
public void onAgentConnect(HostVO host, StartupCommand cmd) {
// no-op
}
@Override
public void onAgentDisconnect(long agentId, Status state) {
// no-op since we do not autoscale
}
}

View File

@ -16,17 +16,9 @@
// under the License.
package com.cloud.consoleproxy;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.Host.Type;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.utils.component.Manager;
import com.cloud.vm.ConsoleProxyVO;
public interface ConsoleProxyManager extends Manager {
public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
public static final int DEFAULT_PROXY_CAPACITY = 50;
public static final int DEFAULT_STANDBY_CAPACITY = 10;
@ -45,16 +37,9 @@ public interface ConsoleProxyManager extends Manager {
public ConsoleProxyManagementState getManagementState();
public void resumeLastManagementState();
public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
public ConsoleProxyVO startProxy(long proxyVmId);
public boolean stopProxy(long proxyVmId);
public boolean rebootProxy(long proxyVmId);
public boolean destroyProxy(long proxyVmId);
public void onLoadReport(ConsoleProxyLoadReportCommand cmd);
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd);
public void onAgentConnect(HostVO host, StartupCommand cmd);
public void onAgentDisconnect(long agentId, Status state);
}

View File

@ -23,26 +23,19 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
import com.cloud.agent.api.GetVncPortAnswer;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
@ -50,11 +43,9 @@ import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
import com.cloud.api.commands.DestroyConsoleProxyCmd;
import com.cloud.certificate.dao.CertificateDao;
import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
@ -68,11 +59,8 @@ import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
@ -109,12 +97,11 @@ import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
@ -126,8 +113,6 @@ import com.cloud.user.UserContext;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GlobalLock;
@ -170,7 +155,8 @@ import com.google.gson.GsonBuilder;
// because sooner or later, it will be driven into Running state
//
@Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class })
public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager, ConsoleProxyService, AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager,
VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
@ -458,7 +444,131 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
private KeystoreDao _ksDao;
@Inject
private KeystoreManager _ksMgr;
private final Random _random = new Random(System.currentTimeMillis());
public class VmBasedAgentHook extends AgentHookBase {
public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
KeystoreManager ksMgr, AgentManager agentMgr) {
super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
}
@Override
public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
if (cmd.getLoadInfo() == null) {
return;
}
ConsoleProxyStatus status = null;
try {
GsonBuilder gb = new GsonBuilder();
gb.setVersion(1.3);
Gson gson = gb.create();
status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
} catch (Throwable e) {
s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
}
if (status != null) {
int count = 0;
if (status.getConnections() != null) {
count = status.getConnections().length;
}
byte[] details = null;
if (cmd.getLoadInfo() != null) {
details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
}
_consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
}
_consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
}
}
@Override
public void onAgentConnect(HostVO host, StartupCommand cmd) {
// no-op
}
@Override
public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
// be it either in alert or in disconnected state, the agent
// process
// may be gone in the VM,
// we will be reacting to stop the corresponding VM and let the
// scan
// process to
HostVO host = _hostDao.findById(agentId);
if (host.getType() == Type.ConsoleProxy) {
String name = host.getName();
if (s_logger.isInfoEnabled()) {
s_logger.info("Console proxy agent disconnected, proxy: " + name);
}
if (name != null && name.startsWith("v-")) {
String[] tokens = name.split("-");
long proxyVmId = 0;
try {
proxyVmId = Long.parseLong(tokens[1]);
} catch (NumberFormatException e) {
s_logger.error("Unexpected exception " + e.getMessage(), e);
return;
}
final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
if (proxy != null) {
// Disable this feature for now, as it conflicts
// with
// the case of allowing user to reboot console proxy
// when rebooting happens, we will receive
// disconnect
// here and we can't enter into stopping process,
// as when the rebooted one comes up, it will kick
// off a
// newly started one and trigger the process
// continue on forever
/*
* _capacityScanScheduler.execute(new Runnable() {
* public void run() { if(s_logger.isInfoEnabled())
* s_logger.info("Stop console proxy " +
* proxy.getName() +
* " VM because of that the agent running inside it has disconnected"
* ); stopProxy(proxy.getId()); } });
*/
} else {
if (s_logger.isInfoEnabled()) {
s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: "
+ name);
}
}
} else {
assert (false) : "Invalid console proxy name: " + name;
}
}
}
}
@Override
protected HostVO findConsoleProxyHost(StartupProxyCommand startupCmd) {
long proxyVmId = startupCmd.getProxyVmId();
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
if (consoleProxy == null) {
s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
return null;
}
assert (consoleProxy != null);
return findConsoleProxyHostByName(consoleProxy.getHostName());
}
}
@Override
public ConsoleProxyInfo assignProxy(final long dataCenterId, final long vmId) {
@ -850,181 +960,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
}
@Override
public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
if (cmd.getLoadInfo() == null) {
return;
}
ConsoleProxyStatus status = null;
try {
GsonBuilder gb = new GsonBuilder();
gb.setVersion(1.3);
Gson gson = gb.create();
status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
} catch (Throwable e) {
s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
}
if (status != null) {
int count = 0;
if (status.getConnections() != null) {
count = status.getConnections().length;
}
byte[] details = null;
if (cmd.getLoadInfo() != null) {
details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
}
_consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
}
_consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
}
}
@Override
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
Long vmId = null;
String ticketInUrl = cmd.getTicket();
if (ticketInUrl == null) {
s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: " + cmd.getVmId());
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticketInUrl);
}
if(!cmd.isReauthenticating()) {
String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
}
if (!ticket.equals(ticketInUrl)) {
Date now = new Date();
// considering of minute round-up
String minuteEarlyTicket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(), new Date(now.getTime() - 60 * 1000));
if (s_logger.isDebugEnabled()) {
s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
}
if (!minuteEarlyTicket.equals(ticketInUrl)) {
s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId() + "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
+ minuteEarlyTicket);
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
}
}
if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
}
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
if (vm == null) {
vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
}
if (vm == null) {
s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if (vm.getHostId() == null) {
s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
HostVO host = _hostDao.findById(vm.getHostId());
if (host == null) {
s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
String sid = cmd.getSid();
if (sid == null || !sid.equals(vm.getVncPassword())) {
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
return new ConsoleAccessAuthenticationAnswer(cmd, false);
}
if(cmd.isReauthenticating()) {
ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
authenticationAnswer.setReauthenticating(true);
s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new
GetVncPortCommand(vm.getId(), vm.getInstanceName()));
if (answer != null && answer.getResult()) {
Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
if(parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: " + parsedHostInfo.second()
+ ", tunnel session: " + parsedHostInfo.third());
authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
authenticationAnswer.setTunnelSession(parsedHostInfo.third());
} else {
s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: " + parsedHostInfo.first()
+ ", port: " + answer.getPort());
authenticationAnswer.setHost(parsedHostInfo.first());
authenticationAnswer.setPort(answer.getPort());
}
} else {
s_logger.warn("Re-authentication request failed");
authenticationAnswer.setSuccess(false);
}
return authenticationAnswer;
}
return new ConsoleAccessAuthenticationAnswer(cmd, true);
}
@Override
public void onAgentConnect(HostVO host, StartupCommand cmd) {
// if (host.getType() == Type.ConsoleProxy) {
// // TODO we can use this event to mark the proxy is up and
// // functioning instead of
// // pinging the console proxy VM command port
// //
// // for now, just log a message
// if (s_logger.isInfoEnabled()) {
// s_logger.info("Console proxy agent is connected. proxy: " + host.getName());
// }
//
// /* update public/private ip address */
// if (_IpAllocator != null && _IpAllocator.exteralIpAddressAllocatorEnabled()) {
// try {
// ConsoleProxyVO console = findConsoleProxyByHost(host);
// if (console == null) {
// s_logger.debug("Can't find console proxy ");
// return;
// }
// console.setPrivateIpAddress(cmd.getPrivateIpAddress());
// console.setPublicIpAddress(cmd.getPublicIpAddress());
// console.setPublicNetmask(cmd.getPublicNetmask());
// _consoleProxyDao.persist(console);
// } catch (NumberFormatException e) {
// }
// }
// }
}
@Override
public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
// be it either in alert or in disconnected state, the agent process
// may be gone in the VM,
@ -1499,7 +1437,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
value = agentMgrConfigs.get("port");
_mgmt_port = NumbersUtil.parseInt(value, 8250);
_listener = new ConsoleProxyListener(this);
_listener =
new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr,
_agentMgr));
_agentMgr.registerForHostEvents(_listener, true, true, false);
_itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
@ -1549,18 +1489,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
return true;
}
@Override
public boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd) throws ServerApiException {
Long proxyId = cmd.getId();
// verify parameters
ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyId);
if (proxy == null) {
throw new InvalidParameterValueException("unable to find a console proxy with id " + proxyId);
}
return destroyProxy(proxyId);
}
protected ConsoleProxyManagerImpl() {
}
@ -1733,52 +1662,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
_consoleProxyDao.update(proxy.getId(), proxy);
}
@Override
public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
StartConsoleProxyAgentHttpHandlerCommand cmd = null;
if (_configDao.isPremium()) {
String storePassword = String.valueOf(_random.nextLong());
byte[] ksBits = _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME, storePassword);
assert (ksBits != null);
if (ksBits == null) {
s_logger.error("Could not find and construct a valid SSL certificate");
}
cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
cmd.setEncryptorPassword(getHashKey());
} else {
cmd = new StartConsoleProxyAgentHttpHandlerCommand();
cmd.setEncryptorPassword(getHashKey());
}
try {
long proxyVmId = startupCmd.getProxyVmId();
ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
if (consoleProxy == null) {
s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
return;
}
assert (consoleProxy != null);
HostVO consoleProxyHost = findConsoleProxyHostByName(consoleProxy.getHostName());
Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
} else {
s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
}
} catch (AgentUnavailableException e) {
s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
} catch (OperationTimedoutException e) {
s_logger.error("Unable to send http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
} catch (OutOfMemoryError e) {
s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
System.exit(1);
} catch (Exception e) {
s_logger.error("Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
}
}
@Override
public ConsoleProxyVO persist(ConsoleProxyVO proxy) {

View File

@ -16,8 +16,10 @@
// under the License.
package com.cloud.consoleproxy;
import com.cloud.api.commands.DestroyConsoleProxyCmd;
import com.cloud.info.ConsoleProxyInfo;
public interface ConsoleProxyService {
boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd);
}
public abstract ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
}

View File

@ -16,29 +16,59 @@
// under the License.
package com.cloud.consoleproxy;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.springframework.stereotype.Component;
import org.apache.log4j.Logger;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyInfo;
import com.cloud.keystore.KeystoreDao;
import com.cloud.keystore.KeystoreManager;
import com.cloud.resource.ResourceManager;
import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.utils.NumbersUtil;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.ConsoleProxyDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value={ConsoleProxyManager.class})
public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager {
String _ip = null;
@Inject ConsoleProxyDao _proxyDao;
@Inject ResourceManager _resourceMgr;
@Inject ConfigurationDao _configDao;
public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager,
ResourceStateAdapter {
private static final Logger s_logger = Logger.getLogger(StaticConsoleProxyManager.class);
@Inject
ConsoleProxyDao _proxyDao;
@Inject
ResourceManager _resourceMgr;
@Inject
ConfigurationDao _configDao;
@Inject
private VMInstanceDao _instanceDao;
@Inject
KeystoreDao _ksDao;
@Inject
private KeystoreManager _ksMgr;
@Inject
private HostDao _hostDao;
private final Random _random = new Random(System.currentTimeMillis());
private String _hashKey;
private String _ip = null;
@Override
protected HostVO findHost(VMInstanceVO vm) {
@ -50,20 +80,52 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
@Override
public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
return new ConsoleProxyInfo(false, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
return new ConsoleProxyInfo(_sslEnabled, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
Map<String, String> dbParams = _configDao.getConfiguration("ManagementServer", params);
_ip = dbParams.get("public.ip");
_ip = _configDao.getValue("consoleproxy.static.publicIp");
if (_ip == null) {
_ip = "127.0.0.1";
}
String value = (String) params.get("consoleproxy.sslEnabled");
if (value != null && value.equalsIgnoreCase("true")) {
_sslEnabled = true;
}
int defaultPort = 8088;
if (_sslEnabled)
defaultPort = 8443;
_consoleProxyUrlPort = NumbersUtil.parseInt(_configDao.getValue("consoleproxy.static.port"), defaultPort);
_resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
return true;
}
@Override
public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
if (!(cmd[0] instanceof StartupProxyCommand)) {
return null;
}
host.setType(com.cloud.host.Host.Type.ConsoleProxy);
return host;
}
@Override
public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource,
Map<String, String> details, List<String> hostTags) {
return null;
}
@Override
public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage)
throws UnableDeleteHostException {
return null;
}
}

View File

@ -102,7 +102,7 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
@Inject protected StorageManager _storageMgr;
@Inject DataStoreManager dataStoreMgr;
@Inject protected ClusterDetailsDao _clusterDetailsDao;
protected List<StoragePoolAllocator> _storagePoolAllocators;
public List<StoragePoolAllocator> getStoragePoolAllocators() {
return _storagePoolAllocators;
@ -157,7 +157,8 @@ public class FirstFitPlanner extends PlannerBase implements DeploymentPlanner {
if(plan.getHostId() != null && haVmTag == null){
Long hostIdSpecified = plan.getHostId();
if (s_logger.isDebugEnabled()){
s_logger.debug("DeploymentPlan has host_id specified, making no checks on this host, looks like admin test: "+hostIdSpecified);
s_logger.debug("DeploymentPlan has host_id specified, choosing this host and making no checks on this host: "
+ hostIdSpecified);
}
HostVO host = _hostDao.findById(hostIdSpecified);
if (host == null) {

View File

@ -33,4 +33,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao<HypervisorCapabili
Integer getMaxDataVolumesLimit(HypervisorType hypervisorType, String hypervisorVersion);
Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion);
Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion);
}

View File

@ -95,4 +95,11 @@ public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase<HypervisorCapa
HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
return result.getMaxHostsPerCluster();
}
@Override
public Boolean isVmSnapshotEnabled(HypervisorType hypervisorType,
String hypervisorVersion) {
HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
return result.getVmSnapshotEnabled();
}
}

View File

@ -1,3 +1,4 @@
// 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
@ -541,8 +542,15 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl
if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
_fwRulesDao.loadSourceCidrs((FirewallRuleVO)rule);
}
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr());
FirewallRuleTO ruleTO;
if (rule.getPurpose() == Purpose.Firewall && rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
String guestVlanTag = network.getBroadcastUri().getHost();
String guestCidr = network.getCidr();
ruleTO = new FirewallRuleTO(rule, guestVlanTag, rule.getTrafficType());
} else {
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr());
}
rulesTO.add(ruleTO);
}

View File

@ -968,9 +968,21 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
// diff between offering #1 and #2 - securityGroup is enabled for the first, and disabled for the third
NetworkOfferingVO offering = null;
if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
offering =
_configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices,
"Offering for QuickCloud with no services", TrafficType.Guest, null, true,
Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true,
Network.GuestType.Shared, false, null, true, null, true, false);
offering.setState(NetworkOffering.State.Enabled);
_networkOfferingDao.update(offering.getId(), offering);
}
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null,
true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false);
offering =
_configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
"Offering for Shared Security group enabled networks", TrafficType.Guest, null, true,
Availability.Optional, null, defaultSharedNetworkOfferingProviders, true,
Network.GuestType.Shared, false, null, true, null, true, false);
offering.setState(NetworkOffering.State.Enabled);
_networkOfferingDao.update(offering.getId(), offering);
}

View File

@ -179,6 +179,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
private List<VpcProvider> vpcElements = null;
private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp);
int _cleanupInterval;
int _maxNetworks;
@ -1054,9 +1055,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
//1) in current release, only vpc provider is supported by Vpc offering
List<Provider> providers = _ntwkModel.getNtwkOffDistinctProviders(guestNtwkOff.getId());
for (Provider provider : providers) {
if (provider != Provider.VPCVirtualRouter) {
throw new InvalidParameterValueException("Only provider of type " + Provider.VPCVirtualRouter.getName()
+ " is supported for network offering that can be used in VPC");
if (!supportedProviders.contains(provider) ) {
throw new InvalidParameterValueException("Provider of type " + provider.getName()
+ " is not supported for network offerings that can be used in VPC");
}
}

View File

@ -25,8 +25,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Command;
import com.cloud.configuration.Config;
@ -90,6 +88,10 @@ public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerI
@Override
public Pair<AfterScanAction, Object> scanPool(Long pool) {
long dataCenterId = pool.longValue();
if (!isSecondaryStorageVmRequired(dataCenterId)) {
return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
}
Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
_cmdExecLogDao.expungeExpiredRecords(cutTime);

View File

@ -37,21 +37,17 @@ import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.storage.DeleteTemplateCommand;
import com.cloud.agent.api.storage.DeleteVolumeCommand;
import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadCommand.Proxy;
import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.ListTemplateCommand;
import com.cloud.agent.api.storage.ListVolumeAnswer;
import com.cloud.agent.api.storage.ListVolumeCommand;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.configuration.Config;
@ -72,13 +68,12 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.resource.ResourceManager;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageManager;
import com.cloud.storage.SwiftVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.VolumeHostVO;
import com.cloud.storage.VolumeVO;
@ -91,7 +86,6 @@ import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeHostDao;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
import com.cloud.storage.swift.SwiftManager;
import com.cloud.storage.template.TemplateConstants;
@ -284,10 +278,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
String sourceChecksum = this.templateMgr.getChecksum(srcTmpltHost.getHostId(), srcTmpltHost.getInstallPath());
DownloadCommand dcmd =
new DownloadCommand(destServer.getStorageUrl(), url, template, TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes);
dcmd.setProxy(getHttpProxy());
if (downloadJobExists) {
dcmd = new DownloadProgressCommand(dcmd, destTmpltHost.getJobId(), RequestType.GET_OR_RESTART);
}
dcmd.setProxy(getHttpProxy());
dcmd.setChecksum(sourceChecksum); // We need to set the checksum as the source template might be a compressed url and have cksum for compressed image. Bug #10775
HostVO ssAhost = _ssvmMgr.pickSsvmHost(destServer);
if( ssAhost == null ) {
@ -369,10 +363,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
start();
DownloadCommand dcmd =
new DownloadCommand(secUrl, template, maxTemplateSizeInBytes);
dcmd.setProxy(getHttpProxy());
if (downloadJobExists) {
dcmd = new DownloadProgressCommand(dcmd, vmTemplateHost.getJobId(), RequestType.GET_OR_RESTART);
}
dcmd.setProxy(getHttpProxy());
if (vmTemplateHost.isCopy()) {
dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd);
}
@ -458,12 +452,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
if(volumeHost != null) {
start();
DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format);
dcmd.setProxy(getHttpProxy());
if (downloadJobExists) {
dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART);
dcmd.setResourceType(ResourceType.VOLUME);
}
dcmd.setProxy(getHttpProxy());
HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver);
if( ssvm == null ) {
s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName());
@ -858,7 +851,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
toBeDownloaded.remove(tmplt);
if (tmpltHost != null) {
s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
s_logger.info("Template Sync found " + tmplt.getName() + " already in the template host table");
if (tmpltHost.getDownloadState() != Status.DOWNLOADED) {
tmpltHost.setErrorString("");
}
@ -918,10 +911,12 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
continue;
}
if (tmpltHost != null && tmpltHost.getDownloadState() != Status.DOWNLOADED) {
s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + sserverId + ", will request download to start/resume shortly");
s_logger.info("Template Sync did not find " + tmplt.getName() + " ready on server " + sserverId
+ ", will request download to start/resume shortly");
} else if (tmpltHost == null) {
s_logger.info("Template Sync did not find " + uniqueName + " on the server " + sserverId + ", will request download shortly");
s_logger.info("Template Sync did not find " + tmplt.getName() + " on the server " + sserverId
+ ", will request download shortly");
VMTemplateHostVO templtHost = new VMTemplateHostVO(sserverId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
_vmTemplateHostDao.persist(templtHost);
VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
@ -971,6 +966,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
}
s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName());
downloadTemplateToStorage(tmplt, ssHost);
} else {
s_logger.info("Skipping download of template " + tmplt.getName() + " since we don't have any "
+ tmplt.getHypervisorType() + " hypervisors");
}
}
}

View File

@ -30,8 +30,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
@ -98,8 +96,8 @@ import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
@ -474,7 +472,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
}
private boolean isSecondaryStorageVmRequired(long dcId) {
protected boolean isSecondaryStorageVmRequired(long dcId) {
DataCenterVO dc = _dcDao.findById(dcId);
_dcDao.loadDetails(dc);
String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
@ -1066,10 +1064,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
} else {
s_logger.debug("Telling the ssvm to load the NfsSecondaryStorageResource");
buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
}
} else {
buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
}
buf.append(" instance=SecStorage");
buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));

View File

@ -65,6 +65,7 @@ public class Upgrade410to420 implements DbUpgrade {
updateSystemVmTemplates(conn);
updateCluster_details(conn);
updatePrimaryStore(conn);
addEgressFwRulesForSRXGuestNw(conn);
}
private void updateSystemVmTemplates(Connection conn) {
@ -305,4 +306,63 @@ public class Upgrade410to420 implements DbUpgrade {
}
}
}
private void addEgressFwRulesForSRXGuestNw(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
ResultSet rsId = null;
ResultSet rsNw = null;
try {
pstmt = conn.prepareStatement("select network_id FROM `cloud`.`ntwk_service_map` where service='Firewall' and provider='JuniperSRX' ");
rs = pstmt.executeQuery();
while (rs.next()) {
long netId = rs.getLong(1);
//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) {
}
}
}
}

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