diff --git a/LICENSE.header b/LICENSE.header index 4eacb643179..60b675e3101 100644 --- a/LICENSE.header +++ b/LICENSE.header @@ -1,16 +1,16 @@ Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file +or more contributor license agreements. See the NOTICE file distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file +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 +with the License. You may obtain a copy of the License at -http://www.apache.org/licenses/LICENSE-2.0 + 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 +KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties index 5f5f3682afd..a7376b68947 100644 --- a/agent/conf/agent.properties +++ b/agent/conf/agent.properties @@ -114,3 +114,7 @@ domr.scripts.dir=scripts/network/domr/kvm # for examples:"Conroe" "Penryn", "Nehalem", "Westmere", "pentiumpro" and so # on,run virsh capabilities for more details. # guest.cpu.model= +# +# vm.memballoon.disable=true +# Disable memory ballooning on vm guests for overcommit, by default overcommit +# feature enables balloon and sets currentMemory to a minimum value. diff --git a/scripts/network/domr/s2s_vpn.sh b/api/resources/META-INF/cloudstack/api-config/module.properties old mode 100755 new mode 100644 similarity index 80% rename from scripts/network/domr/s2s_vpn.sh rename to api/resources/META-INF/cloudstack/api-config/module.properties index 3ec3e260636..3b2a85d2743 --- a/scripts/network/domr/s2s_vpn.sh +++ b/api/resources/META-INF/cloudstack/api-config/module.properties @@ -1,4 +1,3 @@ -#!/bin/bash # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,15 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - - - - -# @VERSION@ - -cert="/root/.ssh/id_rsa.cloud" -domr=$1 -shift -ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/ipsectunnel.sh $*" >/dev/null - -exit $? +name=api-config +parent=core diff --git a/api/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml b/api/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml new file mode 100644 index 00000000000..2cd12663072 --- /dev/null +++ b/api/resources/META-INF/cloudstack/api-config/spring-api-config-context.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/com/cloud/agent/api/to/IpAddressTO.java index 5f31313eba9..1169820e19a 100644 --- a/api/src/com/cloud/agent/api/to/IpAddressTO.java +++ b/api/src/com/cloud/agent/api/to/IpAddressTO.java @@ -33,6 +33,8 @@ public class IpAddressTO { private Integer networkRate; private TrafficType trafficType; private String networkName; + private Integer nicDevId; + private boolean newNic; public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String broadcastUri, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, boolean isOneToOneNat) { @@ -116,4 +118,19 @@ public class IpAddressTO { return networkRate; } + public Integer getNicDevId() { + return nicDevId; + } + + public void setNicDevId(Integer nicDevId) { + this.nicDevId = nicDevId; + } + + public boolean isNewNic() { + return newNic; + } + + public void setNewNic(boolean newNic) { + this.newNic = newNic; + } } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 2197c2b7143..62151a4f0c0 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -112,7 +112,7 @@ public interface Network extends ControlledEntity, StateObject, I private static List supportedProviders = new ArrayList(); public static final Provider VirtualRouter = new Provider("VirtualRouter", false); - public static final Provider JuniperContrail = new Provider("JuniperContrail", false); + public static final Provider JuniperContrailRouter = new Provider("JuniperContrailRouter", false); public static final Provider JuniperSRX = new Provider("JuniperSRX", true); public static final Provider PaloAlto = new Provider("PaloAlto", true); public static final Provider F5BigIp = new Provider("F5BigIp", true); diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 250121e452b..1731b119d5e 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -110,7 +110,7 @@ public interface NetworkService { long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType); - PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel); PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id); diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index b2c04cda00c..1e4d2294641 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -94,7 +94,22 @@ public class Networks { return uri.getSchemeSpecificPart(); } }, - Mido("mido", String.class), Pvlan("pvlan", String.class), Vxlan("vxlan", Long.class), UnDecided(null, null), OpenDaylight("opendaylight", String.class); + Mido("mido", String.class), Pvlan("pvlan", String.class), + Vxlan("vxlan", Long.class) { + @Override + public URI toUri(T value) { + try { + if (value.toString().contains("://")) + return new URI(value.toString()); + else + return new URI("vxlan://" + value.toString()); + } catch (URISyntaxException e) { + throw new CloudRuntimeException( + "Unable to convert to broadcast URI: " + value); + } + } + }, + UnDecided(null, null), OpenDaylight("opendaylight", String.class); private final String scheme; private final Class type; diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 5c348c21b7a..8cc214e894b 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -33,7 +33,7 @@ public interface PhysicalNetwork extends Identity, InternalIdentity { } public enum IsolationMethod { - VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL; + VLAN, L3, GRE, STT, VNS, MIDO, SSP, VXLAN, ODL, L3VPN; } public enum BroadcastDomainRange { diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index fa3ef6d2395..a9d9c527f40 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -69,5 +69,5 @@ public interface VirtualNetworkApplianceService { List upgradeRouterTemplate(UpgradeRouterTemplateCmd cmd); - public static final String MinVRVersion = "4.2.0"; + public static final String MinVRVersion = "4.3.0"; } diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java index 4cfa42b3770..274242ad394 100644 --- a/api/src/com/cloud/network/rules/FirewallRule.java +++ b/api/src/com/cloud/network/rules/FirewallRule.java @@ -36,7 +36,8 @@ public interface FirewallRule extends ControlledEntity, Identity, InternalIdenti Staged, // Rule been created but has never got through network rule conflict detection. Rules in this state can not be sent to network elements. Add, // Add means the rule has been created and has gone through network rule conflict detection. Active, // Rule has been sent to the network elements and reported to be active. - Revoke // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Revoke, // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } enum TrafficType { diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/com/cloud/network/vpc/StaticRoute.java index ccdbec899b8..5707ca14024 100644 --- a/api/src/com/cloud/network/vpc/StaticRoute.java +++ b/api/src/com/cloud/network/vpc/StaticRoute.java @@ -25,7 +25,8 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router. Add, // Add means the route has been created and has gone through network rule conflict detection. Active, // Route has been sent to the VPC router and reported to be active. - Revoke // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Revoke, // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } /** diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 89458fc9614..41931f0949b 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -24,25 +24,49 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit // FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code public enum ResourceObjectType { - UserVm(true, true), Template(true, true), ISO(true, false), Volume(true, true), Snapshot(true, false), Network(true, true), Nic(false, true), LoadBalancer(true, true), PortForwardingRule( - true, true), FirewallRule(true, true), SecurityGroup(true, false), PublicIpAddress(true, true), Project(true, false), Vpc(true, true), NetworkACL(true, true), StaticRoute( - true, false), VMSnapshot(true, false), RemoteAccessVpn(true, true), Zone(false, true), ServiceOffering(false, true), Storage(false, true), PrivateGateway(false, - true), NetworkACLList(false, true), VpnGateway(false, true), CustomerGateway(false, true), VpnConnection(false, true), User(true, true), DiskOffering(false, true); + UserVm(true, true), + Template(true, true), + ISO(true, false), + Volume(true, true), + Snapshot(true, false), + Network(true, true), + Nic(false, true), + LoadBalancer(true, true), + PortForwardingRule(true, true), + FirewallRule(true, true), + SecurityGroup(true, false), + PublicIpAddress(true, true), + Project(true, false), + Vpc(true, true), + NetworkACL(true, true), + StaticRoute(true, false), + VMSnapshot(true, false), + RemoteAccessVpn(true, true), + Zone(false, true), + ServiceOffering(false, true), + Storage(false, true), + PrivateGateway(false, true), + NetworkACLList(false, true), + VpnGateway(false, true), + CustomerGateway(false, true), + VpnConnection(false, true), + User(true, true), + DiskOffering(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; - this.metadataSupport = resourceMetadataSupport; + metadataSupport = resourceMetadataSupport; } private final boolean resourceTagsSupport; private final boolean metadataSupport; public boolean resourceTagsSupport() { - return this.resourceTagsSupport; + return resourceTagsSupport; } public boolean resourceMetadataSupport() { - return this.metadataSupport; + return metadataSupport; } } diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index e02573d7605..51a8fdfbe38 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -461,4 +461,12 @@ public interface UserVmService { UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException; + /** + * Finds and returns an encrypted password for a VM. + * + * @param userVmId + * @return Base64 encoded userdata + */ + String getVmUserData(long vmId); + } diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 52b947fe287..d6e70a8a6cf 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -124,6 +124,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I s_fsm.addTransition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped); s_fsm.addTransition(State.Running, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped); s_fsm.addTransition(State.Migrating, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped); + s_fsm.addTransition(State.Stopped, VirtualMachine.Event.FollowAgentPowerOffReport, State.Stopped); } public static boolean isVmStarted(State oldState, Event e, State newState) { diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 287fff3035b..d500303bcac 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -344,6 +344,7 @@ public class ApiConstants { public static final String CAPACITY_IOPS = "capacityiops"; public static final String NETWORK_SPEED = "networkspeed"; public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange"; + public static final String ISOLATION_METHOD = "isolationmethod"; public static final String ISOLATION_METHODS = "isolationmethods"; public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid"; public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid"; diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 0cfb9509395..4229ec9302b 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -26,6 +26,8 @@ import java.util.regex.Pattern; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.affinity.AffinityGroupService; import org.apache.cloudstack.alert.AlertService; import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; @@ -33,7 +35,6 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; import org.apache.cloudstack.query.QueryService; import org.apache.cloudstack.usage.UsageService; -import org.apache.log4j.Logger; import com.cloud.configuration.ConfigurationService; import com.cloud.domain.Domain; @@ -153,8 +154,6 @@ public abstract class BaseCmd { @Inject public ResourceLimitService _resourceLimitService; @Inject - public IdentityService _identityService; - @Inject public StorageNetworkService _storageNetworkService; @Inject public TaggedResourceService _taggedResourceService; @@ -358,11 +357,11 @@ public abstract class BaseCmd { } public void setFullUrlParams(Map map) { - this.fullUrlParams = map; + fullUrlParams = map; } public Map getFullUrlParams() { - return this.fullUrlParams; + return fullUrlParams; } public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java index e6e18cb9ffa..0fcb8f87e54 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java @@ -77,6 +77,10 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN id to be used for Management traffic by VMware host") private String vlan; + @Parameter(name=ApiConstants.ISOLATION_METHOD, type=CommandType.STRING, description="Used if physical network has multiple isolation types and traffic type is public." + + " Choose which isolation method. Valid options currently 'vlan' or 'vxlan', defaults to 'vlan'.") + private String isolationMethod; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,6 +122,14 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { return vlan; } + public String getIsolationMethod() { + if (isolationMethod != null && !isolationMethod.isEmpty()) { + return isolationMethod; + } else { + return "vlan"; + } + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -148,7 +160,7 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { PhysicalNetworkTrafficType result = - _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getXenLabel(), getKvmLabel(), getVmwareLabel(), + _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getIsolationMethod(), getXenLabel(), getKvmLabel(), getVmwareLabel(), getSimulatorLabel(), getVlan(), getHypervLabel()); if (result != null) { setEntityId(result.getId()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java new file mode 100644 index 00000000000..0e527149821 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/vm/GetVMUserDataCmd.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.cloudstack.api.command.admin.vm; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.UserVmResponse; +import org.apache.cloudstack.api.response.VMUserDataResponse; +import org.apache.log4j.Logger; + +import com.cloud.user.Account; +import com.cloud.uservm.UserVm; + +@APICommand(name = "getVirtualMachineUserData", description = "Returns user data associated with the VM", responseObject = VMUserDataResponse.class, since = "4.4") +public class GetVMUserDataCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(GetVMUserDataCmd.class); + private static final String s_name = "getvirtualmachineuserdataresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "The ID of the virtual machine") + private Long vmId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public long getId() { + return vmId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() { + String userData = _userVmService.getVmUserData(getId()); + VMUserDataResponse resp = new VMUserDataResponse(); + resp.setVmId(_entityMgr.findById(UserVm.class, getId()).getUuid()); + resp.setUserData(userData); + resp.setObjectName("virtualmachineuserdata"); + resp.setResponseName(getCommandName()); + this.setResponseObject(resp); + } + + @Override + public long getEntityOwnerId() { + UserVm userVm = _entityMgr.findById(UserVm.class, getId()); + if (userVm != null) { + return userVm.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getCommandName() { + return s_name; + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index c0e8d3e16a6..439879add9b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -130,7 +130,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { try { result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress()); } catch (InsufficientAddressCapacityException e) { - throw new InvalidParameterValueException("Allocating guest ip for nic failed"); + throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage()); } if (result != null) { diff --git a/api/src/org/apache/cloudstack/api/response/VMUserDataResponse.java b/api/src/org/apache/cloudstack/api/response/VMUserDataResponse.java new file mode 100644 index 00000000000..1b739e56442 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/VMUserDataResponse.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.cloudstack.api.response; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class VMUserDataResponse extends BaseResponse { + @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) + @Param(description = "the ID of the virtual machine") + private String vmId; + + @SerializedName(ApiConstants.USER_DATA) + @Param(description = "Base 64 encoded VM user data") + private String userData; + + public void setUserData(String userData) { + this.userData = userData; + } + + public void setVmId(String vmId) { + this.vmId = vmId; + } + +} diff --git a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java new file mode 100644 index 00000000000..edf5a21b673 --- /dev/null +++ b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java @@ -0,0 +1,40 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.config; + +import javax.ejb.Local; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; + +@Local(value = {ApiServiceConfiguration.class}) +public class ApiServiceConfiguration implements Configurable { + public static final ConfigKey ManagementHostIPAdr = new ConfigKey("Advanced", String.class, "host", "localhost", "The ip address of management server", true); + public static final ConfigKey ApiServletPath = new ConfigKey("Advanced", String.class, "api.servlet.endpoint", "http://localhost:8080/client/api?", + "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", true); + + @Override + public String getConfigComponentName() { + return ApiServiceConfiguration.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {ManagementHostIPAdr, ApiServletPath}; + } + +} diff --git a/awsapi/pom.xml b/awsapi/pom.xml index f0312309b98..4a6c89c9e5f 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -142,7 +142,7 @@ org.opensaml - opensaml + opensaml1 @@ -162,7 +162,7 @@ org.opensaml - opensaml + opensaml1 @@ -178,7 +178,7 @@ org.opensaml - opensaml + opensaml1 @@ -194,7 +194,7 @@ org.opensaml - opensaml + opensaml1 @@ -210,7 +210,7 @@ org.opensaml - opensaml + opensaml1 @@ -223,7 +223,6 @@ org.slf4j slf4j-api - 1.6.1 runtime @@ -271,8 +270,6 @@ org.bouncycastle bcprov-jdk16 - - 1.45 runtime @@ -320,9 +317,9 @@ org.apache.maven.plugins maven-checkstyle-plugin - ${cs.checkstyle.version} + cloudstack-checkstyle none diff --git a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java index 60f974a5e1d..ef7539f7350 100644 --- a/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java +++ b/awsapi/src/com/cloud/bridge/service/core/ec2/EC2Engine.java @@ -66,6 +66,7 @@ import com.cloud.stack.models.CloudStackPasswordData; import com.cloud.stack.models.CloudStackResourceLimit; import com.cloud.stack.models.CloudStackResourceTag; import com.cloud.stack.models.CloudStackSecurityGroup; +import com.cloud.stack.models.CloudStackServiceOffering; import com.cloud.stack.models.CloudStackSnapshot; import com.cloud.stack.models.CloudStackTemplate; import com.cloud.stack.models.CloudStackTemplatePermission; @@ -1414,7 +1415,7 @@ public class EC2Engine extends ManagerBase { if (request.getInstanceType() != null) { instanceType = request.getInstanceType(); } - CloudStackServiceOfferingVO svcOffering = getCSServiceOfferingId(instanceType); + CloudStackServiceOffering svcOffering = getCSServiceOfferingId(instanceType); if (svcOffering == null) { logger.info("No ServiceOffering found to be defined by name, please contact the administrator " + instanceType); throw new Exception("instanceType not found"); @@ -1609,7 +1610,7 @@ public class EC2Engine extends ManagerBase { if (request.getInstanceType() != null) { String instanceType = request.getInstanceType(); - CloudStackServiceOfferingVO svcOffering = getCSServiceOfferingId(instanceType); + CloudStackServiceOffering svcOffering = getCSServiceOfferingId(instanceType); if (svcOffering == null) throw new Exception("instanceType not found"); CloudStackUserVm userVm = getApi().changeServiceForVirtualMachine(instanceId, svcOffering.getId()); @@ -1783,11 +1784,12 @@ public class EC2Engine extends ManagerBase { * */ - private CloudStackServiceOfferingVO getCSServiceOfferingId(String instanceType) throws Exception { + private CloudStackServiceOffering getCSServiceOfferingId(String instanceType) throws Exception { try { if (instanceType == null) instanceType = "m1.small"; // default value - return scvoDao.getSvcOfferingByName(instanceType); + List serviceOfferings = getApi().listServiceOfferings(null, null, false, null, instanceType, null, null); + return serviceOfferings.get(0); } catch (Exception e) { logger.error("Error while retrieving ServiceOffering information by name - ", e); throw new Exception("No ServiceOffering found to be defined by name"); diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index f186fbf7848..f1c166bda11 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -31,7 +31,7 @@ label.smb.password=SMB Password label.smb.domain=SMB Domain label.hypervisors=Hypervisors label.home=Home -label.sockets=Sockets +label.sockets=CPU Sockets label.root.disk.size=Root disk size label.s3.nfs.server=S3 NFS Server label.s3.nfs.path=S3 NFS Path @@ -706,6 +706,7 @@ label.lang.arabic=Arabic label.lang.brportugese=Brazilian Portugese label.lang.catalan=Catalan label.lang.chinese=Chinese (Simplified) +label.lang.dutch=Dutch (Netherlands) label.lang.english=English label.lang.french=French label.lang.german=German @@ -713,6 +714,7 @@ label.lang.italian=Italian label.lang.japanese=Japanese label.lang.korean=Korean label.lang.norwegian=Norwegian +label.lang.polish=Polish label.lang.russian=Russian label.lang.spanish=Spanish label.last.disconnected=Last Disconnected diff --git a/client/WEB-INF/classes/resources/messages_es.properties b/client/WEB-INF/classes/resources/messages_es.properties index 3620047a275..31a9c93646c 100644 --- a/client/WEB-INF/classes/resources/messages_es.properties +++ b/client/WEB-INF/classes/resources/messages_es.properties @@ -22,6 +22,7 @@ error.session.expired=Su sesi\u00c3\u00b3n ha caducado. error.unresolved.internet.name=El nombre de Internet no se puede resolver. extractable=extra\u00c3\u00adble force.delete.domain.warning=Advertencia\: Si elige esta opci\u00c3\u00b3n, la supresi\u00c3\u00b3n de todos los dominios secundarios y todas las cuentas asociadas y sus recursos. +<<<<<<< HEAD force.delete=Fuerza Borrar force.remove=Fuerza Retire force.remove.host.warning=Advertencia\: Si elige esta opci\u00c3\u00b3n, CloudStack para detener la fuerza todas las m\u00c3\u00a1quinas virtuales en ejecuci\u00c3\u00b3n antes de retirar este host del cl\u00c3\u00baster. @@ -31,25 +32,38 @@ ICMP.code=ICMP C\u00c3\u00b3digo ICMP.type=Tipo ICMP image.directory=Directorio de la imagen inline=en l\u00c3\u00adnea +======= +force.delete=Forzar el borrado +force.remove=Forzar el retiro +force.remove.host.warning=Advertencia\: Si elige esta opci\u00f3n, CloudStack para detener la fuerza todas las m\u00e1quinas virtuales en ejecuci\u00f3n antes de retirar este host del cl\u00faster. +force.stop=Forzar la detenci\u00f3n +force.stop.instance.warning=Advertencia\: Forzar la dertenci\u00f3n de esta instancia deber\u00ed\u00ada ser su \u00faltima opci\u00f3n. Puede conducir a la p\u00e9rdida de datos, as\u00ed\u00ad como un comportamiento incoherente del Estado de la m\u00e1quina virtual. +ICMP.code=C\u00f3digo ICMP +ICMP.type=Tipo ICMP +image.directory=Directorio de im\u00e1genes +inline=alineado +label.about=Acerca de +label.about.app=Acerca de CloudStack +>>>>>>> 4e449ff... Add Dutch (Netherlands, Polish languages in Web UI Change Japanese code (ja -> ja_JP) Update transifex sync config label.account=Cuenta label.account.id=ID de la cuenta -label.account.name=Nombre de la cuenta +label.account.name=Nombre de cuenta label.accounts=Cuentas label.account.specific=espec\u00c3\u00adficas de la cuenta -label.acquire.new.ip=adquirir nuevas IP +label.acquire.new.ip=Adquirir nueva IP label.action.attach.disk=Conecte el disco -label.action.attach.disk.processing=disco Fijaci\u00c3\u00b3n .... -label.action.attach.iso=Adjuntar ISO -label.action.attach.iso.processing=Colocaci\u00c3\u00b3n de la norma ISO .... -label.action.cancel.maintenance.mode=Cancelar modo de mantenimiento -label.action.cancel.maintenance.mode.processing=Cancelaci\u00c3\u00b3n del modo de mantenimiento .... -label.action.change.password=Cambiar contrase\u00c3\u00b1a -label.action.change.service=Cambio de Servicio -label.action.change.service.processing=Cambio de servicio .... -label.action.copy.ISO=Copia de la ISO -label.action.copy.ISO.processing=hacer frente ISO .... -label.action.copy.template=Copia de plantilla -label.action.copy.template.processing=hacer frente plantilla .... +label.action.attach.disk.processing=Conectando el disco.... +label.action.attach.iso=Conectar ISO +label.action.attach.iso.processing=Conectando el ISO.... +label.action.cancel.maintenance.mode=Cancelar el modo de mantenimiento +label.action.cancel.maintenance.mode.processing=Cancelando el modo de mantenimiento.... +label.action.change.password=Cambiar la contrase\u00f1a +label.action.change.service=Cambiar el Servicio +label.action.change.service.processing=Cambiando el servicio.... +label.action.copy.ISO=Copiar ISO +label.action.copy.ISO.processing=Copiando ISO .... +label.action.copy.template=Copiear la plantilla +label.action.copy.template.processing=Copiando la plantilla .... label.action.create.template=Crear plantilla label.action.create.template.from.vm=Crear plantilla de VM label.action.create.template.from.volume=Crear plantilla de volumen @@ -250,6 +264,9 @@ label.alert=Alerta label.algorithm=Algoritmo label.allocated=Asignados label.api.key=clave de API +label.app.name=CloudStack +label.archive.alerts=Archivar alertas +label.archive.events=Archivar sucesos label.assign=Asignar label.assign.to.load.balancer=instancia de Asignaci\u00c3\u00b3n de equilibrador de carga label.associated.network.id=ID de red asociados @@ -263,9 +280,13 @@ label.basic.mode=Modo b\u00c3\u00a1sico label.bootable=arranque label.broadcast.domain.type=Tipo de dominio de difusi\u00c3\u00b3n label.by.account=Por Cuenta +label.by.alert.type=Por tipo de alerta label.by.availability=Por Disponibilidad +label.by.date.end=Por fecha (finalizaci\u00f3n) +label.by.date.start=Por fecha (inicio) label.by.domain=Por dominio label.by.end.date=Por Fecha de finalizaci\u00c3\u00b3n +label.by.event.type=Por tipo de suceso label.by.level=por Nivel label.by.pod=Por Pod label.by.role=por funci\u00c3\u00b3n @@ -300,6 +321,7 @@ label.cpu=CPU label.cpu.utilized=CPU Utilizado label.created=creaci\u00c3\u00b3n label.cross.zones=Cruz Zonas +label.custom.disk.iops=IOPS personalizadas label.custom.disk.size=Personal Disk Size label.daily=diario label.data.disk.offering=Datos Disco Offering @@ -307,7 +329,9 @@ label.date=Fecha label.day.of.month=D\u00c3\u00ada del mes label.day.of.week=d\u00c3\u00ada de la semana label.default.use=Usar por defecto +label.delete.alerts=Eliminar alertas label.delete=Eliminar +label.delete.events=Eliminar sucesos label.deleting.failed=No se pudo eliminar label.deleting.processing=Eliminar .... label.description=Descripci\u00c3\u00b3n @@ -319,6 +343,9 @@ label.DHCP.server.type=Tipo de servidor DHCP label.disabled=personas de movilidad reducida label.disabling.vpn.access=Desactivaci\u00c3\u00b3n de VPN de acceso label.disk.allocated=disco asignado +label.disk.iops.max=IOPS m\u00e1ximas +label.disk.iops.min=IOPS m\u00ednimas +label.disk.iops.total=Total de IOPS label.disk.offering=disco Ofrenda label.disk.size.gb=tama\u00c3\u00b1o de disco (en GB) label.disk.size=tama\u00c3\u00b1o de disco @@ -335,6 +362,7 @@ label.domain.suffix=DNS sufijo de dominio (es decir, xyz.com) label.double.quotes.are.not.allowed=comillas dobles no se permite label.download.progress=Progreso de la descarga label.edit=Editar +label.egress.default.policy=Directiva de salida predeterminada label.email=correo electr\u00c3\u00b3nico label.enabling.vpn.access=Habilitaci\u00c3\u00b3n de Acceso VPN label.enabling.vpn=Habilitaci\u00c3\u00b3n VPN @@ -374,6 +402,8 @@ label.host.name=nombre de host label.hosts=Ej\u00c3\u00a9rcitos label.hourly=por hora label.hypervisor=Hypervisor +label.hypervisors=Hipervisores +label.hypervisor.snapshot.reserve=Reserva de instant\u00e1neas de hipervisores label.hypervisor.type=Tipo Hypervisor label.id=ID label.info=Informaci\u00c3\u00b3n @@ -576,7 +606,10 @@ label.resource=Recursos label.resources=Recursos label.role=Papel label.root.disk.offering=Root Disco Offering +label.routing=Enrutamiento label.running.vms=Ejecuci\u00c3\u00b3n de m\u00c3\u00a1quinas virtuales +label.s3.nfs.path=Ruta NFS S3 +label.s3.nfs.server=Servidor NFS S3 label.s3.secret_key=clave secreta label.saturday=s\u00c3\u00a1bado label.save=Guardar @@ -594,6 +627,7 @@ label.select.a.zone=Seleccione una zona. label.sent=Enviados label.server=Servidor label.service.offering=Oferta de Servicio +label.service.state=Estado del servicio label.session.expired=Session Caducado label.shared=compartidas label.SharedMountPoint=SharedMountPoint @@ -605,6 +639,7 @@ label.snapshot.name=Nombre de instant\u00c3\u00a1neas label.snapshot.schedule=Lista de instant\u00c3\u00a1neas label.snapshot.s=Instant\u00c3\u00a1nea (s) label.snapshots=instant\u00c3\u00a1neas +label.sockets=Sockets label.source.nat=NAT Fuente label.specify.vlan=Especifique VLAN label.specify.vxlan=Especifique VXLAN @@ -636,6 +671,7 @@ label.submit=Enviar label.submitted.by=[Enviado por\: ] label.succeeded=Sucesor label.sunday=domingo +label.switch.type=Cambiar el tipo label.system.capacity=Capacidad de todo el sistema label.system.vm=Sistema de VM label.system.vms=Sistema de m\u00c3\u00a1quinas virtuales @@ -680,6 +716,7 @@ label.vcenter.host=vCenter anfitri\u00c3\u00b3n label.vcenter.password=vCenter Contrase\u00c3\u00b1a label.vcenter.username=vCenter Nombre de usuario label.version=Versi\u00c3\u00b3n +label.view.secondary.ips=Ver las IP secundarias label.virtual.appliances=Virtual Appliances label.virtual.appliance=Virtual Appliance label.virtual.machines=Maquinas virtuales @@ -854,6 +891,7 @@ message.step.4.continue=Por favor seleccione al menos una red social para contin message.step.4.desc=Por favor, seleccione la red primaria que la instancia virtual estar\u00c3\u00a1 conectado. message.update.os.preference=Por favor seleccione un sistema operativo de preferencia para este equipo. Todas las instancias virtuales con preferencias similares ser\u00c3\u00a1n los primeros asignados a este equipo antes de elegir otro. message.update.ssl=Por favor, env\u00c3\u00ade una nueva X.509 compatible con certificado SSL que se actualizar\u00c3\u00a1 a cada instancia virtual de la consola del servidor proxy\: +message.validate.invalid.characters=Se han hallado caracteres no v\u00e1lidos. Por favor, corr\u00edjalos. message.virtual.network.desc=Una red dedicada virtualizados para su cuenta. El dominio de difusi\u00c3\u00b3n est\u00c3\u00a1 contenida dentro de una VLAN y todos los acceso a la red p\u00c3\u00bablica se encamina a cabo por un router virtual. message.vm.create.template.confirm=Crear plantilla de la m\u00c3\u00a1quina virtual se reiniciar\u00c3\u00a1 autom\u00c3\u00a1ticamente. message.volume.create.template.confirm=Por favor, confirme que desea crear una plantilla para este volumen de disco. Creaci\u00c3\u00b3n de la plantilla puede oscilar entre varios minutos m\u00c3\u00a1s, dependiendo del tama\u00c3\u00b1o del volumen. diff --git a/client/WEB-INF/classes/resources/messages_fr_FR.properties b/client/WEB-INF/classes/resources/messages_fr_FR.properties index db624221ddf..42335bc7b45 100644 --- a/client/WEB-INF/classes/resources/messages_fr_FR.properties +++ b/client/WEB-INF/classes/resources/messages_fr_FR.properties @@ -641,6 +641,7 @@ label.lang.arabic=Arabe label.lang.brportugese=Portuguais Br\u00e9sil label.lang.catalan=Catalan label.lang.chinese=Chinois (simplifi\u00e9) +label.lang.dutch=N\u00e9erlandais label.lang.english=Anglais label.lang.french=Fran\u00e7ais label.lang.german=Allemand @@ -648,6 +649,7 @@ label.lang.italian=Italien label.lang.japanese=Japonais label.lang.korean=Cor\u00e9en label.lang.norwegian=Norv\u00e9gien +label.lang.polish=Polonais label.lang.russian=Russe label.lang.spanish=Espagnol label.last.disconnected=Derni\u00e8re D\u00e9connexion diff --git a/client/WEB-INF/classes/resources/messages_ja.properties b/client/WEB-INF/classes/resources/messages_ja_JP.properties similarity index 100% rename from client/WEB-INF/classes/resources/messages_ja.properties rename to client/WEB-INF/classes/resources/messages_ja_JP.properties diff --git a/client/WEB-INF/classes/resources/messages_nl_NL.properties b/client/WEB-INF/classes/resources/messages_nl_NL.properties new file mode 100644 index 00000000000..b1bfadb42af --- /dev/null +++ b/client/WEB-INF/classes/resources/messages_nl_NL.properties @@ -0,0 +1,1216 @@ +# 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. + +changed.item.properties=Item eigenschappen gewijzigd +confirm.enable.s3=Vul de volgende informatie in om ondersteuning voor S3-aangestuurde Secundaire Opslag te activeren +confirm.enable.swift=Vul de volgende informatie in om ondersteuning voor Swift te activeren +error.could.not.enable.zone=Kon zone niet activeren +error.installWizard.message=Er ging iets mis; je kunt teruggaan om de eventuele fouten te herstellen +error.invalid.username.password=Ongeldige gebruikersnaam of wachtwoord +error.login=Uw gebruikersnaam/wachtwoord komt niet overeen met onze gegevens +error.menu.select=Kan actie niet uitvoeren omdat geen items zijn geselecteerd +error.mgmt.server.inaccessible=The Management Server is niet toegankelijk. Probeer het later opnieuw. +error.password.not.match=De wachtwoord velden komen niet overeen +error.please.specify.physical.network.tags=Netwerk aanbiedingen zijn niet beschikbaar totdat u labels voor het fysieke netwerk specificeert. +error.session.expired=Uw sessie is verlopen +error.something.went.wrong.please.correct.the.following=Er is iets mis gegaan; Corrigeer het volgende +error.unable.to.reach.management.server=Niet in staat om de Management Server te bereiken +error.unresolved.internet.name=Uw internet naam kan niet worden omgezet. +extractable=Uitpakbaar +force.delete.domain.warning=Waarschuwing\: Wanneer u deze optie selecteert zullen alle onderliggende domeinen, hun gekoppelde accounts en hun verbruik worden verwijderd. +force.delete=Geforceerd verwijderen +force.remove=Geforceerd loskoppelen +force.remove.host.warning=Waarschuwing\: Wanneer u deze optie selecteert zal CloudStack alle draaiende virtuele machines geforceerd stoppen voordat de host van het cluster wordt verwijderd. +force.stop=Geforceerd stoppen +force.stop.instance.warning=Waarschuwing\: Een instantie geforceerd stoppen zou uw laatste optie moeten zijn. Het kan leiden tot dataverlies en inconsistent gedrag van de staat van de virtuele machine. +ICMP.code=ICMP Code +ICMP.type=ICMP Type +image.directory=Afbeelding Directory +inline=Inline +instances.actions.reboot.label=Herstart instantie +label.accept.project.invitation=Accepteer project uitnodiging +label.account=Account +label.account.and.security.group=Account, Security group +label.account.id=Account ID +label.account.name=Account Naam +label.accounts=Accounts +label.account.specific=Account-specifiek +label.acquire.new.ip=Bemachtig nieuw IP +label.action.attach.disk.processing=Schijf wordt toegevoegd.... +label.action.attach.disk=Schijf toevoegen +label.action.attach.iso=ISO toevoegen +label.action.attach.iso.processing=ISO wordt toegevoegd.... +label.action.cancel.maintenance.mode=Annuleer Onderhoudsmodus +label.action.cancel.maintenance.mode.processing=Onderhoudsmodus wordt geannuleerd.... +label.action.change.password=Wijzig Wachtwoord +label.action.change.service.processing=Service wordt gewijzigd.... +label.action.change.service=Wijzig Service +label.action.copy.ISO=Kopieer ISO +label.action.copy.ISO.processing=Kopi\u00ebren ISO.... +label.action.copy.template=Kopieer Template +label.action.copy.template.processing=Bezig met kopi\u00ebren Template.... +label.action.create.template=Cre\u00eber Template +label.action.create.template.from.vm=Cre\u00eber Template vanaf VM +label.action.create.template.from.volume=Cre\u00eber Template van Volume +label.action.create.template.processing=Bezig met aanmaken Template.... +label.action.create.vm=Cre\u00eber VM +label.action.create.vm.processing=Bezig met aanmaken VM.... +label.action.create.volume=Cre\u00eber Volume +label.action.create.volume.processing=Bezig met cre\u00ebren volume.... +label.action.delete.account.processing=Bezig met verwijderen account.... +label.action.delete.account=Verwijder account +label.action.delete.cluster.processing=Bezig met verwijderen van Cluster.... +label.action.delete.cluster=Verwijder Cluster +label.action.delete.disk.offering.processing=Bezig met verwijderen van Schijf Aanbieding.... +label.action.delete.disk.offering=Verwijder Schijf Aanbieding +label.action.delete.domain.processing=Bezig met verwijderen van Domein.... +label.action.delete.domain=Verwijder Domein +label.action.delete.firewall.processing=Bezig met verwijderen van Firewall.... +label.action.delete.firewall=Verwijder firewall regel +label.action.delete.ingress.rule.processing=Bezig met verwijderen van Inkomende Regel.... +label.action.delete.ingress.rule=Verwijder Inkomende Regel +label.action.delete.IP.range.processing=Bezig met verwijderen van IP Range.... +label.action.delete.IP.range=Verwijder IP Range +label.action.delete.ISO.processing=Bezig met verwijderen van ISO.... +label.action.delete.ISO=Verwijder ISO +label.action.delete.load.balancer.processing=Bezig met verwijderen van Load Balancer.... +label.action.delete.load.balancer=Verwijder load balancer regel +label.action.delete.network.processing=Bezig met verwijderen van Netwerk.... +label.action.delete.network=Verwijder Netwerk +label.action.delete.nexusVswitch=Verwijder Nexus 1000v +label.action.delete.physical.network=Verwijder fysiek netwerk +label.action.delete.pod.processing=Bezig met verwijderen van Pod.... +label.action.delete.pod=Verwijder Pod +label.action.delete.primary.storage.processing=Bezig met verwijderen van Primaire Opslag.... +label.action.delete.primary.storage=Verwijder Primaire Opslag +label.action.delete.secondary.storage.processing=Bezig met verwijderen van Secundaire Opslag.... +label.action.delete.secondary.storage=Verwijder Secundaire Opslag +label.action.delete.security.group.processing=Bezig met verwijderen van Security Group.... +label.action.delete.security.group=Verwijder Security Group +label.action.delete.service.offering.processing=Bezig met verwijderen van Service Aanbieding.... +label.action.delete.service.offering=Verwijder Service Aanbieding +label.action.delete.snapshot.processing=Bezig met verwijderen van Snapshot.... +label.action.delete.snapshot=Verwijder Snapshot +label.action.delete.system.service.offering=Verwijder Systeem Service Aanbieding +label.action.delete.template.processing=Bezig met verwijderen van Template.... +label.action.delete.template=Verwijder Template +label.action.delete.user.processing=Bezig met verwijderen Gebruiker.... +label.action.delete.user=Verwijder Gebruiker +label.action.delete.volume.processing=Bezig met verwijderen van Volume.... +label.action.delete.volume=Verwijder Volume +label.action.delete.zone.processing=Bezig met verwijderen van Zone.... +label.action.delete.zone=Verwijder Zone +label.action.destroy.instance.processing=Bezig met vernietigen van Instantie.... +label.action.destroy.instance=Verwijder Instantie +label.action.destroy.systemvm.processing=Bezig met vernietigen van Systeem VM.... +label.action.destroy.systemvm=Vernietig Systeem VM +label.action.detach.disk=Ontkoppel Schijf +label.action.detach.disk.processing=Bezig met ontkoppelen van Schijf.... +label.action.detach.iso=Ontkoppel ISO +label.action.detach.iso.processing=Bezig met ontkoppelen van ISO.... +label.action.disable.account=Deactiveer account +label.action.disable.account.processing=Bezig met deactiveren van account.... +label.action.disable.cluster=Deactiveer Cluster +label.action.disable.cluster.processing=Bezig met deactiveren van Cluster.... +label.action.disable.nexusVswitch=Deactiveer Nexus 1000v +label.action.disable.physical.network=Deactiveer fysiek netwerk +label.action.disable.pod=Deactiveer Pod +label.action.disable.pod.processing=Bezig met deactiveren van Pod.... +label.action.disable.static.NAT=Deactiveer Static NAT +label.action.disable.static.NAT.processing=Bezig met deactiveren van Static NAT.... +label.action.disable.user=Deactiveer Gebruiker +label.action.disable.user.processing=Bezig met deactiveren van Gebruiker.... +label.action.disable.zone=Deactiveer Zone +label.action.disable.zone.processing=Bezig met deactiveren van Zone.... +label.action.download.ISO=Download ISO +label.action.download.template=Download Template +label.action.download.volume=Download Volume +label.action.download.volume.processing=Bezig met downloaden van Volume.... +label.action.edit.account=Wijzig account +label.action.edit.disk.offering=Wijzig schijf aanbieding +label.action.edit.domain=Wijzig Domein +label.action.edit.global.setting=Wijzig Algemene Instellingen +label.action.edit.host=Wijzig Host +label.action.edit.instance=Wijzig Instantie +label.action.edit.ISO=Wijzig ISO +label.action.edit.network.offering=Wijzig Netwerk Aanbieding +label.action.edit.network.processing=Bezig met wijzigen van Netwerk... +label.action.edit.network=Wijzig Netwerk +label.action.edit.pod=Wijzig Pod +label.action.edit.primary.storage=Wijzig Primaire Opslag +label.action.edit.resource.limits=Wijzig verbruikslimieten +label.action.edit.service.offering=Wijzig Service Aanbieding +label.action.edit.template=Wijzig Template +label.action.edit.user=Wijzig Gebruiker +label.action.edit.zone=Wijzig Zone +label.action.enable.account=Activeer account +label.action.enable.account.processing=Bezig met activeren van account.... +label.action.enable.cluster=Activeer Cluster +label.action.enable.cluster.processing=Bezig met activeren van Cluster.... +label.action.enable.maintenance.mode=Activeer onderhoudsmodus +label.action.enable.maintenance.mode.processing=Bezig met activeren van Onderhoudsmodus +label.action.enable.nexusVswitch=Activeer Nexus 1000v +label.action.enable.physical.network=Activeer fysiek netwerk +label.action.enable.pod=Activeer Pod +label.action.enable.pod.processing=Bezig met activeren van Pod.... +label.action.enable.static.NAT=Activeer Static NAT +label.action.enable.static.NAT.processing=Bezig met activeren van Static NAT.... +label.action.enable.user=Activeer Gebruiker +label.action.enable.user.processing=Bezig met activeren van Gebruiker.... +label.action.enable.zone=Activeer Zone +label.action.enable.zone.processing=Bezig met activeren van Zone.... +label.action.force.reconnect=Forceer opnieuw verbinden +label.action.force.reconnect.processing=Bezig met opnieuw verbinden.... +label.action.generate.keys=Genereer Sleutels +label.action.generate.keys.processing=Bezig met generen van Sleutels.... +label.action.list.nexusVswitch=Toon Nexus 1000v +label.action.lock.account=Account op slot zetten +label.action.lock.account.processing=Bezig met account op slot zetten.... +label.action.manage.cluster=Beheer Cluster +label.action.manage.cluster.processing=Bezig met beheren van Cluster.... +label.action.migrate.instance=Migreer Instantie +label.action.migrate.instance.processing=Bezig met migreren van Instantie.... +label.action.migrate.router=MIgreer Router +label.action.migrate.router.processing=Bezig met migreren van Router.... +label.action.migrate.systemvm=Migreer Systeem VM +label.action.migrate.systemvm.processing=Bezig met migreren van Systeem VM.... +label.action.reboot.instance=Herstart Instantie +label.action.reboot.instance.processing=Bezig met herstarten van Instantie.... +label.action.reboot.router=Herstart Router +label.action.reboot.router.processing=Bezig met herstarten van Router.... +label.action.reboot.systemvm=Herstart Systeem VM +label.action.reboot.systemvm.processing=Bezig met herstarten van Systeem VM.... +label.action.recurring.snapshot=Terugkerende Snapshots +label.action.register.iso=Registreer ISO +label.action.register.template=Registreer Template +label.action.release.ip=Ontkoppel IP +label.action.release.ip.processing=Bezig met ontkoppelen van IP.... +label.action.remove.host.processing=Bezig met verwijderen van Host.... +label.action.remove.host=Verwijder Host +label.action.reset.password.processing=Bezig met resetten van wachtwoord.... +label.action.reset.password=Reset Wachtwoord +label.action.resize.volume.processing=Bezig met aanpassen van de grootte van het Volume +label.action.resize.volume=Wijzig de grootte van het volume +label.action.resource.limits=Verbruikslimieten +label.action.restore.instance=Herstel Instantie +label.action.restore.instance.processing=Bezig met herstellen van Instantie.... +label.actions=Acties +label.action.start.instance.processing=Bezig met starten van Instantie.... +label.action.start.instance=Start Instantie +label.action.start.router.processing=Start Router.... +label.action.start.router=Start Router +label.action.start.systemvm.processing=Bezig met starten van Systeem VM.... +label.action.start.systemvm=Start Systeem VM +label.action.stop.instance.processing=Bezig met stoppen van Instantie.... +label.action.stop.instance=Stop Instantie +label.action.stop.router.processing=Bezig met stoppen van Router.... +label.action.stop.router=Stop Router +label.action.stop.systemvm.processing=Bezig met stoppen van Systeem VM.... +label.action.stop.systemvm=Stop Systeem VM +label.action.take.snapshot=Neem Snapshot +label.action.take.snapshot.processing=Bezig met nemen van Snapshot.... +label.action.unmanage.cluster.processing=Bezig met uitschakelen van Clusterbeheer.... +label.action.unmanage.cluster=Schakel Clusterbeheer uit +label.action.update.OS.preference.processing=Bezig met wijzigen van OS voorkeuren.... +label.action.update.OS.preference=Wijzig OS voorkeuren +label.action.update.resource.count.processing=Bezig met updaten van verbruikslimieten.... +label.action.update.resource.count=Update Verbruikslimieten +label.action.vmsnapshot.create=Neem Snapshot van de VM +label.action.vmsnapshot.delete=Verwijder Snapshot van de VM +label.action.vmsnapshot.revert=Draai Snapshot van de VM terug +label.activate.project=Activeer Project +label.active.sessions=Actieve Sessies +label.add.accounts.to=Voeg accounts toe aan +label.add.accounts=Voeg accounts toe +label.add.account.to.project=Voeg account aan project toe +label.add.account=Voeg Account toe +label.add.ACL=Voeg ACL toe +label.add.BigSwitchVns.device=Voeg BigSwitch Vns Controller toe +label.add.by.cidr=Voeg toe door middel van CIDR +label.add.by.group=Voeg toe door middel van Groep +label.add.by=Voeg toe door middel van +label.add.cluster=Voeg Cluster toe +label.add.compute.offering=Voeg Compute aanbieding toe +label.add.direct.iprange=Voeg Direct IP Range toe +label.add.disk.offering=Voeg Schijf Aanbieding toe +label.add.domain=Voeg Domein toe +label.add.egress.rule=Voeg uitgaande regel toe +label.add.F5.device=Voeg F5 apparaat toe +label.add.firewall=Voeg firewall regel toe +label.add.guest.network=Gast netwerk toevoegen +label.add.host=Host toevoegen +label.adding.cluster=Bezig met toevoegen van Cluster +label.adding.failed=Toevoegen mislukt +label.adding.pod=Bezig met toevoegen van Pod +label.adding.processing=Toevoegen.... +label.add.ingress.rule=Voeg inkomende regel toe +label.adding.succeeded=Toevoegen geslaagd +label.adding=Toevoegen +label.adding.user=Bezig met toevoegen van Gebruiker +label.adding.zone=Bezig met toevoegen van Zone +label.add.ip.range=Voeg IP range toe +label.additional.networks=Additioneele Netwerken +label.add.load.balancer=Voeg Load Balancer toe +label.add.more=Voeg meer toe +label.add.netScaler.device=Voeg Netscaler apparaat toe +label.add.network.ACL=Voeg netwerk ACL toe +label.add.network.device=Voeg Netwerk Apparaat toe +label.add.network.offering=Voeg netwerk aanbieding toe +label.add.network=Voeg Netwerk toe +label.add.new.F5=Voeg nieuwe F5 toe +label.add.new.gateway=Voeg nieuwe gateway toe +label.add.new.NetScaler=Voeg nieuwe Netscaler toe +label.add.new.SRX=Voeg nieuwe SRX toe +label.add.new.tier=Voeg nieuwe Tier toe +label.add.NiciraNvp.device=Voeg NVP Controller toe +label.add.physical.network=Voeg fysiek netwerk toe +label.add.pod=Voeg Pod toe +label.add.port.forwarding.rule=Voeg port forwarding regel toe +label.add.primary.storage=Voeg Primaire Opslag toe +label.add.region=Voeg Regio toe +label.add.resources=Resources toevoegen +label.add.route=Route toevoegen +label.add.rule=Regel toevoegen +label.add.secondary.storage=Secundaire Opslag toevoegen +label.add.security.group=Security Group toevoegen +label.add.service.offering=Service Aanbieding toevoegen +label.add.SRX.device=SRX apparaat toevoegen +label.add.static.nat.rule=Statische NAT regel toevoegen +label.add.static.route=Statische route toevoegen +label.add.system.service.offering=Systeem Service Aanbieding toevoegen +label.add.template=Template toevoegen +label.add.to.group=Toevoegen aan groep +label.add.user=Gebruiker toevoegen +label.add.vlan=VLAN toevoegen +label.add.vms.to.lb=Voeg VM(s) toe aan load balancer regel +label.add.vms=VMs toevoegen +label.add.VM.to.tier=Voeg VM toe aan tier +label.add.vm=VM toevoegen +label.add=Voeg toe +label.add.volume=Volume toevoegen +label.add.vpc=VPC toevoegen +label.add.vpn.customer.gateway=VPN Customer Gateway toevoegen +label.add.VPN.gateway=VPN Gateway toevoegen +label.add.vpn.user=VPN gebruiker toevoegen +label.add.zone=Zone toevoegen +label.admin.accounts=Beheer Accounts +label.admin=Beheerder +label.advanced=Geavanceerd +label.advanced.mode=Geavanceerde Modus +label.advanced.search=Geavanceerd zoeken +label.agent.password=Agent wachtwoord +label.agent.username=Agent Gebruikersnaam +label.agree=Accepteren +label.alert=Alarm +label.algorithm=Algoritme +label.allocated=Gebruikt +label.allocation.state=Verbruik Staat +label.api.key=API Sleutel +label.apply=Uitvoeren +label.assign=Toevoegen +label.assign.to.load.balancer=Voeg instantie toe aan load balancer +label.associated.network=Bijbehorend Netwerk +label.associated.network.id=Bijbehorend Netwerk ID +label.attached.iso=Gekoppelde ISO +label.author.email=Auteur e-mail +label.author.name=Auteur naam +label.availability=Beschikbaarheid +label.availability.zone=Beschikbaarheids-zone +label.available=Beschikbaar +label.available.public.ips=Beschikbare Publieke IP adressen +label.back=Terug +label.bandwidth=Bandbreedte +label.basic=Basis +label.basic.mode=Basis Modus +label.bigswitch.controller.address=BigSwitch Vns Controller Adres +label.bootable=Bootable +label.broadcast.domain.range=Broadcast domain range +label.broadcast.domain.type=Broadcast Domain Type +label.broadcast.uri=Broadcast URI +label.by.account=Op Account +label.by.availability=Op Beschikbaarheid +label.by.domain=Op Domein +label.by.end.date=Op Eind Datum +label.by.level=Op Level +label.by.pod=Op Pod +label.by.role=Op Rol +label.by.start.date=Op Start Datum +label.by.state=Op Staat +label.bytes.received=Bytes Ontvangen +label.bytes.sent=Bytes Verzonden +label.by.traffic.type=Op Verkeerstype +label.by.type.id=Op Type ID +label.by.type=Op Type +label.by.zone=Op Zone +label.cancel=Annuleer +label.capacity=Capaciteit +label.certificate=Certificaat +label.change.service.offering=Wijzig service aanbieding +label.change.value=Wijzig waarde +label.character=Karakter +label.checksum=MD5 checksum +label.cidr.account=CIDRN of Account/Security Group +label.cidr=CIDR +label.cidr.list=Bron CIDR +label.CIDR.list=CIDR lijst +label.CIDR.of.destination.network=CIDR van bestemmingsnetwerk +label.clean.up=Opschonen +label.clear.list=Schoon lijst op +label.close=Sluiten +label.cloud.console=Cloud Beheers Console +label.cloud.managed=Cloud.com Managed +label.cluster=Cluster +label.cluster.name=Cluster Naam +label.clusters=Clusters +label.cluster.type=Cluster Type +label.clvm=CLVM +label.code=Code +label.community=Community +label.compute.and.storage=Compute en Opslag +label.compute=Compute +label.compute.offering=Compute aanbieding +label.configuration=Configuratie +label.configure=Configureer +label.configure.network.ACLs=Configureer Netwerk ACLs +label.configure.vpc=Configureer VPC +label.confirmation=Bevestiging +label.confirm.password=Bevestig wachtwoord +label.congratulations=Gefeliciteerd\! +label.conserve.mode=Conserveer modus +label.console.proxy=Console proxy +label.continue.basic.install=Ga door met basis installatie +label.continue=Ga door +label.corrections.saved=Correcties opgeslagen +label.cpu.allocated=CPU gebruik +label.cpu.allocated.for.VMs=CPU gebruikt voor VMs +label.CPU.cap=CPU Cap +label.cpu=CPU +label.cpu.limits=CPU limieten +label.cpu.mhz=CPU (in MHz) +label.cpu.utilized=CPU Verbruik +label.created=Aangemaakt +label.created.by.system=Aangemaakt door systeem +label.create.project=Nieuw project +label.create.template=Nieuwe template +label.create.VPN.connection=Nieuwe VPN connectie +label.cross.zones=Over Zones +label.custom.disk.size=Vrije schijf grootte +label.daily=Dagelijkse +label.data.disk.offering=Data Schijf Aanbieding +label.date=Datum +label.day.of.month=Dag van de Maand +label.day.of.week=Dag van de Week +label.dead.peer.detection=Dead Peer detectie +label.decline.invitation=Sla uitnodiging af +label.dedicated=Dedicated +label.default=Standaard +label.default.use=Standaard Gebruik +label.default.view=Standaard Weergave +label.delete.BigSwitchVns=Verwijder BigSwitch Vns Controller +label.delete.F5=Verwijder F5 +label.delete.gateway=Verwijder gateway +label.delete.NetScaler=Verwijder NetScaler +label.delete.NiciraNvp=Verwijder Nvp Controller +label.delete.project=Verwijder project +label.delete.SRX=Verwijder SRX +label.delete=Verwijder +label.delete.VPN.connection=Verwijder VPN connectie +label.delete.VPN.customer.gateway=Verwijder VPN Customer Gateway +label.delete.VPN.gateway=Verwijder VPN Gateway +label.delete.vpn.user=Verwijder VPN gebruiker +label.deleting.failed=Verwijderen Mislukt +label.deleting.processing=Verwijderen.... +label.description=Beschrijving +label.destination.physical.network.id=Bestemming fysiek netwerk ID +label.destination.zone=Bestemmingszone +label.destroy.router=Verwijder router +label.destroy=Verwijder +label.detaching.disk=Ontkoppelen Schijf +label.details=Details +label.device.id=Apparaat ID +label.devices=Apparaten +label.dhcp=DHCP +label.DHCP.server.type=DHCP Server Type +label.direct.ips=Shared Netwerk IPs +label.disabled=Uitgeschakeld +label.disable.provider=Provider uitschakelen +label.disable.vpn=VPN uitschakelen +label.disabling.vpn.access=Uitschakelen van VPN Toegang +label.disk.allocated=Schijfruimte gealloceerd +label.disk.offering=Schijf Aanbieding +label.disk.size.gb=Schijf Grootte (in GB) +label.disk.size=Schijf Grootte +label.disk.total=Schijf Totaal +label.disk.volume=Schijf Volume +label.display.name=Weergavenaam +label.display.text=Weergavetekst +label.dns.1=DNS 1 +label.dns.2=DNS 2 +label.dns=DNS +label.DNS.domain.for.guest.networks=DNS domein voor Gast Netwerken +label.domain.admin=Domein Beheerder +label.domain=Domein +label.domain.id=Domein ID +label.domain.name=Domeinnaam +label.domain.router=Domein router +label.domain.suffix=DNS domein achtervoegsel (v.b., xyz.com) +label.done=Klaar +label.double.quotes.are.not.allowed=Aanhalingstekens zijn hier niet toegestaan +label.download.progress=Download Voortgang +label.drag.new.position=Sleep naar nieuwe positie +label.edit.lb.rule=Wijzig LB regel +label.edit.network.details=Wijzig netwerk details +label.edit.project.details=Wijzig project details +label.edit.tags=Wijzig tags +label.edit.traffic.type=Wijzig traffic type +label.edit.vpc=Wijzig VPC +label.edit=Wijzig +label.egress.rules=Uitgaande regels +label.egress.rule=Uitgaande regel +label.elastic=Elastisch +label.elastic.IP=Elastisch IP +label.elastic.LB=Elastisch LB +label.email=Email +label.enable.provider=Provider inschakelen +label.enable.s3=S3-gebaseerde Secondary Storage inschakelen +label.enable.swift=Swift inschakelen +label.enable.vpn=VPN inschakelen +label.enabling.vpn.access=VPN toegang inschakelen +label.enabling.vpn=VPN inschakelen +label.end.IP=Eind IP +label.endpoint=Endpoint +label.endpoint.or.operation=Endpoint or Operation +label.end.port=Eind Poort +label.end.reserved.system.IP=Einde gereserveerde systeem IP +label.end.vlan=Einde Vlan +label.enter.token=Voer token in +label.error.code=Fout code +label.error=Fout +label.ESP.encryption=ESP Encryptie +label.ESP.hash=ESP Hash +label.ESP.lifetime=ESP Lifetime (secondes) +label.ESP.policy=ESP policy +label.esx.host=ESX/ESXi Host +label.example=Voorbeeld +label.external.link=Externe link +label.f5=F5 +label.failed=Mislukt +label.featured=Voorgesteld +label.fetch.latest=Haal laatste op +label.filterBy=Filter per +label.firewall=Firewall +label.first.name=Voornaam +label.format=Formaat +label.friday=Vrijdag +label.full.path=Volledig pad +label.full=Volledig +label.gateway=Gateway +label.general.alerts=Algemene Waarschuwingen +label.generating.url=Generen van URL +label.go.step.2=Ga naar Stap 2 +label.go.step.3=Ga naar Stap 3 +label.go.step.4=Ga naar Stap 4 +label.go.step.5=Ga naar Stap 5 +label.group=Groep +label.group.optional=Groep (Optioneel) +label.guest.cidr=Gast CIDR +label.guest.end.ip=Gast eind IP +label.guest=Gast +label.guest.gateway=Gast Gateway +label.guest.ip=Gast IP Adres +label.guest.ip.range=Gast IP range +label.guest.netmask=Gast Netmask +label.guest.networks=Gast netwerken +label.guest.start.ip=Gast start IP +label.guest.traffic=Gast verkeer +label.guest.type=Gast Type +label.ha.enabled=HA ingeschakeld +label.help=Help +label.hide.ingress.rule=Verberg Inkomende Regel +label.hints=Tips +label.host.alerts=Host Waarschuwingen +label.host=Host +label.host.MAC=Host MAC +label.host.name=Hostnaam +label.hosts=Hosts +label.host.tags=Host Tags +label.hourly=Uurlijks +label.hypervisor.capabilities=Hypervisor mogelijkheden +label.hypervisor=Hypervisor +label.hypervisor.type=Hypervisor Type +label.hypervisor.version=Hypervisor versie +label.id=ID +label.IKE.DH=IKE DH +label.IKE.encryption=IKE Encryptie +label.IKE.hash=IKE Hash +label.IKE.lifetime=IKE lifetime (secondes) +label.IKE.policy=IKE policy +label.info=Info +label.ingress.rule=Inkomende Regel +label.initiated.by=Ge\u00efnitieerd door +label.installWizard.addClusterIntro.subtitle=Wat is een cluster? +label.installWizard.addClusterIntro.title=Nu\: Cluster toevoegen +label.installWizard.addHostIntro.subtitle=Wat is een host? +label.installWizard.addHostIntro.title=Nu\: Host toevoegen +label.installWizard.addPodIntro.subtitle=Wat is een pod? +label.installWizard.addPodIntro.title=Nu\: Pod toevoegen +label.installWizard.addPrimaryStorageIntro.subtitle=Wat is primary storage? +label.installWizard.addPrimaryStorageIntro.title=Nu\: Primaire opslag toevoegen +label.installWizard.addSecondaryStorageIntro.subtitle=Wat is secundaire opslag? +label.installWizard.addSecondaryStorageIntro.title=Nu\: Secundaire opslag toevoegen +label.installWizard.addZoneIntro.subtitle=Wat is een zone? +label.installWizard.addZoneIntro.title=Nu\: Zone toevoegen +label.installWizard.addZone.title=Zone toevoegen +label.installWizard.click.launch=Klik op de lanceer knop. +label.installWizard.subtitle=Deze rondleiding gaat je helpen met het uitvoeren van de CloudStack&\#8482 installatie +label.installWizard.title=Hallo en welkom bij CloudStack&\#8482 +label.instance=Instantie +label.instance.limits=Instantie Limieten +label.instance.name=Instantie Naam +label.instances=Instanties +label.internal.dns.1=Interne DNS 1 +label.internal.dns.2=Interne DNS 2 +label.internal.name=Interne naam +label.interval.type=Interval Type +label.introduction.to.cloudstack=CloudStack&\#8482 Introductie +label.invalid.integer=Onjuiste Waarde +label.invalid.number=Onjuist nummer +label.invitations=Uitnodigingen +label.invited.accounts=Uitgenodigde accounts +label.invite.to=Nodig uit voor +label.invite=Uitnodigen +label.ip.address=IP Adres +label.ipaddress=IP Adres +label.ip.allocations=IP Allocaties +label.ip=IP +label.ip.limits=Publieke IP Limieten +label.ip.or.fqdn=IP of FQDN +label.ip.range=IP Range +label.ip.ranges=IP Ranges +label.IPsec.preshared.key=IPsec Preshared-Key +label.ips=IPs +label.iscsi=iSCSI +label.is.default=Is Standaard +label.iso.boot=ISO Boot +label.iso=ISO +label.isolated.networks=Geisoleerde netwerken +label.isolation.method=Isolatie methode +label.isolation.mode=Isolatie Modus +label.isolation.uri=Isolatie URI +label.is.redundant.router=Redundant +label.is.shared=Is Gedeeld +label.is.system=Is Systeem +label.item.listing=Items lijst +label.keep=Bewaar +label.keyboard.type=Toetsenbord type +label.key=Sleutel +label.kvm.traffic.label=KVM verkeer label +label.label=Label +label.lang.brportugese=Braziliaans Portgees +label.lang.chinese=Chinees (Simplified) +label.lang.english=Engels +label.lang.french=Frans +label.lang.japanese=Japans +label.lang.korean=Koreans +label.lang.russian=Russisch +label.lang.spanish=Spaans +label.last.disconnected=Laatse keer niet verbonden +label.last.name=Achternaam +label.latest.events=Laatste gebeurtenissen +label.launch=Lanceer +label.launch.vm=Lanceer VM +label.launch.zone=Lanceer zone +label.LB.isolation=LB isolatie +label.least.connections=Minste connecties +label.level=Level +label.load.balancer=Load Balancer +label.load.balancing=Load Balancing +label.load.balancing.policies=Load balancing policies +label.loading=Laden +label.local=Lokaal +label.local.storage.enabled=Lokale opslag ingeschakeld +label.local.storage=Lokale Opslag +label.login=Login +label.logout=Log uit +label.lun=LUN +label.LUN.number=LUN \# +label.make.project.owner=Maak account project eigenaar +label.manage=Beheer +label.management=Beheer +label.management.ips=Beheers IP Adressen +label.manage.resources=Beheer Resources +label.max.cpus=Max. CPU cores +label.max.guest.limit=Max. Instanties +label.maximum=Maximaal +label.max.memory=Max. geheugen (MiB) +label.max.networks=Max. netwerken +label.max.primary.storage=Max. primare opslag (GiB) +label.max.public.ips=Max. publieke IPs +label.max.secondary.storage=Max. secundaire opslag (GiB) +label.max.snapshots=Max. snapshots +label.max.templates=Max. templates +label.max.vms=Max. VMs per gebruiker +label.max.volumes=Max. volumes +label.max.vpcs=Max. VPCs +label.may.continue=U kunt nu verder gaan. +label.memory.allocated=Geheugen Gealloceerd +label.memory=Geheugen +label.memory.limits=Geheugen limieten (MiB) +label.memory.mb=Geheugen (in MB) +label.memory.total=Totaal Geheugen +label.memory.used=Geheugen gebruikt +label.menu.accounts=Accounts +label.menu.alerts=Waarschuwingen +label.menu.all.accounts=Alle Accounts +label.menu.all.instances=Alle Instanties +label.menu.community.isos=Community ISOs +label.menu.community.templates=Community Templates +label.menu.configuration=Configuratie +label.menu.dashboard=Dashboard +label.menu.destroyed.instances=Vernietigde Instanties +label.menu.disk.offerings=Schijf Aanbiedingen +label.menu.domains=Domeinen +label.menu.events=Gebeurtenissen +label.menu.featured.isos=Voorgestelde ISOs +label.menu.featured.templates=Voorgestelde Templates +label.menu.global.settings=Algemene Instellingen +label.menu.infrastructure=Infrastructuur +label.menu.instances=Instanties +label.menu.ipaddresses=IP Adressen +label.menu.isos=ISOs +label.menu.my.accounts=Mijn Accounts +label.menu.my.instances=Mijn Instanties +label.menu.my.isos=Mijn ISOs +label.menu.my.templates=Mijn Templates +label.menu.network=Netwerk +label.menu.network.offerings=Netwerk Aanbiedingen +label.menu.physical.resources=Fysieke Resources +label.menu.regions=Regio\\'s +label.menu.running.instances=Draaiende Instanties +label.menu.security.groups=Security Groups +label.menu.service.offerings=Service Aanbiedingen +label.menu.snapshots=Snapshots +label.menu.stopped.instances=Uitgeschakelde Instanties +label.menu.storage=Opslag +label.menu.system.service.offerings=Systeem Aanbiedingen +label.menu.system=Systeem +label.menu.system.vms=Systeem VMs +label.menu.templates=Templates +label.menu.virtual.appliances=Virtueele Appliances +label.menu.virtual.resources=Virtuele Resources +label.menu.volumes=Volumes +label.migrate.instance.to.host=Migreer instantie naar andere host +label.migrate.instance.to=Migreer instantie naar +label.migrate.instance.to.ps=Migreer instantie naar andere primaire opslag +label.migrate.router.to=Migreer Router naar +label.migrate.systemvm.to=Migreer Systeem VM naar +label.migrate.to.host=Migreer naar host +label.migrate.to.storage=Migreer naar opslag +label.migrate.volume=Migreer volume naar andere primaire opslag +label.minimum=Minimum +label.minute.past.hour=Minuten na het uur +label.monday=Maandag +label.monthly=Maandelijks +label.more.templates=Meer Templates +label.move.down.row=Verplaats \u00e9\u00e9n regel naar beneden +label.move.to.bottom=Verplaats naar beneden +label.move.to.top=Verplaats naar boven +label.move.up.row=Verplaats \u00e9\u00e9n regel naar boven +label.my.account=Mijn Account +label.my.network=Mijn netwerk +label.my.templates=Mijn templates +label.name=Naam +label.name.optional=Naam (Optioneel) +label.nat.port.range=NAT Poort Range +label.netmask=Netmask +label.netScaler=NetScaler +label.network.ACL=Netwerk ACL +label.network.ACLs=Netwerk ACLs +label.network.ACL.total=Netwerk ACL Totaal +label.network.desc=Netwerk Beschr. +label.network.device=Netwerk Apparaat +label.network.device.type=Netwerk Apparaat Type +label.network.domain=Netwerk Domein +label.network.domain.text=Netwerk Domein +label.network.id=Netwerk ID +label.networking.and.security=Netwerken en beveiliging +label.network.label.display.for.blank.value=Gebruik standaard gateway +label.network.name=Netwerk Naam +label.network=Netwerk +label.network.offering.display.text=Netwerk Aanbieding Weergave Tekst +label.network.offering.id=Netwerk Aanbieding ID +label.network.offering.name=Netwerk Aanbieding Naam +label.network.offering=Netwerk Aanbieding +label.network.read=Netwerk gelezen +label.network.service.providers=Netwerk Service Aanbieders +label.networks=Netwerken +label.network.type=Netwerk Type +label.network.write=Netwerk geschreven +label.new=Nieuw +label.new.password=Nieuw wachtwoord +label.new.project=Nieuw Project +label.new.vm=Nieuwe VM +label.next=Volgende +label.nexusVswitch=Nexus 1000v +label.nfs=NFS +label.nfs.server=NFS Server +label.nfs.storage=NFS Opslag +label.nic.adapter.type=NIC adapter type +label.nicira.controller.address=Controller Adres +label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid +label.nicira.transportzoneuuid=Transport Zone Uuid +label.nics=NICs +label.no.actions=Geen Beschikbare Acties +label.no.alerts=Geen Recente Waarschuwingen +label.no.data=Geen data om weer te geven +label.no.errors=Geen Recente Fouten +label.no.isos=Geen beschikbare ISOs +label.no.items=Geen Beschikbare Items +label.no=Nee +label.none=Geen +label.no.security.groups=Geen Beschikbare Security Groups +label.not.found=Niet gevonden +label.no.thanks=Nee bedankt +label.notifications=Notificaties +label.number.of.clusters=Aantal Clusters +label.number.of.hosts=Aantal Hosts +label.number.of.pods=Aantal Pods +label.number.of.system.vms=Aantal Systeem VMs +label.number.of.virtual.routers=Aantal Virtual Routers +label.number.of.zones=Aantal Zones +label.num.cpu.cores=Aantal CPU Cores +label.numretries=Keren opnieuw geprorbeerd +label.ocfs2=OCFS2 +label.offer.ha=HA aanbieden +label.ok=OK +label.optional=Optioneel +label.order=Volgorde +label.os.preference=OS Voorkeur +label.os.type=OS Type +label.owned.public.ips=Publieke IP Adressen in beheer +label.owner.account=Account Eigenaar +label.owner.domain=Domein Eigenaar +label.parent.domain=Bovenliggend Domein +label.password.enabled=Wachtwoord Ingeschakeld +label.password=Wachtwoord +label.path=Pad +label.perfect.forward.secrecy=Perfect Forward Secrecy +label.physical.network=Fysiek Netwerk +label.physical.network.ID=Fysiek netwerk ID +label.PING.CIFS.password=PING CIFS wachtwoord +label.PING.CIFS.username=PING CIFS gebruikersnaam +label.PING.dir=PING Directory +label.PING.storage.IP=PING opslag IP +label.please.specify.netscaler.info=Geef hier informatie van de Netscaler op +label.please.wait=Een ogenblik geduld a.u.b. +label.plugin.details=Plugin details +label.plugins=Plugins +label.pod.name=Pod Naam +label.pod=Pod +label.pods=Pods +label.port.forwarding.policies=Port forwarding policies +label.port.forwarding=Port Forwarding +label.port.range=Port Range +label.PreSetup=PreSetup +label.previous=Vorige +label.prev=Terug +label.primary.allocated=Primaire Opslag Gealloceerd +label.primary.network=Primair Netwerk +label.primary.storage.count=Primaire Opslag Pools +label.primary.storage.limits=Primaire Opslag limieten (GiB) +label.primary.storage=Primaire Opslag +label.primary.used=Primaire Opslag Gebruikt +label.private.Gateway=Priv\u00e9 Gateway +label.private.interface=Priv\u00e9 Interface +label.private.ip=Priv\u00e9 IP Adres +label.private.ip.range=Priv\u00e9 IP Range +label.private.ips=Priv\u00e9 IP adressen +label.privatekey=PKCS\#8 Private Key +label.private.network=Priv\u00e9 Netwerk +label.private.port=Priv\u00e9 Port +label.private.zone=Priv\u00e9 Zone +label.project.dashboard=Project Dashboard +label.project.id=Project ID +label.project.invite=Nodig uit voor project +label.project.name=Project naam +label.project=Project +label.projects=Projecten +label.project.view=Project Weergave +label.protocol=Protocol +label.providers=Providers +label.public.interface=Publieke Interface +label.public.ip=Publiek IP Adres +label.public.ips=Publieke IP Adressen +label.public.network=Publiek netwerk +label.public.port=Publieke Poort +label.public=Publiek +label.public.traffic=Publiek verkeer +label.public.zone=Publieke Zone +label.purpose=Doel +label.Pxe.server.type=PXE Server Type +label.quickview=Sneloverzicht +label.reboot=Reboot +label.recent.errors=Recente Fouten +label.redundant.router.capability=Redundante router mogelijkheden +label.redundant.router=Redundante Router +label.redundant.state=Redundante staat +label.refresh=Ververs +label.region=Regio +label.related=Samenhangend +label.remind.later=Herinner me later +label.remove.ACL=Verwijder ACL +label.remove.egress.rule=Verwijder uitgaande regel +label.remove.from.load.balancer=Verwijder Instantie van load balancer +label.remove.ingress.rule=Verwijder inkomende regel +label.remove.ip.range=Verwijder IP range +label.remove.pf=Verwijder port forwarding regel +label.remove.project.account=Verwijder account van project +label.remove.region=Verwijder Regio +label.remove.rule=Verwijder regel +label.remove.static.nat.rule=Verwijder static NAT regel +label.remove.static.route=Verwijder statische route +label.remove.tier=Verwijder tier +label.remove.vm.from.lb=Verwijder VM van load balancer regel +label.remove.vpc=verwijder VPC +label.removing.user=Verwijderen Gebruiker +label.removing=Verwijderen +label.required=Vereist +label.reserved.system.gateway=Gereseveerde systeem gateway +label.reserved.system.ip=Gereserveerd Systeem IP +label.reserved.system.netmask=Gereserveerd systeem netmask +label.reset.VPN.connection=Reset VPN verbinding +label.resize.new.offering.id=Nieuwe Aanbieding +label.resize.new.size=Nieuwe Grootte(GB) +label.resize.shrink.ok=Verklein OK +label.resource.limits=Verbruikslimieten +label.resource.state=Verbruik staat +label.resources=Verbruiken +label.resource=Verbruik +label.restart.network=Herstart netwerk +label.restart.required=Herstart benodigd +label.restart.vpc=herstart VPC +label.restore=Herstel +label.review=Beoordeel +label.revoke.project.invite=Trek uitnodiging in +label.role=Rol +label.root.disk.controller=Root schijf controller +label.root.disk.offering=Root Schijf Aanbieding +label.round.robin=Round-robin +label.rules=Regels +label.running.vms=Draaiende VMs +label.s3.access_key=Toegangssleutel +label.s3.bucket=Bucket +label.s3.connection_timeout=Connectie Timeout +label.s3.endpoint=Endpoint +label.s3.max_error_retry=Max. opnieuw proberen na Fout +label.s3.secret_key=Geheime sleutel +label.s3.socket_timeout=Socket Timeout +label.s3.use_https=Gebruik HTTPS +label.saturday=Zaterdag +label.save.and.continue=Opslaan en verder gaan +label.save=Opslaan +label.saving.processing=Opslaan.... +label.scope=Scope +label.search=Zoeken +label.secondary.storage.count=Secundaire Opslag Pools +label.secondary.storage.limits=Secundaire Opslag limieten (GiB) +label.secondary.storage=Secundaire Opslag +label.secondary.storage.vm=Secundaire Opslag VM +label.secondary.used=Secundaire Opslag Gebruikt +label.secret.key=Geheime sleutel +label.security.group.name=Security Group Naam +label.security.group=Security Group +label.security.groups.enabled=Security Groups Ingeschakeld +label.security.groups=Security Groups +label.select.a.template=Selecteer een template +label.select.a.zone=Selecteer een zone +label.select.instance=Selecteer een instance +label.select.instance.to.attach.volume.to=Selecteer een instance om het volume aan te koppelen +label.select.iso.or.template=Selecteer een ISO of template +label.select.offering=Selecteer Aanbieding +label.select.project=Selecteer Project +label.select=Selecteer +label.select.tier=Selecteer Tier +label.select-view=Selecteer Weergave +label.select.vm.for.static.nat=Selecteer VM voor static NAT +label.sent=Verstuurd +label.server=Server +label.service.capabilities=Service Mogelijkheden +label.service.offering=Service Aanbieding +label.session.expired=Sessie Verlopen +label.setup=Instellen +label.setup.network=Stel Netwerk in +label.setup.zone=Stel Zone in +label.set.up.zone.type=Stel zone type in +label.shared=Gedeeld +label.SharedMountPoint=SharedMountPoint +label.show.ingress.rule=Toon Inkomende Regel +label.shutdown.provider=Schakel provider uit +label.site.to.site.VPN=Site-to-site VPN +label.size=Grootte +label.skip.guide=Ik heb CloudStack al eerder gebruikt, sla deze stap over +label.snapshot.limits=Snapshot Limieten +label.snapshot.name=Snapshot Naam +label.snapshot.schedule=Stel herhalende Snapshot in +label.snapshot=Snapshot +label.snapshot.s=Snapshot (s) +label.snapshots=Snapshots +label.source=Bron +label.source.nat=Source NAT +label.specify.IP.ranges=Specificeer IP ranges +label.specify.vlan=Specificeer VLAN +label.SR.name = SR Name-Label +label.srx=SRX +label.start.IP=Start IP +label.start.port=Start Poort +label.start.reserved.system.IP=Start gereseveerd systeem IP +label.start.vlan=Start VLAN +label.state=Staat +label.static.nat.enabled=Static NAT Ingeschakeld +label.static.nat=Static NAT +label.static.nat.to=Static NAT naar +label.static.nat.vm.details=Static NAT VM Details +label.statistics=Statistieken +label.status=Status +label.step.1=Stap 1 +label.step.1.title=Stap 1\: Selecteer een Template +label.step.2=Stap 2 +label.step.2.title=Stap 2\: Service Aanbieding +label.step.3=Stap 3 +label.step.3.title=Stap 4\: Selecteer een Schijf Aanbieding +label.step.4=Stap 4 +label.step.4.title=Stap 4\: Netwerk +label.step.5=Stap 5 +label.step.5.title=Stap 5\: Beoordeel +label.stickiness=Stickiness +label.sticky.cookie-name=Cookie naam +label.sticky.domain=Domein +label.sticky.expire=Verloopt +label.sticky.holdtime=Wacht tijd +label.sticky.indirect=Indirect +label.sticky.length=Lengte +label.sticky.mode=Modus +label.sticky.nocache=Geen cache +label.sticky.postonly=Alleen Post +label.sticky.prefix=Prefix +label.sticky.request-learn=Request learn +label.sticky.tablesize=Tabel grootte +label.stopped.vms=Uitgeschakelde VMs +label.stop=Stop +label.storage=Opslag +label.storage.tags=Opslag Tags +label.storage.traffic=Opslag Verkeer +label.storage.type=Opslag Type +label.subdomain.access=Subdomein Toegang +label.submitted.by=[Verstuurd door\: ] +label.submit=Verstuur +label.succeeded=Geslaagd +label.sunday=Zondag +label.super.cidr.for.guest.networks=Super CIDR voor Gast Netwerken +label.supported.services=Geondersteunde Diensten +label.supported.source.NAT.type=Ondersteunde Source NAT type +label.suspend.project=Pauzeer Project +label.system.capacity=Systeem Capaciteit +label.system.offering=Systeem Aanbieding +label.system.service.offering=Systeem Service Aanbieding +label.system.vms=Systeem VMs +label.system.vm=Systeem VM +label.system.vm.type=Systeem VM type +label.system.wide.capacity=Systeembreede capaciteit +label.tagged=Tagged +label.tags=Tags +label.target.iqn=Doel IQN +label.task.completed=Taak uitgevoerd +label.template.limits=Template Limieten +label.template=Template +label.TFTP.dir=TFTP Directory +label.theme.default=Standaard Thema +label.theme.grey=Aangepast - Grijs +label.theme.lightblue=Aangepast - Licht Blauw +label.thursday=Donderdag +label.tier.details=Tier details +label.tier=Tier +label.timeout.in.second = Timeout(seconden) +label.timeout=Timeout +label.time=Tijd +label.time.zone=Tijdzone +label.timezone=Tijdzone +label.token=Token +label.total.cpu=Totaal CPU +label.total.CPU=Totaal CPU +label.total.hosts=Totaal Hosts +label.total.memory=Totaal Geheugen +label.total.of.ip=Totaal aantal IP Adressen +label.total.of.vm=Totaal aantal VM +label.total.storage=Totaal Opslag +label.total.vms=Totaal VMs +label.traffic.label=Verkeerslabel +label.traffic.types=Verkeer Types +label.traffic.type=Verkeer Type +label.tuesday=Dinsdag +label.type.id=Type ID +label.type=Type +label.unavailable=Niet beschikbaar +label.unlimited=Ongelimiteerd +label.untagged=Untagged +label.update.project.resources=Update project verbruik +label.update.ssl.cert= SSL Certificaat +label.update.ssl= SSL Certificaat +label.updating=Bezig met updaten +label.upload=Upload +label.upload.volume=Upload Volume +label.url=URL +label.usage.interface=Verbruik Interface +label.used=Gebruikt +label.user=Gebruiker +label.username=Gebruikersnaam +label.users=Gebruikers +label.use.vm.ip=Gebruik VM IP\: +label.value=Waarde +label.vcdcname=vCenter DC naam +label.vcenter.cluster=vCenter Cluster +label.vcenter.datacenter=vCenter Datacenter +label.vcenter.datastore=VCenter Datastore +label.vcenter.host=vCenter Host +label.vcenter.password=vCenter Wachtwoord +label.vcenter.username=vCenter Gebruikersnaam +label.vcipaddress=vCenter IP Adres +label.version=Versie +label.view.all=Toon alle +label.view.console=Toon console +label.viewing=Weergeven +label.view.more=Toon meer +label.view=Toon +label.virtual.appliances=Virtueele Appliances +label.virtual.appliance=Virtuele Appliance +label.virtual.machines=Virtuele machines +label.virtual.network=Virtueel Netwerk +label.virtual.routers=Virtuele Routers +label.virtual.router=Virtuele Router +label.vm.add=Instantie Toevoegen +label.vm.destroy=Verwijder +label.vm.display.name=VM weergave naam +label.VMFS.datastore=VMFS datastore +label.vmfs=VMFS +label.vm.name=VM naam +label.vm.reboot=Reboot +label.VMs.in.tier=VMs in tier +label.vmsnapshot.current=isHuidige +label.vmsnapshot.memory=Snapshot geheugen +label.vmsnapshot.parentname=Bovenliggend +label.vmsnapshot.type=Type +label.vmsnapshot=VM Snapshots +label.vm.start=Start +label.vm.state=VM staat +label.vm.stop=Stop +label.vms=VMs +label.vmware.traffic.label=VMware verkeerslabel +label.volgroup=Volume Groep +label.volume.limits=Volume Limieten +label.volume.name=Volume Naam +label.volumes=Volumes +label.volume=Volume +label.vpc.id=VPC ID +label.VPC.router.details=VPC router details +label.vpc=VPC +label.VPN.connection=VPN Connectie +label.vpn.customer.gateway=VPN Customer Gateway +label.VPN.customer.gateway=VPN Customer Gateway +label.VPN.gateway=VPN Gateway +label.vpn=VPN +label.vsmctrlvlanid=Controle VLAN ID +label.vsmpktvlanid=Pakket VLAN ID +label.vsmstoragevlanid=Opslag VLAN ID +label.vsphere.managed=vSphere beheerd +label.waiting=Wachten +label.warn=Waarschuwing +label.wednesday=Woensdag +label.weekly=Wekelijks +label.welcome.cloud.console=Welkom op de Management Console +label.welcome=Welkom +label.what.is.cloudstack=Wat is CloudStack&\#8482? +label.xen.traffic.label=XenServer verkeerslabel +label.yes=Ja +label.zone.details=Zone details +label.zone.id=Zone ID +label.zone.name=Zone naam +label.zone.step.1.title=Stap 1\: Selecteer een Netwerk +label.zone.step.2.title=Stap 2\: Zone toevoegen +label.zone.step.3.title=Stap 3\: Pod toevoegen +label.zone.step.4.title=Step 4\: IP range toevoegen +label.zones=Zones +label.zone.type=Type Zone +label.zone.wide=Zone breed +label.zoneWizard.trafficType.guest=Gast\: Verkeer tussen virtuele machines van de eindgebruiker +label.zoneWizard.trafficType.public=Publiek\: Verkeer tussen het internet en virtueele machines in de cloud. +label.zoneWizard.trafficType.storage=Opslag\: Verkeer tussen de primaire en secundaire opslag servers zoals VM templates en snapshots +label.zone=Zone +managed.state=Beheersstaat +message.acquire.new.ip=Bevestigen dat je een nieuw IP voor dit netwerk wilt verkrijgen. +message.acquire.new.ip.vpc=Bevestig dat u een nieuw IP wilt verkrijgen voor deze VPC. +message.acquire.public.ip=Selecteer de zone waarvan u een nieuw IP wenst te verkrijgen. +message.action.cancel.maintenance=Het onderhoud voor de host is succesvol geannuleerd. Het daadwerkelijke proces kan echter enkele minuten duren. +message.action.cancel.maintenance.mode=Bevestig dat u het onderhoud wilt annuleren. +message.action.change.service.warning.for.instance=Uw instantie moet uitgeschakeld zijn voordat u de service aanbieding kunt wijzigen. +message.action.change.service.warning.for.router=Uw router moet uitgeschakeld zijn voordat u de service aanbieding kunt wijzigen. +message.action.delete.cluster=Bevestig dat u dit cluster wilt verwijderen. +message.action.delete.disk.offering=Bevestig dat u deze schijf aanbieding wilt verwijderen. +message.action.delete.domain=Bevestig dat u dit domein wilt verwijderen. +message.action.delete.external.firewall=Bevestig dat u deze externe firewall wilt verwijderen. Waarschuwing\: Als u van plan bent dezelfde firewall opnieuw toe te voegen, dient u de verbruiksstatistieken eerst te resetten. +message.action.delete.external.load.balancer=Bevestig dat u deze externe loadbalancer wilt verwijderen. Waarschuwing\: Als u van plan bent dezelfde loadbalancer opnieuw toe te voegen, dient u de verbruiksstatistieken eerst te resetten. +message.action.delete.ingress.rule=Bevestig dat u deze inkomende regel wilt verwijderen. +message.action.delete.ISO=Bevestig dat u deze ISO wilt verwijderen. +message.action.delete.ISO.for.all.zones=Deze ISO wordt gebruikt door alle zones. Bevestig dat u deze wilt verwijderen van alle zones. +message.action.delete.network=Bevestig dat u dit netwerk wilt verwijderen. +message.action.delete.nexusVswitch=Bevestig dat u deze nexus 1000v wilt verwijderen +message.action.delete.physical.network=Bevestig dat u dit fysieke netwerk wilt verwijderen. +message.action.delete.pod=Bevestig dat u deze pod wilt verwijderen. +message.action.delete.primary.storage=Bevestig dat u deze primaire opslag wilt verwijderen. +message.action.delete.secondary.storage=Bevestig dat u deze secudaire opslag wilt verwijderen. +message.action.delete.security.group=Bevestig dat u deze security group wilt verwijderen. +message.action.delete.service.offering=Bevestig dat u deze service aanbieding wilt verwijderen. +message.action.delete.snapshot=Bevestig dat u deze snapshot wilt verwijderen. +message.action.delete.system.service.offering=Bevestig dat u deze systeem service aanbieding wilt verwijderen. +message.action.delete.template=Bevestig dat u deze template wilt verwijderen +message.action.delete.template.for.all.zones=Deze template wordt gebruikt door alle zones. Bevestig dat u deze wilt verwijderen van alle zones. +message.action.delete.volume=Bevestig dat u dit volume wilt verwijderen +message.action.delete.zone=Bevestig dat u deze zone wilt verwijderen +message.action.destroy.instance=Bevestig dat u deze instantie wilt vernietigen +message.action.destroy.systemvm=Bevestig dat u deze Systeem VM wilt vernietigen +message.action.disable.cluster=Bevestig dat u dit cluster wilt uitschakelen. +message.action.disable.nexusVswitch=Bevestig dat u deze nexus 1000v wilt uitschakelen. +message.action.disable.physical.network=Bevestig dat u dit fysieke netwerk wilt uitschakelen. +message.action.disable.pod=Bevestig dat u deze pod wilt uitschakelen. +message.action.disable.static.NAT=Bevestig dat u static NAT wilt uitschakelen. +message.action.disable.zone=Bevestig dat u deze zone wilt uitschakelen. +message.action.download.iso=Bevestig dat u deze ISO wilt downloaden. +message.action.download.template=Bevestig dat u deze template wilt downloaden. +message.action.enable.cluster=Bevestig dat u dit cluster wilt inschakelen. +message.action.enable.maintenance=Uw host is succesvol voorbereid op onderhoud. Het proces kan echter een paar minuten duren afhankelijk van de hoeveelheid VMs op de host. +message.action.enable.nexusVswitch=Bevestig dat u deze nexus 1000v wilt inschakelen +message.action.enable.physical.network=Bevestig dat u dit fysieke netwerk wilt inschakelen. +message.action.enable.pod=Bevestigd dat u deze pod wilt inschakelen. +message.action.enable.zone=Bevestig dat u deze zone wilt inschakelen. +message.action.force.reconnect=De host is succesvol geforceerd om opnieuw te verbinden. Dit proces kan echter enkele minuten duren. +message.action.host.enable.maintenance.mode=Het inschakelen van de onderhoudsmodus zorgt ervoor dat alle draaiende instanties worden gemigreerd naar andere beschikbare hosts. +message.step.2.desc= +message.step.3.desc= +mode=Modus +notification.reboot.instance=Herstart instantie +state.Allocated=Gebruikt +state.Disabled=Uitgeschakeld +state.Error=Fout diff --git a/client/WEB-INF/classes/resources/messages_pl.properties b/client/WEB-INF/classes/resources/messages_pl.properties new file mode 100644 index 00000000000..9024030f51e --- /dev/null +++ b/client/WEB-INF/classes/resources/messages_pl.properties @@ -0,0 +1,469 @@ +# 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. + +error.invalid.username.password=B\u0142\u0119dna nazwa u\u017cytkownika lub has\u0142o +label.account.id=ID konta +label.account=Konto +label.account.name=Nazwa konta +label.accounts=Konta +label.action.attach.disk=Dodaj dysk +label.action.attach.disk.processing=Dodawanie dysku +label.action.attach.iso=Dodaj obraz ISO +label.action.attach.iso.processing=Dodawanie obrazu ISO +label.action.change.password=Zmie\u0144 has\u0142o +label.action.copy.ISO=Kopiuj ISO +label.action.copy.ISO.processing=Kopiuj ISO.... +label.action.copy.template=Kopij szablon +label.action.copy.template.processing=Kopije szablon.... +label.action.create.template.from.vm=Utw\u00f3rz szablon z VM +label.action.create.template.from.volume=Utw\u00f3rz Szablon z wolumenu +label.action.create.template.processing=Tworz\u0119 szablon +label.action.create.template=Utw\u00f3rz szablon +label.action.create.vm.processing=Tworz\u0119 VM.... +label.action.create.vm=Utw\u00f3rz VM +label.action.create.volume.processing=Tworz\u0119 wolumen.... +label.action.create.volume=Utw\u00f3rz wolumen +label.action.delete.account.processing=Usuwanie dost\u0119pu.... +label.action.delete.account=Usu\u0144 dost\u0119p +label.action.delete.cluster.processing=Usuwam klaster.... +label.action.delete.cluster=Usu\u0144 klaster +label.action.delete.domain.processing=Usuwam domen\u0119.... +label.action.delete.domain=Usu\u0144 domen\u0119 +label.action.delete.firewall.processing=Usuwam Firewall +label.action.delete.firewall=Usu\u0144 regu\u0142\u0119 Firewall +label.action.delete.ISO.processing=Usuwam ISO.... +label.action.delete.ISO=Usu\u0144 ISO +label.action.delete.network.processing=Usuwam sie\u0107.... +label.action.delete.network=Usu\u0144 sie\u0107 +label.action.delete.nexusVswitch=Usu\u0144 Nexus 1000v +label.action.delete.physical.network=Usu\u0144 fizyczn\u0105 sie\u0107 +label.action.delete.user.processing=Usuwam u\u017cytkownika.... +label.action.delete.user=Usu\u0144 u\u017cytkownika +label.action.delete.volume.processing=Usuwam wolumen.... +label.action.delete.volume=Usu\u0144 wolumen +label.action.delete.zone.processing=Usuwam stref\u0119.... +label.action.delete.zone=Usu\u0144 stref\u0119 +label.action.destroy.instance.processing=Usuwam instancj\u0119 +label.action.destroy.instance=Usu\u0144 instancj\u0119 +label.action.detach.disk=Od\u0142\u0105cz dysk +label.action.detach.disk.processing=Od\u0142\u0105czanie dysku.... +label.action.detach.iso=Od\u0142\u0105cz obraz ISO +label.action.detach.iso.processing=Od\u0142\u0105czanie obrazu ISO +label.action.disable.account.processing=Wy\u0142\u0105czam dost\u0119p.... +label.action.disable.account=Wy\u0142\u0105cz dost\u0119p +label.action.disable.cluster.processing=Wy\u0142\u0105czam klaster.... +label.action.disable.cluster=Wy\u0142\u0105cz klaster +label.action.disable.nexusVswitch=Wy\u0142\u0105cz Nexus 1000v +label.action.disable.physical.network=Wy\u0142\u0105cz fizyczn\u0105 sie\u0107 +label.action.disable.user.processing=Wy\u0142\u0105czam u\u017cytkownika +label.action.disable.user=Wy\u0142\u0105cz u\u017cytkownika +label.action.disable.zone.processing=Wy\u0142\u0105czam stref\u0119.... +label.action.disable.zone=Wy\u0142\u0105cz stref\u0119 +label.action.download.ISO=Pobierz ISO +label.action.download.template=Pobierz szablon +label.action.download.volume=Pobierz wolumen +label.action.download.volume.processing=Pobieram wolumen.... +label.action.edit.account=Edytuj dost\u0119p +label.action.edit.domain=Edytuj domen\u0119 +label.action.edit.global.setting=Edytuj Globalne ustawienia +label.action.edit.host=Edytuj host +label.action.edit.instance=Edytuj instancj\u0119 +label.action.edit.ISO=Edytuj ISO +label.action.edit.network=Edytuj sie\u0107 +label.action.edit.network.processing=Zmieniam sie\u0107.... +label.action.edit.template=Edytuj szablon +label.action.edit.user=Edytuj u\u017cytkownika +label.action.edit.zone=Edytuj stref\u0119 +label.action.enable.account.processing=W\u0142\u0105czam dost\u0119p.... +label.action.enable.account=W\u0142\u0105cz dost\u0119p +label.action.enable.cluster.processing=W\u0142\u0105czam klaster.... +label.action.enable.cluster=W\u0142\u0105cz klaster +label.action.enable.nexusVswitch=W\u0142\u0105cz Nexus 1000v +label.action.enable.physical.network=W\u0142\u0105cz fizyczn\u0105 sie\u0107 +label.action.enable.user.processing=W\u0142\u0105czam u\u017cytkownika.... +label.action.enable.user=W\u0142\u0105cz u\u017cytkownika +label.action.enable.zone.processing=W\u0142\u0105czam stref\u0119.... +label.action.enable.zone=W\u0142\u0105cz stref\u0119 +label.action.generate.keys=Generuj klucze +label.action.generate.keys.processing=Generuj\u0119 klucze.... +label.action.list.nexusVswitch=Kista Nexus 1000v +label.action.lock.account.processing=Blokuj\u0119 dost\u0119p.... +label.action.lock.account=Zablokuj dost\u0119p +label.action.manage.cluster.processing=Zarz\u0105dzam klastrem.... +label.action.manage.cluster=Zarz\u0105dzaj klastrem +label.action.migrate.instance=Migruj instancj\u0119 +label.action.migrate.instance.processing=Migruj\u0119 instancj\u0119.... +label.action.migrate.router=Migruj router +label.action.migrate.router.processing=Migruje router.... +label.action.migrate.systemvm=Migruj system VM +label.action.migrate.systemvm.processing=Migruj\u0119 system VM.... +label.action.reboot.instance.processing=Restartuje instancj\u0119 +label.action.reboot.instance=Restartuj instancj\u0119 +label.action.reboot.router.processing=Restartuje router..... +label.action.reboot.router=Restartuj router +label.action.reboot.systemvm.processing=Restartuje system VM.... +label.action.reboot.systemvm=Restartuj system VM +label.action.register.iso=Rejestruj ISO +label.action.register.template=Rejestruj szablon +label.action.remove.host.processing=Usuwam host.... +label.action.remove.host=Usu\u0144 host +label.action.reset.password.processing=Resetuj\u0119 has\u0142o.... +label.action.reset.password=Resetuj has\u0142o +label.action.resize.volume.processing=Zmieniam wielko\u015b\u0107 wolumenu.... +label.action.resize.volume=Zmie\u0144 wielko\u015b\u0107 wolumenu +label.action.restore.instance=Przywr\u00f3\u0107 instancj\u0119 +label.actions=Akcje +label.action.start.instance.processing=Uruchamiam instancj\u0119.... +label.action.start.instance=Uruchom instancj\u0119 +label.action.start.router.processing=Uruchamiam router.... +label.action.start.router=Uruchom router +label.action.start.systemvm.processing=Uruchamiam system VM... +label.action.start.systemvm=Uruchom system VM +label.action.stop.instance.processing=Zatrzymuj\u0119 instancj\u0119.... +label.action.stop.instance=Zatrzymaj instancj\u0119 +label.action.stop.router.processing=Zatrzymuj\u0119 router... +label.action.stop.router=Zatrzymaj router +label.action.stop.systemvm.processing=Zatrzymuj\u0119 system VM.... +label.action.stop.systemvm=Zatrzymaj system VM +label.action.take.snapshot.processing=Tworz\u0119 snapshot.... +label.action.take.snapshot=Zr\u00f3b snapshot +label.activate.project=Aktywuj projekt +label.add.account=Dodaj konto +label.add.accounts=Dodaj konta +label.add.accounts.to=Dodaj konto do +label.add.account.to.project=Dodaj konto do projektu +label.add.ACL=Dodaj ACL +label.add.by.cidr=Dodaj przez CIDR +label.add.by=Dodaj przez +label.add.by.group=Dodaj przez grup\u0119 +label.add.cluster=Dodaj klaster +label.add=Dodaj +label.add.domain=Dodaj domen\u0119 +label.add.firewall=Dodaj regu\u0142\u0119 firewall +label.add.host=Dodaj host +label.adding=Dodawanie +label.adding.failed=Dodanie nieudane +label.adding.processing=Dodawanie +label.adding.succeeded=Dodanie udane +label.add.more=Dodaj wi\u0119cej +label.add.network.device=Dodaj urz\u0105dzenie sieciowe +label.add.network=Dodaj sie\u0107 +label.add.new.F5=Dodaj nowy F5 +label.add.new.SRX=Dodaj nowy SRX +label.add.region=Dodaj region +label.add.rule=Dodaj regu\u0142\u0119 +label.add.to.group=Dodaj do grupy +label.add.user=Dodaj u\u017cytkownika +label.add.vlan=Dodaj VLAN +label.add.vm=Dodaj VM +label.add.vms=Dodaj VM-ny +label.add.volume=Dodaj wolumen +label.add.vpc=Dodaj VPC +label.add.zone=Dodaj stref\u0119 +label.admin=Admin +label.api.key=Klucz API +label.apply=Zastosuj +label.author.name=Imi\u0119 autora +label.available=Dost\u0119pne +label.available.public.ips=Dost\u0119pne publiczne adresy IP +label.back=Wstecz +label.bandwidth=Przepustowo\u015b\u0107 +label.cancel=Zako\u0144cz +label.certificate=Certyfikat +label.cidr=CIDR +label.CIDR.list=Lista CIDR +label.clean.up=Wyczy\u015b\u0107 +label.clear.list=Wyczy\u015b\u0107 list\u0119 +label.close=Zamknij +label.clvm=CLVM +label.code=Kod +label.community=Spo\u0142eczno\u015b\u0107 +label.configuration=Konfiguracja +label.configure=Konfiguruj +label.configure.vpc=Konfiguruj VPC +label.confirmation=Potwierdzenie +label.confirm.password=Potwierd\u017a has\u0142o +label.congratulations=Gratulacje\! +label.continue=Kontynuuj +label.corrections.saved=Poprawka zapisana +label.cpu=CPU +label.cpu.limits=Limit CPU +label.cpu.mhz=CPU (w MHz) +label.created.by.system=Utworzono przez system +label.created=Utworzono +label.create.project=Stw\u00f3rz projekt +label.daily=Dziennie +label.date=Data +label.day.of.month=Dzie\u0144 miesi\u0105ca +label.day.of.week=Dzie\u0144 tygodnia +label.dedicated=Dedykowany +label.default=Domy\u015blnie +label.default.view=Widok domy\u015blny +label.delete.F5=Usu\u0144 F5 +label.delete.project=Usu\u0144 projekt +label.delete.SRX=Usu\u0144 SRX +label.delete=Usu\u0144 +label.deleting.failed=Usuwanie nieudane +label.deleting.processing=Usuwanie.... +label.destroy.router=Zniszcz router +label.destroy=Zniszcz +label.detaching.disk=Od\u0142\u0105czanie dysku +label.details=Szczeg\u00f3\u0142y +label.disabled=Wy\u0142\u0105czony +label.disable.vpn=Wy\u0142\u0105cz VPN +label.disk.size.gb=Wielko\u015b\u0107 dysku (w GB) +label.disk.size=Wielko\u015b\u0107 dysku +label.display.name=Wy\u015bwietlana nazwa +label.domain.admin=Administrator domeny +label.domain=Domena +label.domain.id=ID domeny +label.domain.name=Nazwa domeny +label.done=Sko\u0144czono +label.download.progress=Post\u0119p w pobieraniu +label.drag.new.position=Przenie\u015b w nowe miejsce +label.edit=Edytuj +label.edit.network.details=Edytuj szczeg\u00f3\u0142y sieci +label.edit.project.details=Zmie\u0144 szczeg\u00f3\u0142y projektu +label.edit.vpc=Edytuj VPC +label.elastic=Elastyczny +label.elastic.IP=Zmienne IP +label.email=Poczta +label.enable.vpn=W\u0142\u0105cz VPN +label.error=B\u0142\u0105d +label.f5=F5 +label.featured=Polecane +label.filterBy=Filtrowanie wg +label.firewall=Zapora +label.first.name=Pierwsza nazwa +label.format=Format +label.friday=Pi\u0105tek +label.full.path=Pe\u0142na \u015bcie\u017cka +label.go.step.2=Id\u017a do punktu 2 +label.go.step.3=Id\u017a do punktu 3 +label.go.step.4=Id\u017a do punktu 4 +label.go.step.5=Id\u017a do punktu 5 +label.group=Grupa +label.group.optional=Grupa (opcjonalnie) +label.guest=Go\u015b\u0107 +label.guest.type=Rodzaj go\u015bci +label.help=Pomoc +label.hints=Podpowiedzi +label.id=ID +label.info=Informacje +label.instances=Instancje +label.invitations=Zaproszenia +label.invited.accounts=Zaproszone konta +label.invite.to=Zapro\u015b do +label.invite=Zapro\u015b +label.ip=IP +label.iso=ISO +label.keep=Zostaw +label.key=Klucz +label.lang.english=Angielski +label.lang.french=Francuski +label.lang.japanese=Japo\u0144ski +label.lang.korean=Korea\u0144ski +label.lang.russian=Rosyjski +label.lang.spanish=Hiszpia\u0144ski +label.last.name=Nazwisko +label.least.connections=Ostatnie po\u0142\u0105czenie +label.level=Poziom +label.loading=Wczytywanie +label.local=Lokalne +label.local.storage.enabled=Pami\u0119\u0107 lokalna w\u0142\u0105czona +label.local.storage=Pami\u0119\u0107 lokalna +label.login=Zaloguj +label.logout=Wyloguj +label.lun=LUN +label.LUN.number=LUN \# +label.max.guest.limit=Maksymalna liczba go\u015bci +label.maximum=Maksimum +label.max.public.ips=Maksymalna liczba publicznych adres\u00f3w IP +label.memory.limits=Limit pami\u0119ci (MiB) +label.memory.mb=Pami\u0119\u0107 (w MB) +label.memory=Pami\u0119\u0107 +label.menu.accounts=Konta +label.menu.alerts=Alarmy +label.menu.all.accounts=Wszystkie konta +label.menu.all.instances=Wszystkie instancje +label.menu.configuration=Konfiguracja +label.menu.domains=Domeny +label.menu.infrastructure=Infrastruktura +label.menu.instances=Instancje +label.menu.ipaddresses=Adresy IP +label.menu.isos=ISO +label.menu.my.accounts=Moje konta +label.menu.my.instances=Moje instancje +label.menu.my.isos=Moje ISO +label.menu.network=Sie\u0107 +label.menu.regions=Regiony +label.menu.system=System +label.minimum=Minimum +label.monday=Poniedzia\u0142ek +label.monthly=Miesi\u0119cznie +label.move.down.row=Jeden rz\u0105d na d\u00f3\u0142 +label.move.to.top=Przenie\u015b na sam\u0105 g\u00f3r\u0119 +label.move.up.row=Jeden rz\u0105d do g\u00f3ry +label.my.account=Moje konto +label.my.network=Moja sie\u0107 +label.name=Nazwa +label.name.optional=Nazwa (opcjonalnie) +label.network.id=ID sieci +label.network.name=Nazwa sieci +label.network=Sie\u0107 +label.networks=Sieci +label.new=Nowy +label.new.project=Nowy projekt +label.next=Nast\u0119pny +label.nfs=NFS +label.nfs.server=Serwer NFS +label.no.data=Brak danych +label.none=Brak +label.no=Nie +label.no.thanks=Nie dzi\u0119kuj\u0119 +label.notifications=Przypomnienia +label.number.of.hosts=Liczba host\u00f3w +label.ok=OK +label.order=Zadanie +label.password=Has\u0142o +label.path=\u015acie\u017cka +label.please.wait=Prosz\u0119 czeka\u0107 +label.plugin.details=Szczeg\u00f3\u0142y wtyczki +label.plugins=Wtyczki +label.previous=Wstecz +label.private.network=Sie\u0107 prywatna +label.project.id=Nazwa ID projektu +label.project.invite=Zapro\u015b do projektu +label.project.name=Nazwa projektu +label.project=Projekt +label.projects=Projekty +label.protocol=Protok\u00f3\u0142 +label.providers=Dostawcy +label.public.ip=Publiczny adres IP +label.public.ips=Publiczne adresy IP +label.public.network=Sie\u0107 publiczna +label.public=Pobliczny +label.public.port=Publiczny port +label.reboot=Uruchom ponownie +label.refresh=Od\u015bwie\u017c +label.region=Region +label.remind.later=Przypomnij p\u00f3\u017aniej +label.remove.rule=Usu\u0144 regu\u0142\u0119 +label.remove.vpc=Usu\u0144 VPC +label.removing.user=Usu\u0144 u\u017cytkownika +label.removing=Usuwanie +label.required=Wymagane +label.resource.limits=Limit zasob\u00f3w +label.resources=Zasoby +label.resource=Zas\u00f3b +label.restart.required=Wymagany restart +label.rules=Zasady +label.saturday=Sobota +label.save.and.continue=Zapisz i kontynuuj +label.save=Zapisz +label.saving.processing=Zapisywanie.... +label.search=Szukaj +label.select.instance=Wybierz instancj\u0119 +label.select.project=Wybierz projekt +label.select=Wybierz +label.sent=Wys\u0142ano +label.server=Serwer +label.size=Wielko\u015bc +label.specify.IP.ranges=Wyszczeg\u00f3lnij zasi\u0119g adres\u00f3w IP +label.srx=SRX +label.statistics=Statystyki +label.status=Status +label.step.1=Krok 1 +label.step.2=Krok 2 +label.step.3=Krok 3 +label.step.4=Krok 4 +label.step.5=Krok 5 +label.sticky.domain=Domena +label.sticky.expire=Wygasa +label.sticky.length=D\u0142ugo\u015b\u0107 +label.sticky.mode=Tryb +label.sticky.prefix=Prefiks +label.stop=Stop +label.sunday=Niedziela +label.suspend.project=Zawie\u015b projekt +label.tagged=Otagowany +label.tags=Tagi +label.task.completed=Zadania uko\u0144czone +label.time=Czas +label.time.zone=Strefa czasowa +label.timezone=Strefa czasowa +label.type.id=Wpisz ID +label.type=Wpisz +label.unavailable=Niedost\u0119pny +label.unlimited=Nieograniczony +label.untagged=Nieotagowany +label.updating=Aktualizowanie +label.url=URL +label.used=U\u017cyte +label.username=Nazwa u\u017cytkownika +label.users=U\u017cytkownicy +label.user=U\u017cytkowni +label.version=Wersja +label.view.all=Zobacz wszystko +label.view=Zobacz +label.vm.add=Dodaj instancj\u0119 +label.vm.destroy=Zniszcz +label.vmfs=VMFS +label.vm.name=Nazwa VM +label.vm.reboot=Uruchom ponownie +label.vmsnapshot.type=Wpisz +label.vm.start=Rozpocznij +label.vm.stop=Stop +label.vms=VMs +label.vpc=VPC +label.vpn=VPN +label.waiting=Czekanie +label.warn=Ostrze\u017cenie +label.wednesday=\u015aroda +label.weekly=Tygodniowo +label.welcome=Witaj +label.what.is.cloudstack=Czym jest CloudStack&\#8482? +label.yes=Tak +message.action.delete.nexusVswitch=Potwierd\u017a, \u017ce chcesz usun\u0105\u0107\: nexus 1000v +message.action.download.iso=Potwierd\u017a, \u017ce chcesz pobra\u0107 ten obraz ISO. +message.activate.project=Czy na pewno chcesz aktywowa\u0107 ten projekt? +message.confirm.delete.F5=Czy na pewno chcesz usun\u0105\u0107 F5? +message.confirm.delete.SRX=Czy na pewno chcesz usun\u0105\u0107 SRX? +message.delete.project=Czy na pewno chcesz usun\u0105\u0107 ten projekt? +message.disable.vpn=Czy na pewno chcesz wy\u0142\u0105czy\u0107 VPN? +message.no.projects=Nie posiadasz \u017cadnych projekt\u00f3w.
Utw\u00f3rz nowy projekt w zak\u0142adce projekty +message.please.proceed=Przejd\u017a do nast\u0119pnego punktu +message.step.2.desc= +message.step.3.desc= +message.suspend.project=Czy na pewno chcesz zawiesi\u0107 ten projekt +mode=Tryb +state.Accepted=Akceptowano +state.Active=Aktywny +state.Completed=Uko\u0144czono +state.Creating=Tworzenie +state.Declined=Odrzucono +state.Destroyed=Zniszczono +state.Disabled=Wy\u0142\u0105czony +state.enabled=W\u0142\u0105czone +state.Enabled=W\u0142\u0105czone +state.Error=B\u0142\u0105d +state.ready=Gotowe +state.Ready=Gotowe +state.Starting=Rozpoczynanie +state.Stopped=Zatrzymano +state.Suspended=Zawieszono +ui.listView.filters.all=Wszystko diff --git a/client/WEB-INF/classes/resources/messages_pt_BR.properties b/client/WEB-INF/classes/resources/messages_pt_BR.properties index 86bb83177a8..07fd3f42d76 100644 --- a/client/WEB-INF/classes/resources/messages_pt_BR.properties +++ b/client/WEB-INF/classes/resources/messages_pt_BR.properties @@ -373,6 +373,7 @@ label.compute.and.storage=Processamento e Armazenamento label.compute.offering=Oferta de Computa\u00e7\u00e3o label.configuration=Configura\u00e7\u00e3o label.configure=Configurar +label.configure.ldap=Configurar LDAP label.configure.network.ACLs=Configure ACLs de rede label.configure.vpc=Configurar VPC label.confirmation=Confirma\u00e7\u00e3o @@ -390,6 +391,7 @@ label.cpu.mhz=CPU (em MHz) label.cpu.utilized=CPU Utilizada label.created.by.system=Criado pelo sistema label.created=Criado +label.create.nfs.secondary.staging.store=Criar storage staging secund\u00e1rio NFS label.create.project=Criar um projeto label.create.template=Criar template label.create.VPN.connection=Criar uma conex\u00e3o VPN @@ -418,6 +420,7 @@ label.delete.VPN.gateway=deletar um gateway de VPN label.delete.vpn.user=Deletar usu\u00e1rio VPN label.deleting.failed=Falha ao remover label.deleting.processing=Removendo.... +label.deployment.planner=Deployment planejado label.description=Descri\u00e7\u00e3o label.destination.physical.network.id=ID de destino da rede f\u00edsica label.destination.zone=Zona de Destino @@ -617,6 +620,9 @@ label.launch=Executar label.launch.vm=Executar VM label.launch.zone=Executar zona. label.LB.isolation=Isolamento de LB +label.ldap.configuration=Configura\u00e7\u00e3o do LDAP +label.ldap.group.name=Grupo LDAP +label.ldap.port=Porta do LDAP label.least.connections=Least connections label.level=N\u00edvel label.load.balancer=Load Balancer @@ -784,6 +790,7 @@ label.PING.CIFS.password=PING CIFS password label.PING.CIFS.username=PING CIFS username label.PING.dir=PING Directory label.PING.storage.IP=Disparar PING para IP do Storage +label.planner.mode=Modo planejado label.please.specify.netscaler.info=Por favor especifique as informa\u00e7\u00f5es do Netscaler label.please.wait=Por Favor Aguarde label.pod.name=Nome do Pod @@ -791,6 +798,7 @@ label.pod=POD label.pods=Pods label.port.forwarding=Encaminhamento de Porta label.port.forwarding.policies=Pol\u00edticas de redirecionamento de portas +label.port=Porta label.port.range=Range de Porta label.PreSetup=PreSetup label.previous=Anterior @@ -829,6 +837,15 @@ label.public.zone=Zona P\u00fablica label.purpose=Prop\u00f3sito label.Pxe.server.type=Tipo de Servidor PXE label.quickview=Visualiza\u00e7\u00e3o r\u00e1pida +<<<<<<< HEAD +======= +label.quiesce.vm=Quiesce VM +label.rbd.id=Usu\u00e1rio Ceph +label.rbd.monitor=Monitor Ceph +label.rbd.pool=Pool Ceph +label.rbd=RDB +label.rbd.secret=Cephx secret +>>>>>>> 4e449ff... Add Dutch (Netherlands, Polish languages in Web UI Change Japanese code (ja -> ja_JP) Update transifex sync config label.reboot=Reiniciar label.recent.errors=Erros Recentes label.redundant.router.capability=Recurso de roteador redundante @@ -841,6 +858,7 @@ label.remove.egress.rule=Remover regra egress label.remove.from.load.balancer=Removendo Cloud Server do Load Balancer label.remove.ingress.rule=Remover regra ingress label.remove.ip.range=Remover range de IP +label.remove.ldap=Remover LDAP label.remove.pf=Remover regra de redirecionamento de porta label.remove.project.account=Remover conta de projeto label.remove.rule=Remover regra @@ -924,6 +942,9 @@ label.show.ingress.rule=Mostrar Regra de Entrada label.site.to.site.VPN=Site-to-site VPN label.size=Tamanho label.skip.guide=Eu utilizei o CloudStack antes, pular este guia +label.smb.domain=Dom\u00ednio SMB +label.smb.password=Senha SMB +label.smb.username=Usu\u00e1rio SMB label.snapshot.limits=Limites de Snapshot label.snapshot.name=Nome do Snapshot label.snapshot=Snapshot @@ -1080,6 +1101,12 @@ label.vm.state=Estado da VM label.vm.stop=Parar label.vms=VMs label.vmware.traffic.label=Etiqueta de tr\u00e1fego VMware +<<<<<<< HEAD +======= +label.vnet.id=VLAN ID +label.vnet=VLAN +label.volatile=Vol\u00e1til +>>>>>>> 4e449ff... Add Dutch (Netherlands, Polish languages in Web UI Change Japanese code (ja -> ja_JP) Update transifex sync config label.volgroup=Grupo de Volume label.volume=Disco label.volume.limits=Limites de Disco @@ -1230,6 +1257,7 @@ message.basic.mode.desc=Escolha este modelo de rede se voc\u00ea *n\u00e3o message.change.offering.confirm=Confirme que voc\u00ea deseja mudar o plano deste Cloud Server. message.change.password=Por favor, troque sua senha. message.configure.all.traffic.types=Voc\u00ea tem m\u00faltiplas redes f\u00edsicas; favor configurar etiquetas para cada tipo de tr\u00e1fego clicando no bot\u00e3o Edit. +message.configure.ldap=Por favor, confirme que voc\u00ea deseja configurar o LDAP. message.configuring.guest.traffic=Configurando tr\u00e1fego do guest message.configuring.physical.networks=Configurando redes f\u00edsicas message.configuring.public.traffic=Configurando tr\u00e1fego p\u00fablico @@ -1355,6 +1383,14 @@ message.please.select.a.different.public.and.management.network.before.removing= message.please.select.networks=Por favor selecione as redes para sua m\u00e1quina virtual. message.please.wait.while.zone.is.being.created=Por favor, espere enquanto sua zona est\u00e1 sendo criada; isto pode demorar um pouco... message.project.invite.sent=Convite enviado para o usu\u00e1rio; Eles ser\u00e3o adicionados ao projeto ap\u00f3s aceitarem o convite +<<<<<<< HEAD +======= +message.public.traffic.in.advanced.zone=O tr\u00e1fego p\u00fablico \u00e9 gerado quando as VMs na nuvem acessam a internet. Os IPs acess\u00edveis ao p\u00fablico devem ser alocados para essa finalidade. Os usu\u00e1rios finais podem usar a interface do usu\u00e1rio CloudStack para adquirir esses IPs afim de implementar NAT entre a sua rede de guests e sua rede p\u00fablica.

Forne\u00e7a pelo menos um intervalo de endere\u00e7os IP para o tr\u00e1fego de internet. +message.public.traffic.in.basic.zone=O tr\u00e1fego p\u00fablico \u00e9 gerado quando as VMs na nuvem acessam a Internet ou prestam servi\u00e7os aos clientes atrav\u00e9s da Internet. Os IPs acess\u00edveis ao p\u00fablico devem ser alocados para essa finalidade. Quando uma inst\u00e2ncia \u00e9 criada, um IP a partir deste conjunto de IPs p\u00fablicos ser\u00e3o destinados \u00e0 inst\u00e2ncia, al\u00e9m do endere\u00e7o IP guest. Um NAT est\u00e1tico 1-1 ser\u00e1 criada automaticamente entre o IP p\u00fablico e IP guest. Os usu\u00e1rios finais tamb\u00e9m podem usar a interface de usu\u00e1rio CloudStack para adquirir IPs adicionais afim de se implementar NAT est\u00e1tico entre suas inst\u00e2ncias e o IP p\u00fablico. +message.redirecting.region=Redirecionando para regi\u00e3o... +message.remove.ldap=Voc\u00ea tem certeza que deseja deletar a configura\u00e7\u00e3o LDAP? +message.remove.region=Voc\u00ea tem certeza que deseja remover esta regi\u00e3o deste servidor de gerenciamento? +>>>>>>> 4e449ff... Add Dutch (Netherlands, Polish languages in Web UI Change Japanese code (ja -> ja_JP) Update transifex sync config message.remove.vpc=Favor confirmar que voc\u00ea deseja remover a VPC message.remove.vpn.access=Confirme se voc\u00ea deseja remover acesso VPN do seguinte Usu\u00e1rio. message.reset.password.warning.notPasswordEnabled=O template desta inst\u00e2ncia foi criado sem senha habilitada diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index c5ac7fd67af..4f38c317bdd 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -72,6 +72,7 @@ migrateVirtualMachine=1 migrateVirtualMachineWithVolume=1 recoverVirtualMachine=7 expungeVirtualMachine=7 +getVirtualMachineUserData=15 #### snapshot commands createSnapshot=15 diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java new file mode 100644 index 00000000000..46e003ecae3 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +import java.util.List; + +public class GetVmConfigAnswer extends Answer { + + String vmName; + List nics; + + protected GetVmConfigAnswer() { + } + + public GetVmConfigAnswer(String vmName, List nics) { + this.vmName = vmName; + this.nics = nics; + } + + public String getVmName() { + return vmName; + } + + public List getNics() { + return nics; + } + + public class NicDetails { + String macAddress; + int vlanid; + + public NicDetails() { + } + + public NicDetails(String macAddress, int vlanid) { + this.macAddress = macAddress; + this.vlanid = vlanid; + } + + public String getMacAddress() { + return macAddress; + } + + public int getVlanid() { + return vlanid; + } + + } + + @Override + public boolean executeInSequence() { + return false; + } +} \ No newline at end of file diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDao.java b/core/src/com/cloud/agent/api/GetVmConfigCommand.java similarity index 56% rename from server/src/com/cloud/uuididentity/dao/IdentityDao.java rename to core/src/com/cloud/agent/api/GetVmConfigCommand.java index a0978fac17c..9133bd6b2c3 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityDao.java +++ b/core/src/com/cloud/agent/api/GetVmConfigCommand.java @@ -14,25 +14,33 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +package com.cloud.agent.api; -package com.cloud.uuididentity.dao; -import com.cloud.server.ResourceTag.ResourceObjectType; -import com.cloud.utils.Pair; -import com.cloud.utils.db.GenericDao; +import java.util.List; -public interface IdentityDao extends GenericDao { - Long getIdentityId(String tableName, String identityString); +import com.cloud.agent.api.to.NicTO; - String getIdentityUuid(String tableName, String identityString); +public class GetVmConfigCommand extends Command { + String vmName; + List nics; + protected GetVmConfigCommand() { + } - void initializeDefaultUuid(String tableName); + public GetVmConfigCommand(String vmName) { + this.vmName = vmName; + } - /** - * @param tableName - * @param identityId - * @param resourceType TODO - * @return - */ - Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType); + public String getVmName() { + return vmName; + } + + public void setNics(List nics){ + this.nics = nics; + } + + @Override + public boolean executeInSequence() { + return false; + } } diff --git a/api/src/org/apache/cloudstack/api/IdentityService.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java similarity index 67% rename from api/src/org/apache/cloudstack/api/IdentityService.java rename to core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java index 8451945ef81..1140485c67c 100644 --- a/api/src/org/apache/cloudstack/api/IdentityService.java +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java @@ -14,10 +14,23 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.api; +package com.cloud.agent.api; -public interface IdentityService { - Long getIdentityId(String tableName, String identityString); +public class ModifyVmNicConfigAnswer extends Answer { + String vmName; + protected ModifyVmNicConfigAnswer() { + } - String getIdentityUuid(String tableName, String identityString); + public ModifyVmNicConfigAnswer(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + @Override + public boolean executeInSequence() { + return false; + } } diff --git a/server/src/com/cloud/uuididentity/IdentityServiceImpl.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java similarity index 52% rename from server/src/com/cloud/uuididentity/IdentityServiceImpl.java rename to core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java index 039bb318905..0230beca732 100644 --- a/server/src/com/cloud/uuididentity/IdentityServiceImpl.java +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java @@ -14,31 +14,29 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.uuididentity; +package com.cloud.agent.api; -import javax.ejb.Local; -import javax.inject.Inject; -import org.springframework.stereotype.Component; - -import org.apache.cloudstack.api.IdentityService; - -import com.cloud.utils.component.ManagerBase; -import com.cloud.uuididentity.dao.IdentityDao; - -@Component -@Local(value = {IdentityService.class}) -public class IdentityServiceImpl extends ManagerBase implements IdentityService { - @Inject - private IdentityDao _identityDao; - - @Override - public Long getIdentityId(String tableName, String identityString) { - return _identityDao.getIdentityId(tableName, identityString); +public class ModifyVmNicConfigCommand extends Command { + String vmName; + int vlan; + String macAddress; + protected ModifyVmNicConfigCommand() { } + public ModifyVmNicConfigCommand(String vmName, int vlan, String macAddress) { + this.vmName = vmName; + this.vlan = vlan; + this.macAddress = macAddress; + } + + public String getVmName() { + return vmName; + } + + @Override - public String getIdentityUuid(String tableName, String identityString) { - return _identityDao.getIdentityUuid(tableName, identityString); + public boolean executeInSequence() { + return false; } } diff --git a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java index 9a2bea875b4..217e962d18a 100644 --- a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -16,10 +16,10 @@ // under the License. package com.cloud.agent.api.routing; -import java.util.HashMap; - import com.cloud.agent.api.Command; +import java.util.HashMap; + public abstract class NetworkElementCommand extends Command { HashMap accessDetails = new HashMap(0); @@ -35,6 +35,8 @@ public abstract class NetworkElementCommand extends Command { public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private"; public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default"; + private String routerAccessIp; + protected NetworkElementCommand() { super(); } @@ -52,4 +54,11 @@ public abstract class NetworkElementCommand extends Command { return false; } + public String getRouterAccessIp() { + return routerAccessIp; + } + + public void setRouterAccessIp(String routerAccessIp) { + this.routerAccessIp = routerAccessIp; + } } diff --git a/server/src/com/cloud/uuididentity/dao/IdentityVO.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java similarity index 62% rename from server/src/com/cloud/uuididentity/dao/IdentityVO.java rename to core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java index c40f40bc702..243098abeab 100644 --- a/server/src/com/cloud/uuididentity/dao/IdentityVO.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java @@ -14,12 +14,14 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.uuididentity.dao; +package com.cloud.agent.resource.virtualnetwork; -import javax.persistence.Entity; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.utils.ExecutionResult; -/** - */ -@Entity -public class IdentityVO { +public interface VirtualRouterDeployer { + ExecutionResult executeInVR(String routerIp, String script, String args); + ExecutionResult createFileInVR(String routerIp, String path, String filename, String content); + ExecutionResult prepareCommand(NetworkElementCommand cmd); + ExecutionResult cleanupCommand(NetworkElementCommand cmd); } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 15f1c40e3ce..1ed38644536 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -16,30 +16,6 @@ // under the License. package com.cloud.agent.resource.virtualnetwork; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.InetSocketAddress; -import java.net.URL; -import java.net.URLConnection; -import java.nio.channels.SocketChannel; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckRouterAnswer; @@ -49,9 +25,8 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; -import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; -import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.routing.CreateIpAliasCommand; import com.cloud.agent.api.routing.DeleteIpAliasCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; @@ -59,15 +34,21 @@ import com.cloud.agent.api.routing.DnsMasqConfigCommand; import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetMonitorServiceCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatAnswer; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticRouteAnswer; @@ -78,19 +59,26 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.exception.InternalErrorException; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.ComponentLifecycle; -import com.cloud.utils.component.Manager; import com.cloud.utils.net.NetUtils; -import com.cloud.utils.script.OutputInterpreter; -import com.cloud.utils.script.Script; -import com.cloud.utils.ssh.SshHelper; +import com.google.gson.Gson; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import javax.naming.ConfigurationException; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SocketChannel; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * VirtualNetworkResource controls and configures virtual networking @@ -100,31 +88,27 @@ import com.cloud.utils.ssh.SshHelper; * || Param Name | Description | Values | Default || * } **/ -@Local(value = {VirtualRoutingResource.class}) -public class VirtualRoutingResource implements Manager { +public class VirtualRoutingResource { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); - private String _publicIpAddress; - private String _firewallPath; - private String _loadbPath; - private String _dhcpEntryPath; - private String _publicEthIf; - private String _privateEthIf; - private String _bumpUpPriorityPath; - private String _routerProxyPath; - private String _createIpAliasPath; - private String _deleteIpAliasPath; - private String _callDnsMasqPath; + private VirtualRouterDeployer _vrDeployer; - private int _timeout; - private int _startTimeout; - private String _scriptsDir; private String _name; private int _sleep; private int _retry; private int _port; + public VirtualRoutingResource(VirtualRouterDeployer deployer) { + this._vrDeployer = deployer; + } + public Answer executeRequest(final Command cmd) { try { + ExecutionResult rc = _vrDeployer.prepareCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to prepare VR command due to " + rc.getDetails()); + return new Answer(cmd, false, rc.getDetails()); + } + if (cmd instanceof SetPortForwardingRulesVpcCommand) { return execute((SetPortForwardingRulesVpcCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { @@ -135,12 +119,6 @@ public class VirtualRoutingResource implements Manager { return execute((SetStaticNatRulesCommand)cmd); } else if (cmd instanceof LoadBalancerConfigCommand) { return execute((LoadBalancerConfigCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); - } else if (cmd instanceof CheckConsoleProxyLoadCommand) { - return execute((CheckConsoleProxyLoadCommand)cmd); - } else if (cmd instanceof WatchConsoleProxyLoadCommand) { - return execute((WatchConsoleProxyLoadCommand)cmd); } else if (cmd instanceof SavePasswordCommand) { return execute((SavePasswordCommand)cmd); } else if (cmd instanceof DhcpEntryCommand) { @@ -169,11 +147,28 @@ public class VirtualRoutingResource implements Manager { return execute((Site2SiteVpnCfgCommand)cmd); } else if (cmd instanceof CheckS2SVpnConnectionsCommand) { return execute((CheckS2SVpnConnectionsCommand)cmd); + } else if (cmd instanceof SetMonitorServiceCommand) { + return execute((SetMonitorServiceCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return execute((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return execute((SetNetworkACLCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return execute((SetSourceNatCommand)cmd); + } else if (cmd instanceof IpAssocVpcCommand) { + return execute((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return execute((IpAssocCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } catch (final IllegalArgumentException e) { return new Answer(cmd, false, e.getMessage()); + } finally { + ExecutionResult rc = _vrDeployer.cleanupCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to cleanup VR command due to " + rc.getDetails()); + } } } @@ -187,9 +182,9 @@ public class VirtualRoutingResource implements Manager { args += "-u "; args += userpwd.getUsernamePassword(); } - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername() + ":" + result.getDetails()); } } return new Answer(cmd); @@ -214,22 +209,16 @@ public class VirtualRoutingResource implements Manager { } args += " -C " + cmd.getLocalCidr(); args += " -i " + cmd.getPublicInterface(); - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN failed"); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private Answer execute(SetFirewallRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; - for (int i = 0; i < cmd.getRules().length; i++) { - results[i] = "Failed"; - } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerAccessIp = cmd.getRouterAccessIp(); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - if (routerIp == null) { + if (routerAccessIp == null) { return new SetFirewallRulesAnswer(cmd, false, results); } @@ -237,18 +226,16 @@ public class VirtualRoutingResource implements Manager { FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); String[][] rules = cmd.generateFwRules(); - final Script command = new Script(_firewallPath, _timeout, s_logger); - command.add(routerIp); - command.add("-F"); + String args = " -F"; if (trafficType == FirewallRule.TrafficType.Egress) { - command.add("-E"); + args += " -E"; if (egressDefault.equals("true")) { - command.add("-P ", "1"); + args += " -P 1"; } else if (egressDefault.equals("System")) { - command.add("-P ", "2"); + args += " -P 2"; } else { - command.add("-P ", "0"); + args += " -P 0"; } } @@ -258,47 +245,55 @@ public class VirtualRoutingResource implements Manager { for (int i = 0; i < fwRules.length; i++) { sb.append(fwRules[i]).append(','); } - command.add("-a", sb.toString()); + args += " -a " + sb.toString(); } - String result = command.execute(); - if (result != null) { + ExecutionResult result; + + if (trafficType == FirewallRule.TrafficType.Egress) { + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_egress.sh", args); + } else { + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_ingress.sh", args); + } + + if (!result.isSuccess()) { + //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails + for (int i = 0; i < results.length; i++) { + results[i] = "Failed: " + result.getDetails(); + } return new SetFirewallRulesAnswer(cmd, false, results); } - return new SetFirewallRulesAnswer(cmd, true, null); + return new SetFirewallRulesAnswer(cmd, true, results); } private Answer execute(SetPortForwardingRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; for (PortForwardingRuleTO rule : cmd.getRules()) { - String result = null; - final Script command = new Script(_firewallPath, _timeout, s_logger); + StringBuilder args = new StringBuilder(); + args.append(rule.revoked() ? " -D " : " -A "); + args.append(" -P ").append(rule.getProtocol().toLowerCase()); + args.append(" -l ").append(rule.getSrcIp()); + args.append(" -p ").append(rule.getStringSrcPortRange()); + args.append(" -r ").append(rule.getDstIp()); + args.append(" -d ").append(rule.getStringDstPortRange()); - command.add(routerIp); - command.add(rule.revoked() ? "-D" : "-A"); - command.add("-P ", rule.getProtocol().toLowerCase()); - command.add("-l ", rule.getSrcIp()); - command.add("-p ", rule.getStringSrcPortRange()); - command.add("-r ", rule.getDstIp()); - command.add("-d ", rule.getStringDstPortRange()); - result = command.execute(); - if (result == null) { - results[i++] = null; - } else { + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); + + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - protected Answer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -308,9 +303,9 @@ public class VirtualRoutingResource implements Manager { args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - String result = routerProxy("vpc_staticnat.sh", routerIp, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_staticnat.sh", args); - if (result == null) { + if (!result.isSuccess()) { results[i++] = null; } else { results[i++] = "Failed"; @@ -321,44 +316,41 @@ public class VirtualRoutingResource implements Manager { } - private Answer execute(SetStaticNatRulesCommand cmd) { + private SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { if (cmd.getVpcId() != null) { return SetVPCStaticNatRules(cmd); } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; for (StaticNatRuleTO rule : cmd.getRules()) { - String result = null; - final Script command = new Script(_firewallPath, _timeout, s_logger); - command.add(routerIp); - command.add(rule.revoked() ? "-D" : "-A"); - //1:1 NAT needs instanceip;publicip;domrip;op - command.add(" -l ", rule.getSrcIp()); - command.add(" -r ", rule.getDstIp()); + StringBuilder args = new StringBuilder(); + args.append(rule.revoked() ? " -D " : " -A "); + args.append(" -l ").append(rule.getSrcIp()); + args.append(" -r ").append(rule.getDstIp()); if (rule.getProtocol() != null) { - command.add(" -P ", rule.getProtocol().toLowerCase()); + args.append(" -P ").append(rule.getProtocol().toLowerCase()); } - command.add(" -d ", rule.getStringSrcPortRange()); - command.add(" -G "); + args.append(" -d ").append(rule.getStringSrcPortRange()); + args.append(" -G "); - result = command.execute(); - if (result == null) { - results[i++] = null; - } else { + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); + + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } return new SetStaticNatRulesAnswer(cmd, results, endResult); } - protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) { + private Answer execute(LoadBalancerConfigCommand cmd) { String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); if (routerIp == null) { @@ -372,96 +364,61 @@ public class VirtualRoutingResource implements Manager { tmpCfgFileContents += config[i]; tmpCfgFileContents += "\n"; } - File permKey = new File("/root/.ssh/id_rsa.cloud"); - try { - SshHelper.scpTo(routerIp, 3922, "root", permKey, null, "/etc/haproxy/", tmpCfgFileContents.getBytes(), "haproxy.cfg.new", null); + String tmpCfgFilePath = "/etc/haproxy/"; + String tmpCfgFileName = "haproxy.cfg.new"; + ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), tmpCfgFilePath, tmpCfgFileName, tmpCfgFileContents); - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String ip = cmd.getNic().getIp(); - String args = " -i " + ip; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - String result = routerProxy("vpc_loadbalancer.sh", routerIp, args); - - if (result != null) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - return new Answer(cmd); - - } catch (Exception e) { - return new Answer(cmd, e); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Fail to copy LB config file to VR"); } + + String[][] rules = cfgtr.generateFwRules(cmd); + + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; + + String args = ""; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); + } + args += " -a " + sb.toString(); + } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + if (cmd.getVpcId() == null) { + args = " -i " + routerIp + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "loadbalancer.sh", args); + } else { + args = " -i " + cmd.getNic().getIp() + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_loadbalancer.sh", args); + } + + return new Answer(cmd, result.isSuccess(), result.getDetails()); } - private Answer execute(LoadBalancerConfigCommand cmd) { - if (cmd.getVpcId() != null) { - return VPCLoadBalancerConfig(cmd); - } - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - File tmpCfgFile = null; - try { - String cfgFilePath = ""; - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - String[][] rules = cfgtr.generateFwRules(cmd); - if (routerIp != null) { - tmpCfgFile = File.createTempFile(routerIp.replace('.', '_'), "cfg"); - final PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(tmpCfgFile))); - for (int i = 0; i < config.length; i++) { - out.println(config[i]); - } - out.close(); - cfgFilePath = tmpCfgFile.getAbsolutePath(); - } - - final String result = - setLoadBalancerConfig(cfgFilePath, rules[LoadBalancerConfigurator.ADD], rules[LoadBalancerConfigurator.REMOVE], rules[LoadBalancerConfigurator.STATS], - routerIp); - - return new Answer(cmd, result == null, result); - } catch (final IOException e) { - return new Answer(cmd, false, e.getMessage()); - } finally { - if (tmpCfgFile != null) { - tmpCfgFile.delete(); - } - } - } protected Answer execute(VmDataCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); Map> data = new HashMap>(); data.put(cmd.getVmIpAddress(), cmd.getVmData()); @@ -472,186 +429,88 @@ public class VirtualRoutingResource implements Manager { String args = "-d " + json; - final String result = routerProxy("vmdata.py", routerIp, args); - if (result != null) { - return new Answer(cmd, false, "VmDataCommand failed, check agent logs"); - } - return new Answer(cmd); - } - - protected Answer execute(final IpAssocCommand cmd) { - IpAddressTO[] ips = cmd.getIpAddresses(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; - String result = null; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - for (IpAddressTO ip : ips) { - result = - assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress(), 2, false); - if (result != null) { - results[i++] = IpAssocAnswer.errorResult; - } else { - results[i++] = ip.getPublicIp() + " - success"; - ; - } - } - return new IpAssocAnswer(cmd, results); - } - - private String setLoadBalancerConfig(final String cfgFile, final String[] addRules, final String[] removeRules, final String[] statsRules, String routerIp) { - - if (routerIp == null) { - routerIp = "none"; - } - - final Script command = new Script(_loadbPath, _timeout, s_logger); - - command.add("-i", routerIp); - command.add("-f", cfgFile); - - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - command.add("-a", sb.toString()); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - command.add("-d", sb.toString()); - } - - sb = new StringBuilder(); - if (statsRules.length > 0) { - for (int i = 0; i < statsRules.length; i++) { - sb.append(statsRules[i]).append(','); - } - command.add("-s", sb.toString()); - } - - return command.execute(); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vmdata.py", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final SavePasswordCommand cmd) { final String password = cmd.getPassword(); final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String vmName = cmd.getVmName(); final String vmIpAddress = cmd.getVmIpAddress(); - final String local = vmName; String args = "-v " + vmIpAddress; args += " -p " + password; - String result = routerProxy("savepassword.sh", routerPrivateIPAddress, args); - if (result != null) { - return new Answer(cmd, false, "Unable to save password to DomR."); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "savepassword.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DhcpEntryCommand cmd) { - final Script command = new Script(_dhcpEntryPath, _timeout, s_logger); - command.add("-r", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + String args = " -m " + cmd.getVmMac(); if (cmd.getVmIpAddress() != null) { - command.add("-v", cmd.getVmIpAddress()); + args += " -4 " + cmd.getVmIpAddress(); } - command.add("-m", cmd.getVmMac()); - command.add("-n", cmd.getVmName()); + args += " -h " + cmd.getVmName(); if (cmd.getDefaultRouter() != null) { - command.add("-d", cmd.getDefaultRouter()); - } - if (cmd.getStaticRoutes() != null) { - command.add("-s", cmd.getStaticRoutes()); + args += " -d " + cmd.getDefaultRouter(); } if (cmd.getDefaultDns() != null) { - command.add("-N", cmd.getDefaultDns()); + args += " -n " + cmd.getDefaultDns(); + } + + if (cmd.getStaticRoutes() != null) { + args += " -s " + cmd.getStaticRoutes(); } if (cmd.getVmIp6Address() != null) { - command.add("-6", cmd.getVmIp6Address()); - command.add("-u", cmd.getDuid()); + args += " -6 " + cmd.getVmIp6Address(); + args += " -u " + cmd.getDuid(); } if (!cmd.isDefault()) { - command.add("-z"); + args += " -N"; } - final String result = command.execute(); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final CreateIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final Script command = new Script(_createIpAliasPath, _timeout, s_logger); List ipAliasTOs = cmd.getIpAliasList(); String args = ""; - command.add(routerIp); for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - command.add(args); - final String result = command.execute(); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "createipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DeleteIpAliasCommand cmd) { - final Script command = new Script(_deleteIpAliasPath, _timeout, s_logger); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String args = ""; - command.add(routerIp); List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } + //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. args = args + "- "; List activeIpAliasTOs = cmd.getCreateIpAliasTos(); for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - command.add(args); - final String result = command.execute(); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "deleteipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DnsMasqConfigCommand cmd) { - final Script command = new Script(_callDnsMasqPath, _timeout, s_logger); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List dhcpTos = cmd.getIps(); String args = ""; for (DhcpTO dhcpTo : dhcpTos) { args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - command.add(routerIp); - command.add(args); - final String result = command.execute(); - return new Answer(cmd, result == null, result); - } - - public String getRouterStatus(String routerIP) { - return routerProxyWithParser("checkrouter.sh", routerIP, null); - } - - public String routerProxyWithParser(String script, String routerIP, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - String result = command.execute(parser); - if (result == null) { - return parser.getLine(); - } - return null; + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "dnsmasq.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { @@ -659,78 +518,46 @@ public class VirtualRoutingResource implements Manager { String args = ""; for (String ip : cmd.getVpnIps()) { - args += " " + ip; + args += ip + " "; } - final String result = routerProxy("checkbatchs2svpn.sh", routerIP, args); - if (result == null || result.isEmpty()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); - } - - public String routerProxy(String script, String routerIP, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - return command.execute(); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "checkbatchs2svpn.sh", args); + return new CheckS2SVpnConnectionsAnswer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(CheckRouterCommand cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getRouterStatus(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "checkrouter.sh", null); + if (!result.isSuccess()) { + return new CheckRouterAnswer(cmd, result.getDetails()); } - return new CheckRouterAnswer(cmd, result, true); + return new CheckRouterAnswer(cmd, result.getDetails(), true); } protected Answer execute(BumpUpPriorityCommand cmd) { - final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final Script command = new Script(_bumpUpPriorityPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(routerPrivateIPAddress); - String result = command.execute(parser); - if (result != null) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed: " + result); - } - return new Answer(cmd, true, null); - } - - protected String getDomRVersion(String routerIP) { - return routerProxyWithParser("get_template_version.sh", routerIP, null); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "bumpup_priority.sh", null); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(GetDomRVersionCmd cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getDomRVersion(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "get_template_version.sh", null); + if (!result.isSuccess()) { return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed"); } - String[] lines = result.split("&"); + String[] lines = result.getDetails().split("&"); if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); - } - - protected Answer execute(final CheckConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); - } - - protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); + return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } protected Answer execute(Site2SiteVpnCfgCommand cmd) { - String args; + String args = ""; if (cmd.isCreate()) { - args = "-A"; + args += "-A"; args += " -l "; args += cmd.getLocalPublicIp(); args += " -n "; @@ -761,7 +588,7 @@ public class VirtualRoutingResource implements Manager { args += " -p "; } } else { - args = "-D"; + args += "-D"; args += " -r "; args += cmd.getPeerGatewayIp(); args += " -n "; @@ -769,59 +596,45 @@ public class VirtualRoutingResource implements Manager { args += " -N "; args += cmd.getPeerGuestCidrList(); } - String result = routerProxy("ipsectunnel.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result != null) { - return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure site to site VPN failed due to " + result.getDetails()); } return new Answer(cmd); } - private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { - String result = null; - - final StringBuffer sb = new StringBuffer(); - sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); - - boolean success = true; - try { - final URL url = new URL(sb.toString()); - final URLConnection conn = url.openConnection(); - - final InputStream is = conn.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - final StringBuilder sb2 = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb2.append(line + "\n"); - } - result = sb2.toString(); - } catch (final IOException e) { - success = false; - } finally { - try { - is.close(); - } catch (final IOException e) { - s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); - success = false; - } - } - } catch (final IOException e) { - s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); - success = false; - } - - return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); - } - - public String configureMonitor(final String routerIP, final String config) { + protected Answer execute(SetMonitorServiceCommand cmd) { + String config = cmd.getConfiguration(); String args = " -c " + config; - return routerProxy("monitor_service.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "monitor_service.sh", args); + + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); + } + return new Answer(cmd); } - public String assignGuestNetwork(final String dev, final String routerIP, final String routerGIP, final String gateway, final String cidr, final String netmask, - final String dns, final String domainName) { + protected SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + NicTO nic = cmd.getNic(); + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2 = cmd.getDefaultDns2(); + if (dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + String dev = "eth" + nic.getDeviceId(); + String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); String args = " -C"; args += " -d " + dev; @@ -835,33 +648,74 @@ public class VirtualRoutingResource implements Manager { if (domainName != null && !domainName.isEmpty()) { args += " -e " + domainName; } - return routerProxy("vpc_guestnw.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_guestnw.sh", args); + + if (!result.isSuccess()) { + return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result.getDetails()); + } + return new SetupGuestNetworkAnswer(cmd, true, "success"); } - public String assignNetworkACL(final String routerIP, final String dev, final String routerGIP, final String netmask, final String rule, String privateGw) { - String args = " -d " + dev; - if (privateGw != null) { - args += " -a " + rule; - return routerProxy("vpc_privategw_acl.sh", routerIP, args); - } else { - args += " -i " + routerGIP; - args += " -m " + netmask; - args += " -a " + rule; - return routerProxy("vpc_acl.sh", routerIP, args); + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + String[] results = new String[cmd.getRules().length]; + + String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + + try { + String[][] rules = cmd.generateFwRules(); + String[] aclRules = rules[0]; + NicTO nic = cmd.getNic(); + String dev = "eth" + nic.getDeviceId(); + String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + String rule = sb.toString(); + ExecutionResult result; + + String args = " -d " + dev; + if (privateGw != null) { + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_privategw_acl.sh", args); + } else { + args += " -i " + nic.getIp(); + args += " -m " + netmask; + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_acl.sh", args); + } + + if (!result.isSuccess()) { + for (int i = 0; i < results.length; i++) { + results[i] = "Failed"; + } + return new SetNetworkACLAnswer(cmd, false, results); + } + + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); } } - public String assignSourceNat(final String routerIP, final String pubIP, final String dev) { + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + IpAddressTO pubIP = cmd.getIpAddress(); + String dev = "eth" + pubIP.getNicDevId(); String args = " -A "; args += " -l "; - args += pubIP; + args += pubIP.getPublicIp(); args += " -c "; args += dev; - return routerProxy("vpc_snat.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_snat.sh", args); + return new SetSourceNatAnswer(cmd, result.isSuccess(), result.getDetails()); } private SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; @@ -874,9 +728,9 @@ public class VirtualRoutingResource implements Manager { args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - String result = routerProxy("vpc_portforwarding.sh", routerIp, args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_portforwarding.sh", args); - if (result != null) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -886,44 +740,56 @@ public class VirtualRoutingResource implements Manager { return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP, final String nicname, final String gateway, final String netmask, - final String subnet, boolean sourceNat) throws InternalErrorException { + public IpAssocAnswer execute(IpAssocVpcCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String[] results = new String[cmd.getIpAddresses().length]; String args = ""; String snatArgs = ""; - - if (add) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; + for (int i = 0; i < cmd.getIpAddresses().length; i ++) { + results[i] = "Failed"; } - args += " -l "; - args += pubIP; - args += " -c "; - args += nicname; - args += " -g "; - args += gateway; - args += " -m "; - args += netmask; - args += " -n "; - args += subnet; - - String result = routerProxy("vpc_ipassoc.sh", routerIP, args); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:" + result); - } - if (sourceNat) { - snatArgs += " -l " + pubIP; - snatArgs += " -c " + nicname; - - result = routerProxy("vpc_privateGateway.sh", routerIP, snatArgs); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:" + result); + int i = 0; + for (IpAddressTO ip : cmd.getIpAddresses()) { + if (ip.isAdd()) { + args += " -A "; + snatArgs += " -A "; + } else { + args += " -D "; + snatArgs += " -D "; } + args += " -l "; + args += ip.getPublicIp(); + String nicName = "eth" + ip.getNicDevId(); + args += " -c "; + args += nicName; + args += " -g "; + args += ip.getVlanGateway(); + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_ipassoc.sh", args); + if (!result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - vpc_ipassoc failed:" + result.getDetails(); + break; + } + + if (ip.isSourceNat()) { + snatArgs += " -l " + ip.getPublicIp(); + snatArgs += " -c " + nicName; + + result = _vrDeployer.executeInVR(routerIP, "vpc_privateGateway.sh", snatArgs); + if (result != null) { + results[i++] = ip.getPublicIp() + " - vpc_privateGateway failed:" + result.getDetails(); + break; + } + } + results[i++] = ip.getPublicIp() + " - success "; } + return new IpAssocAnswer(cmd, results); } private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { @@ -939,9 +805,9 @@ public class VirtualRoutingResource implements Manager { } String args = " -a " + sb.toString(); - String result = routerProxy("vpc_staticroute.sh", routerIP, args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_staticroute.sh", args); - if (result != null) { + if (!result.isSuccess()) { for (int i = 0; i < results.length; i++) { results[i] = "Failed"; } @@ -956,147 +822,56 @@ public class VirtualRoutingResource implements Manager { } } - public String assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String broadcastUri, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, int nicNum, boolean newNic) { - - String args = ""; - if (add) { - args += "-A"; - } else { - args += "-D"; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - String publicNic = "eth" + nicNum; - args += " -c "; - args += publicNic; - - args += " -g "; - args += vlanGateway; - - if (newNic) { - args += " -n"; + public Answer execute(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + for (int i = 0; i < results.length; i++) { + results[i] = IpAssocAnswer.errorResult; } - return routerProxy("ipassoc.sh", privateIpAddress, args); - } + int i = 0; + for (IpAddressTO ip: cmd.getIpAddresses()) { + String args = ""; + if (ip.isAdd()) { + args += "-A"; + } else { + args += "-D"; + } + String cidrSize = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + if (ip.isSourceNat()) { + args += " -s"; + } + if (ip.isFirstIP()) { + args += " -f"; + } + args += " -l "; + args += ip.getPublicIp() + "/" + cidrSize; - private void deleteBridge(String brName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ifconfig " + brName + " down;brctl delbr " + brName); - cmd.execute(); - } + String publicNic = "eth" + ip.getNicDevId(); + args += " -c "; + args += publicNic; - private boolean isDNSmasqRunning(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ls -l /var/run/libvirt/network/" + dnsmasqName + ".pid"); - String result = cmd.execute(); - if (result != null) { - return false; - } else { - return true; + args += " -g "; + args += ip.getVlanGateway(); + + if (ip.isNewNic()) { + args += " -n"; + } + + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "ipassoc.sh", args); + if (result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - success"; + } else { + results[i++] = ip.getPublicIp() + " - failed:" + result.getDetails(); + break; + } } + return new IpAssocAnswer(cmd, results); } - private void stopDnsmasq(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("kill -9 `cat /var/run/libvirt/network/" + dnsmasqName + ".pid`"); - cmd.execute(); - } - - // protected Answer execute(final SetFirewallRuleCommand cmd) { - // String args; - // if(cmd.getProtocol().toLowerCase().equals(NetUtils.NAT_PROTO)){ - // //1:1 NAT needs instanceip;publicip;domrip;op - // if(cmd.isCreate()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -G " + cmd.getProtocol(); - // }else{ - // if (cmd.isEnable()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -P " + cmd.getProtocol().toLowerCase(); - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -p " + cmd.getPublicPort(); - // args += " -n " + cmd.getRouterName(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -d " + cmd.getPrivatePort(); - // args += " -N " + cmd.getVlanNetmask(); - // - // String oldPrivateIP = cmd.getOldPrivateIP(); - // String oldPrivatePort = cmd.getOldPrivatePort(); - // - // if (oldPrivateIP != null) { - // args += " -w " + oldPrivateIP; - // } - // - // if (oldPrivatePort != null) { - // args += " -x " + oldPrivatePort; - // } - // } - // - // final Script command = new Script(_firewallPath, _timeout, s_logger); - // String [] argsArray = args.split(" "); - // for (String param : argsArray) { - // command.add(param); - // } - // String result = command.execute(); - // return new Answer(cmd, result == null, result); - // } - - protected String getDefaultScriptsDir() { - return "scripts/network/domr/dom0"; - } - - protected String findScript(final String script) { - return Script.findScript(_scriptsDir, script); - } - - @Override public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; - _scriptsDir = (String)params.get("domr.scripts.dir"); - if (_scriptsDir == null) { - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir can't be initialized from domr.scripts.dir param, use default"); - } - _scriptsDir = getDefaultScriptsDir(); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir to use: " + _scriptsDir); - } - - String value = (String)params.get("scripts.timeout"); - _timeout = NumbersUtil.parseInt(value, 120) * 1000; - - value = (String)params.get("start.script.timeout"); - _startTimeout = NumbersUtil.parseInt(value, 360) * 1000; - - value = (String)params.get("ssh.sleep"); + String value = (String)params.get("ssh.sleep"); _sleep = NumbersUtil.parseInt(value, 10) * 1000; value = (String)params.get("ssh.retry"); @@ -1105,60 +880,9 @@ public class VirtualRoutingResource implements Manager { value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); - _publicIpAddress = (String)params.get("public.ip.address"); - if (_publicIpAddress != null) { - s_logger.warn("Incoming public ip address is overriden. Will always be using the same ip address: " + _publicIpAddress); + if (_vrDeployer == null) { + throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!"); } - - _firewallPath = findScript("call_firewall.sh"); - if (_firewallPath == null) { - throw new ConfigurationException("Unable to find the call_firewall.sh"); - } - - _loadbPath = findScript("call_loadbalancer.sh"); - if (_loadbPath == null) { - throw new ConfigurationException("Unable to find the call_loadbalancer.sh"); - } - - _dhcpEntryPath = findScript("dhcp_entry.sh"); - if (_dhcpEntryPath == null) { - throw new ConfigurationException("Unable to find dhcp_entry.sh"); - } - - _publicEthIf = (String)params.get("public.network.device"); - if (_publicEthIf == null) { - _publicEthIf = "xenbr1"; - } - _publicEthIf = _publicEthIf.toLowerCase(); - - _privateEthIf = (String)params.get("private.network.device"); - if (_privateEthIf == null) { - _privateEthIf = "xenbr0"; - } - _privateEthIf = _privateEthIf.toLowerCase(); - - _bumpUpPriorityPath = findScript("bumpUpPriority.sh"); - if (_bumpUpPriorityPath == null) { - throw new ConfigurationException("Unable to find bumpUpPriority.sh"); - } - - _routerProxyPath = findScript("router_proxy.sh"); - if (_routerProxyPath == null) { - throw new ConfigurationException("Unable to find router_proxy.sh"); - } - _createIpAliasPath = findScript("createipAlias.sh"); - if (_createIpAliasPath == null) { - throw new ConfigurationException("unable to find createipAlias.sh"); - } - _deleteIpAliasPath = findScript("deleteipAlias.sh"); - if (_deleteIpAliasPath == null) { - throw new ConfigurationException("unable to find deleteipAlias.sh"); - } - _callDnsMasqPath = findScript("call_dnsmasq.sh"); - if (_callDnsMasqPath == null) { - throw new ConfigurationException("unable to find call_dnsmasq.sh"); - } - return true; } @@ -1237,50 +961,4 @@ public class VirtualRoutingResource implements Manager { return false; } - - @Override - public String getName() { - return _name; - } - - @Override - public void setName(String name) { - _name = name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public int getRunLevel() { - return ComponentLifecycle.RUN_LEVEL_COMPONENT; - } - - public void setRunLevel() { - } - - @Override - public void setConfigParams(Map params) { - // TODO Auto-generated method stub - - } - - @Override - public Map getConfigParams() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setRunLevel(int level) { - // TODO Auto-generated method stub - - } } diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/com/cloud/agent/transport/Request.java index f4ed5c4b6e6..b5890d90451 100755 --- a/core/src/com/cloud/agent/transport/Request.java +++ b/core/src/com/cloud/agent/transport/Request.java @@ -23,6 +23,7 @@ import java.io.StringReader; import java.lang.reflect.Type; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.zip.GZIPInputStream; @@ -49,6 +50,7 @@ import com.cloud.exception.UnsupportedVersionException; import com.cloud.serializer.GsonHelper; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -436,11 +438,35 @@ public class Request { } buf.append(", Ver: ").append(_ver.toString()); buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", "); - buf.append(content); + String cleanContent = content.toString(); + if(cleanContent.contains("password")) { + buf.append(cleanPassword(cleanContent)); + } else { + buf.append(content); + } buf.append(" }"); return buf.toString(); } + public static String cleanPassword(String logString) { + String cleanLogString = null; + if (logString != null) { + cleanLogString = logString; + String[] temp = logString.split(","); + int i = 0; + if (temp != null) { + while (i < temp.length) { + temp[i] = StringUtils.cleanString(temp[i]); + i++; + } + List stringList = new ArrayList(); + Collections.addAll(stringList, temp); + cleanLogString = StringUtils.join(stringList, ","); + } + } + return cleanLogString; + } + /** * Factory method for Request and Response. It expects the bytes to be * correctly formed so it's possible that it throws underflow exceptions diff --git a/debian/control b/debian/control index c756dcd0d8e..ab4644badd2 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: cloudstack Section: libs Priority: extra Maintainer: Wido den Hollander -Build-Depends: debhelper (>= 7), openjdk-6-jdk | openjdk-7-jdk, tomcat6, genisoimage, +Build-Depends: debhelper (>= 7), openjdk-7-jdk, tomcat6, genisoimage, python-mysqldb, maven3 | maven (>= 3), python (>= 2.6.6-3~) Standards-Version: 3.8.1 Homepage: http://www.cloudstack.org/ @@ -22,7 +22,7 @@ Description: CloudStack server library Package: cloudstack-agent Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in @@ -31,7 +31,7 @@ Description: CloudStack agent Package: cloudstack-usage Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc Description: CloudStack usage monitor The CloudStack usage monitor provides usage accounting across the entire cloud for cloud operators to charge based on usage parameters. diff --git a/deps/XenServerJava/pom.xml b/deps/XenServerJava/pom.xml index 5c885b49808..84d9a975c98 100644 --- a/deps/XenServerJava/pom.xml +++ b/deps/XenServerJava/pom.xml @@ -40,9 +40,9 @@ org.apache.maven.plugins maven-checkstyle-plugin - ${cs.checkstyle.version} + cloudstack-checkstyle none diff --git a/engine/components-api/src/com/cloud/vm/VmWorkConstants.java b/engine/components-api/src/com/cloud/vm/VmWorkConstants.java index 20e40b7f84b..4627cfe078b 100644 --- a/engine/components-api/src/com/cloud/vm/VmWorkConstants.java +++ b/engine/components-api/src/com/cloud/vm/VmWorkConstants.java @@ -20,4 +20,5 @@ public interface VmWorkConstants { public static final String VM_WORK_QUEUE = "VmWorkJobQueue"; public static final String VM_WORK_JOB_DISPATCHER = "VmWorkJobDispatcher"; public static final String VM_WORK_JOB_WAKEUP_DISPATCHER = "VmWorkJobWakeupDispatcher"; + public static final String VM_WORK_JOB_PLACEHOLDER = "VmWorkJobPlaceHolder"; } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 628528a33c4..b71252879fc 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -61,6 +61,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO; import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.MessageDispatcher; import org.apache.cloudstack.framework.messagebus.MessageHandler; import org.apache.cloudstack.jobs.JobInfo; import org.apache.cloudstack.managed.context.ManagedContextRunnable; @@ -491,7 +492,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); - if (volumeExpungeCommands != null && hostId != null) { + if (volumeExpungeCommands != null && volumeExpungeCommands.size() > 0 && hostId != null) { Commands cmds = new Commands(Command.OnError.Stop); for (Command volumeExpungeCommand : volumeExpungeCommands) { @@ -560,6 +561,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _executor.scheduleAtFixedRate(new TransitionTask(), 5000, VmJobStateReportInterval.value(), TimeUnit.SECONDS); _executor.scheduleAtFixedRate(new CleanupTask(), VmOpCleanupInterval.value(), VmOpCleanupInterval.value(), TimeUnit.SECONDS); cancelWorkItems(_nodeId); + + // cleanup left over place holder works + _workJobDao.expungeLeftoverWorkJobs(ManagementServerNode.getManagementServerId()); return true; } @@ -578,6 +582,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _agentMgr.registerForHostEvents(this, true, true, true); + if (VmJobEnabled.value()) { + _messageBus.subscribe(VirtualMachineManager.Topics.VM_POWER_STATE, MessageDispatcher.getDispatcher(this)); + } + return true; } @@ -746,7 +754,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateStart(vmUuid, params, planToDeploy, planner); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateStart(vmUuid, params, planToDeploy, planner); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = startVmThroughJobQueue(vmUuid, params, planToDeploy); @@ -1107,6 +1125,13 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VolumeVO volume = _volsDao.findById(volumeId); disk.setPath(volume.get_iScsiName()); + + if (disk.getData() instanceof VolumeObjectTO) { + VolumeObjectTO volTo = (VolumeObjectTO)disk.getData(); + + volTo.setPath(volume.get_iScsiName()); + } + volume.setPath(volume.get_iScsiName()); _volsDao.update(volumeId, volume); @@ -1117,20 +1142,22 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // for managed storage on XenServer and VMware, need to update the DB with a path if the VDI/VMDK file was newly created private void handlePath(DiskTO[] disks, Map iqnToPath) { - if (disks != null) { + if (disks != null && iqnToPath != null) { for (DiskTO disk : disks) { Map details = disk.getDetails(); boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED)); - if (isManaged && disk.getPath() == null) { + if (isManaged) { Long volumeId = disk.getData().getId(); VolumeVO volume = _volsDao.findById(volumeId); String iScsiName = volume.get_iScsiName(); String path = iqnToPath.get(iScsiName); - volume.setPath(path); + if (path != null) { + volume.setPath(path); - _volsDao.update(volumeId, volume); + _volsDao.update(volumeId, volume); + } } } } @@ -1268,7 +1295,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateStop(vmUuid, cleanUpEvenIfUnableToStop); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateStop(vmUuid, cleanUpEvenIfUnableToStop); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = stopVmThroughJobQueue(vmUuid, cleanUpEvenIfUnableToStop); @@ -1560,7 +1599,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateStorageMigration(vmUuid, destPool); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateStorageMigration(vmUuid, destPool); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = migrateVmStorageThroughJobQueue(vmUuid, destPool); @@ -1642,7 +1691,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateMigrate(vmUuid, srcHostId, dest); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateMigrate(vmUuid, srcHostId, dest); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = migrateVmThroughJobQueue(vmUuid, srcHostId, dest); @@ -1913,7 +1972,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateMigrateWithStorage(vmUuid, srcHostId, destHostId, volumeToPool); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = migrateVmWithStorageThroughJobQueue(vmUuid, srcHostId, destHostId, volumeToPool); @@ -2156,6 +2227,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.trace("VM Operation Thread Running"); try { _workDao.cleanup(VmOpCleanupWait.value()); + + // TODO. hard-coded to one hour after job has been completed + Date cutDate = new Date(new Date().getTime() - 3600000); + _workJobDao.expungeCompletedWorkJobs(cutDate); } catch (Exception e) { s_logger.error("VM Operations failed due to ", e); } @@ -2192,7 +2267,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateReboot(vmUuid, params); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateReboot(vmUuid, params); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = rebootVmThroughJobQueue(vmUuid, params); @@ -2743,7 +2828,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn(e.getMessage()); } } - } else if (serverState == State.Stopping) { + } else if (serverState == State.Stopped) { s_logger.debug("Scheduling a stop command for " + vm); _haMgr.scheduleStop(vm, hostId, WorkType.Stop); } else { @@ -3113,7 +3198,16 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateAddVmToNetwork(vm, network, requested); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + return orchestrateAddVmToNetwork(vm, network, requested); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = addVmToNetworkThroughJobQueue(vm, network, requested); @@ -3216,7 +3310,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateRemoveNicFromVm(vm, nic); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + return orchestrateRemoveNicFromVm(vm, nic); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = removeNicFromVmThroughJobQueue(vm, nic); @@ -3455,7 +3559,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - orchestrateMigrateForScale(vmUuid, srcHostId, dest, oldSvcOfferingId); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + orchestrateMigrateForScale(vmUuid, srcHostId, dest, oldSvcOfferingId); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = migrateVmForScaleThroughJobQueue(vmUuid, srcHostId, dest, oldSvcOfferingId); @@ -3704,7 +3818,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateReConfigureVm(vmUuid, oldServiceOffering, reconfiguringOnExistingHost); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + VirtualMachine vm = _vmDao.findByUuid(vmUuid); + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + return orchestrateReConfigureVm(vmUuid, oldServiceOffering, reconfiguringOnExistingHost); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = reconfigureVmThroughJobQueue(vmUuid, oldServiceOffering, reconfiguringOnExistingHost); @@ -3816,7 +3940,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // @MessageHandler(topic = Topics.VM_POWER_STATE) - private void HandlePownerStateReport(Object target, String subject, String senderAddress, Object args) { + private void HandlePowerStateReport(String subject, String senderAddress, Object args) { assert (args != null); Long vmId = (Long)args; @@ -3836,7 +3960,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac break; // PowerUnknown shouldn't be reported, it is a derived - // VM power state from host state (host un-reachable + // VM power state from host state (host un-reachable) case PowerUnknown: default: assert (false); @@ -3846,8 +3970,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.warn("VM " + vmId + " no longer exists when processing VM state report"); } } else { - // TODO, do job wake-up signalling, since currently async job wake-up is not in use - // we will skip it for nows + // reset VM power state tracking so that we won't lost signal when VM has + // been translated to + _vmDao.resetVmPowerStateTracking(vmId); } } @@ -3924,6 +4049,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac switch (vm.getState()) { case Starting: case Stopping: + case Running: case Stopped: case Migrating: try { @@ -3937,7 +4063,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac // TODO: we need to forcely release all resource allocation break; - case Running: case Destroyed: case Expunging: break; @@ -4179,7 +4304,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4192,7 +4317,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4232,7 +4357,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); workJob.setStep(VmWorkJobVO.Step.Prepare); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4243,7 +4368,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4285,7 +4410,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); workJob.setStep(VmWorkJobVO.Step.Prepare); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4296,7 +4421,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4335,7 +4460,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4345,7 +4470,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4389,7 +4514,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4400,7 +4525,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4441,7 +4566,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4453,7 +4578,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4493,7 +4618,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4505,7 +4630,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4543,7 +4668,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4554,7 +4679,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4592,7 +4717,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4603,7 +4728,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4641,7 +4766,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4652,7 +4777,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4692,7 +4817,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac workJob.setAccountId(account.getId()); workJob.setUserId(user.getId()); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -4703,7 +4828,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4793,7 +4918,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac NicProfile nic = orchestrateAddVmToNetwork(vm, network, work.getRequestedNicProfile()); - return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(nic.getId()))); + return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(nic.getId())); } private Pair orchestrateRemoveNicFromVm(VmWorkRemoveNicFromVm work) throws Exception { @@ -4848,4 +4973,23 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac public Pair handleVmWorkJob(VmWork work) throws Exception { return _jobHandlerProxy.handleVmWorkJob(work); } + + private VmWorkJobVO createPlaceHolderWork(long instanceId) { + VmWorkJobVO workJob = new VmWorkJobVO(""); + + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER); + workJob.setCmd(""); + workJob.setCmdInfo(""); + + workJob.setAccountId(0); + workJob.setUserId(0); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(instanceId); + workJob.setInitMsid(ManagementServerNode.getManagementServerId()); + + _workJobDao.persist(workJob); + + return workJob; + } } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java index f84c7b72a93..152d0d889c6 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java @@ -28,4 +28,6 @@ public interface VirtualMachinePowerStateSync { // to adapt legacy ping report void processHostVmStatePingReport(long hostId, Map report); + + Map convertVmStateReport(Map states); } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java index cd4c3c05965..453890c4279 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java @@ -32,12 +32,9 @@ import com.cloud.vm.dao.VMInstanceDao; public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStateSync { private static final Logger s_logger = Logger.getLogger(VirtualMachinePowerStateSyncImpl.class); - @Inject - MessageBus _messageBus; - @Inject - VMInstanceDao _instanceDao; - @Inject - VirtualMachineManager _vmMgr; + @Inject MessageBus _messageBus; + @Inject VMInstanceDao _instanceDao; + @Inject VirtualMachineManager _vmMgr; public VirtualMachinePowerStateSyncImpl() { } @@ -53,7 +50,7 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat if (s_logger.isDebugEnabled()) s_logger.debug("Process host VM state report from ping process. host: " + hostId); - Map translatedInfo = convertToInfos(report); + Map translatedInfo = convertVmStateReport(report); processReport(hostId, translatedInfo); } @@ -62,7 +59,7 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat if (s_logger.isDebugEnabled()) s_logger.debug("Process host VM state report from ping process. host: " + hostId); - Map translatedInfo = convertToInfos(report); + Map translatedInfo = convertVmStateReport(report); processReport(hostId, translatedInfo); } @@ -74,16 +71,19 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat s_logger.debug("VM state report. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue()); if (_instanceDao.updatePowerState(entry.getKey(), hostId, entry.getValue())) { - if (s_logger.isDebugEnabled()) s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue()); _messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, entry.getKey()); + } else { + if (s_logger.isDebugEnabled()) + s_logger.debug("VM power state does not change, skip DB writing. vm id: " + entry.getKey()); } } } - private Map convertToInfos(Map states) { + @Override + public Map convertVmStateReport(Map states) { final HashMap map = new HashMap(); if (states == null) { return map; @@ -93,7 +93,6 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat VMInstanceVO vm = findVM(entry.getKey()); if (vm != null) { map.put(vm.getId(), entry.getValue().getState()); - break; } else { s_logger.info("Unable to find matched VM in CloudStack DB. name: " + entry.getKey()); } diff --git a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java index 285c8a2831e..31b2d9ca2d2 100644 --- a/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java +++ b/engine/orchestration/src/com/cloud/vm/VmWorkJobDispatcher.java @@ -60,9 +60,6 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch String cmd = job.getCmd(); assert (cmd != null); - if (s_logger.isDebugEnabled()) - s_logger.debug("Run VM work job: " + cmd + ", job origin: " + job.getRelated()); - Class workClz = null; try { workClz = Class.forName(job.getCmd()); @@ -80,27 +77,33 @@ public class VmWorkJobDispatcher extends AdapterBase implements AsyncJobDispatch return; } - if (_handlers == null || _handlers.isEmpty()) { - s_logger.error("Invalid startup configuration, no work job handler is found. cmd: " + job.getCmd() + ", job info: " + job.getCmdInfo() - + ", job origin: " + job.getRelated()); - _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, "Invalid startup configuration. no job handler is found"); - return; + if (s_logger.isDebugEnabled()) + s_logger.debug("Run VM work job: " + cmd + " for VM " + work.getVmId() + ", job origin: " + job.getRelated()); + try { + if (_handlers == null || _handlers.isEmpty()) { + s_logger.error("Invalid startup configuration, no work job handler is found. cmd: " + job.getCmd() + ", job info: " + job.getCmdInfo() + + ", job origin: " + job.getRelated()); + _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, "Invalid startup configuration. no job handler is found"); + return; + } + + VmWorkJobHandler handler = _handlers.get(work.getHandlerName()); + + if (handler == null) { + s_logger.error("Unable to find work job handler. handler name: " + work.getHandlerName() + ", job cmd: " + job.getCmd() + + ", job info: " + job.getCmdInfo() + ", job origin: " + job.getRelated()); + _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, "Unable to find work job handler"); + return; + } + + CallContext.register(work.getUserId(), work.getAccountId(), job.getRelated()); + + Pair result = handler.handleVmWorkJob(work); + _asyncJobMgr.completeAsyncJob(job.getId(), result.first(), 0, result.second()); + } finally { + if (s_logger.isDebugEnabled()) + s_logger.debug("Done with run of VM work job: " + cmd + " for VM " + work.getVmId() + ", job origin: " + job.getRelated()); } - - VmWorkJobHandler handler = _handlers.get(work.getHandlerName()); - - if (handler == null) { - s_logger.error("Unable to find work job handler. handler name: " + work.getHandlerName() + ", job cmd: " + job.getCmd() - + ", job info: " + job.getCmdInfo() + ", job origin: " + job.getRelated()); - _asyncJobMgr.completeAsyncJob(job.getId(), JobInfo.Status.FAILED, 0, "Unable to find work job handler"); - return; - } - - CallContext.register(work.getUserId(), work.getAccountId(), job.getRelated()); - - Pair result = handler.handleVmWorkJob(work); - _asyncJobMgr.completeAsyncJob(job.getId(), result.first(), 0, result.second()); - } catch(Throwable e) { s_logger.error("Unable to complete " + job + ", job origin:" + job.getRelated(), e); diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 0d6d7185320..d51ed191b9d 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -323,6 +323,13 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) { break; } + + if (pool != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a suitable pool for create volume: " + pool.getId()); + } + break; + } } } @@ -408,6 +415,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati @DB public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering, List avoids, long size, HypervisorType hyperType) { + // update the volume's hypervisor_ss_reserve from its disk offering (used for managed storage) volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType); StoragePool pool = null; @@ -1089,6 +1097,14 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati // retry one more time in case of template reload is required for Vmware case AsyncCallFuture future = null; if (templateId == null) { + DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId()); + HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType(); + + // update the volume's hypervisor_ss_reserve from its disk offering (used for managed storage) + updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType); + + volume = volFactory.getVolume(newVol.getId(), destPool); + future = volService.createVolumeAsync(volume, destPool); } else { TemplateInfo templ = tmplFactory.getTemplate(templateId, DataStoreRole.Image); @@ -1106,6 +1122,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId()); } } + + StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId()); + + if (newVol.getVolumeType() == Type.DATADISK && storagePool.isManaged()) { + long hostId = vm.getVirtualMachine().getHostId(); + Host host = _hostDao.findById(hostId); + + volService.connectVolumeToHost(volFactory.getVolume(newVol.getId()), host, destPool); + } + newVol = _volsDao.findById(newVol.getId()); break; //break out of template-redeploy retry loop } catch (InterruptedException e) { diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 6dd1d4b491c..1a400e049e0 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -171,7 +171,6 @@ - diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index a933d03c071..82b6d8481a5 100755 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -27,11 +27,9 @@ import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import org.apache.log4j.Logger; @@ -83,7 +81,6 @@ public class Upgrade410to420 implements DbUpgrade { persistVswitchConfiguration(conn); createPlaceHolderNics(conn); updateRemoteAccessVpn(conn); - updateSystemVmTemplates(conn); updateOverCommitRatioClusterDetails(conn); updatePrimaryStore(conn); addEgressFwRulesForSRXGuestNw(conn); @@ -634,173 +631,6 @@ public class Upgrade410to420 implements DbUpgrade { } - private void updateSystemVmTemplates(Connection conn) { - // TODO: system vm template migration after storage refactoring - PreparedStatement pstmt = null; - ResultSet rs = null; - s_logger.debug("Updating System Vm template IDs"); - try { - //Get all hypervisors in use - Set hypervisorsListInUse = new HashSet(); - try { - pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); - rs = pstmt.executeQuery(); - while (rs.next()) { - switch (HypervisorType.getType(rs.getString(1))) { - case XenServer: - hypervisorsListInUse.add(HypervisorType.XenServer); - break; - case KVM: - hypervisorsListInUse.add(HypervisorType.KVM); - break; - case VMware: - hypervisorsListInUse.add(HypervisorType.VMware); - break; - case Hyperv: - hypervisorsListInUse.add(HypervisorType.Hyperv); - break; - case LXC: - hypervisorsListInUse.add(HypervisorType.LXC); - break; - } - } - } catch (SQLException e) { - throw new CloudRuntimeException("Error while listing hypervisors in use", e); - } - - Map NewTemplateNameList = new HashMap() { - { - put(HypervisorType.XenServer, "systemvm-xenserver-4.2"); - put(HypervisorType.VMware, "systemvm-vmware-4.2"); - put(HypervisorType.KVM, "systemvm-kvm-4.2"); - put(HypervisorType.LXC, "systemvm-lxc-4.2"); - put(HypervisorType.Hyperv, "systemvm-hyperv-4.2"); - } - }; - - Map routerTemplateConfigurationNames = new HashMap() { - { - put(HypervisorType.XenServer, "router.template.xen"); - put(HypervisorType.VMware, "router.template.vmware"); - put(HypervisorType.KVM, "router.template.kvm"); - put(HypervisorType.LXC, "router.template.lxc"); - put(HypervisorType.Hyperv, "router.template.hyperv"); - } - }; - - Map newTemplateUrl = new HashMap() { - { - put(HypervisorType.XenServer, "http://download.cloud.com/templates/4.2/systemvmtemplate-2013-07-12-master-xen.vhd.bz2"); - put(HypervisorType.VMware, "http://download.cloud.com/templates/4.2/systemvmtemplate-4.2-vh7.ova"); - put(HypervisorType.KVM, "http://download.cloud.com/templates/4.2/systemvmtemplate-2013-06-12-master-kvm.qcow2.bz2"); - put(HypervisorType.LXC, "http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2"); - put(HypervisorType.Hyperv, "http://download.cloud.com/templates/4.2/systemvmtemplate-2013-06-12-master-xen.vhd.bz2"); - } - }; - - Map newTemplateChecksum = new HashMap() { - { - put(HypervisorType.XenServer, "fb1b6e032a160d86f2c28feb5add6d83"); - put(HypervisorType.VMware, "8fde62b1089e5844a9cd3b9b953f9596"); - put(HypervisorType.KVM, "6cea42b2633841648040becb588bd8f0"); - put(HypervisorType.LXC, "2755de1f9ef2ce4d6f2bee2efbb4da92"); - put(HypervisorType.Hyperv, "fb1b6e032a160d86f2c28feb5add6d83"); - } - }; - - for (Map.Entry hypervisorAndTemplateName : NewTemplateNameList.entrySet()) { - s_logger.debug("Updating " + hypervisorAndTemplateName.getKey() + " System Vms"); - try { - //Get 4.2.0 system Vm template Id for corresponding hypervisor - pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = ? and removed is null order by id desc limit 1"); - pstmt.setString(1, hypervisorAndTemplateName.getValue()); - rs = pstmt.executeQuery(); - if (rs.next()) { - long templateId = rs.getLong(1); - rs.close(); - pstmt.close(); - // Mark the old system templates as removed - pstmt = - conn.prepareStatement("UPDATE `cloud`.`vm_template` SET removed = now() WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null"); - pstmt.setString(1, hypervisorAndTemplateName.getKey().toString()); - pstmt.executeUpdate(); - pstmt.close(); - // change template type to SYSTEM - pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); - pstmt.setLong(1, templateId); - pstmt.executeUpdate(); - pstmt.close(); - // update templete ID of system Vms - pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = ?"); - pstmt.setLong(1, templateId); - pstmt.setString(2, hypervisorAndTemplateName.getKey().toString()); - pstmt.executeUpdate(); - pstmt.close(); - // Change value of global configuration parameter router.template.* for the corresponding hypervisor - pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` SET value = ? WHERE name = ?"); - pstmt.setString(1, hypervisorAndTemplateName.getValue()); - pstmt.setString(2, routerTemplateConfigurationNames.get(hypervisorAndTemplateName.getKey())); - pstmt.executeUpdate(); - pstmt.close(); - } else { - if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())) { - throw new CloudRuntimeException("4.2.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); - } else { - s_logger.warn("4.2.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. " + hypervisorAndTemplateName.getKey() + - " hypervisor is not used, so not failing upgrade"); - // Update the latest template URLs for corresponding hypervisor - pstmt = - conn.prepareStatement("UPDATE `cloud`.`vm_template` SET url = ? , checksum = ? WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null order by id desc limit 1"); - pstmt.setString(1, newTemplateUrl.get(hypervisorAndTemplateName.getKey())); - pstmt.setString(2, newTemplateChecksum.get(hypervisorAndTemplateName.getKey())); - pstmt.setString(3, hypervisorAndTemplateName.getKey().toString()); - pstmt.executeUpdate(); - pstmt.close(); - } - } - } catch (SQLException e) { - throw new CloudRuntimeException("Error while updating " + hypervisorAndTemplateName.getKey() + " systemVm template", e); - } - } - try { - pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` set dynamically_scalable = 1 where name = ? and type = 'SYSTEM'"); - pstmt.setString(1, NewTemplateNameList.get(HypervisorType.VMware)); - pstmt.executeUpdate(); - pstmt.close(); - } catch (SQLException e) { - throw new CloudRuntimeException("Error while updating dynamically_scalable flag to 1 for SYSTEM template systemvm-vmware-4.2"); - } - s_logger.debug("Updating System Vm Template IDs Complete"); - } finally { - try { - if (rs != null) { - rs.close(); - } - - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } - } - /* - pstmt = null; - try { - pstmt = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); - pstmt.executeUpdate(); - } catch (SQLException e) { - throw new CloudRuntimeException("Failed to upgrade vm template data store uuid: " + e.toString()); - } finally { - if (pstmt != null) { - try { - pstmt.close(); - } catch (SQLException e) { - } - } - } - */ - } - //KVM snapshot flag: only turn on if Customers is using snapshot; private void setKVMSnapshotFlag(Connection conn) { s_logger.debug("Verify and set the KVM snapshot flag if snapshot was used. "); diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java index 268a27d2582..7e26132d9e0 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java @@ -24,10 +24,15 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import com.cloud.hypervisor.Hypervisor; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @@ -63,6 +68,51 @@ public class Upgrade421to430 implements DbUpgrade { @Override public void performDataMigration(Connection conn) { encryptLdapConfigParams(conn); + encryptImageStoreDetails(conn); + upgradeMemoryOfSsvmOffering(conn); + updateSystemVmTemplates(conn); + } + + private void upgradeMemoryOfSsvmOffering(Connection conn) { + PreparedStatement updatePstmt = null; + PreparedStatement selectPstmt = null; + ResultSet selectResultSet = null; + int newRamSize = 512; //512MB + long serviceOfferingId = 0; + + /** + * Pick first row in service_offering table which has system vm type as secondary storage vm. User added offerings would start from 2nd row onwards. + * We should not update/modify any user-defined offering. + */ + + try { + selectPstmt = conn.prepareStatement("SELECT id FROM `cloud`.`service_offering` WHERE vm_type='secondarystoragevm'"); + updatePstmt = conn.prepareStatement("UPDATE `cloud`.`service_offering` SET ram_size=? WHERE id=?"); + selectResultSet = selectPstmt.executeQuery(); + if(selectResultSet.next()) { + serviceOfferingId = selectResultSet.getLong("id"); + } + + updatePstmt.setInt(1, newRamSize); + updatePstmt.setLong(2, serviceOfferingId); + updatePstmt.executeUpdate(); + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to upgrade ram_size of service offering for secondary storage vm. ", e); + } finally { + try { + if (selectPstmt != null) { + selectPstmt.close(); + } + if (selectResultSet != null) { + selectResultSet.close(); + } + if (updatePstmt != null) { + updatePstmt.close(); + } + } catch (SQLException e) { + } + } + s_logger.debug("Done upgrading RAM for service offering of Secondary Storage VM to " + newRamSize); } private void encryptLdapConfigParams(Connection conn) { @@ -140,6 +190,174 @@ public class Upgrade421to430 implements DbUpgrade { } + private void updateSystemVmTemplates(Connection conn) { + PreparedStatement pstmt = null; + ResultSet rs = null; + s_logger.debug("Updating System Vm template IDs"); + try{ + //Get all hypervisors in use + Set hypervisorsListInUse = new HashSet(); + try { + pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); + rs = pstmt.executeQuery(); + while(rs.next()){ + switch (Hypervisor.HypervisorType.getType(rs.getString(1))) { + case XenServer: hypervisorsListInUse.add(Hypervisor.HypervisorType.XenServer); + break; + case KVM: hypervisorsListInUse.add(Hypervisor.HypervisorType.KVM); + break; + case VMware: hypervisorsListInUse.add(Hypervisor.HypervisorType.VMware); + break; + case Hyperv: hypervisorsListInUse.add(Hypervisor.HypervisorType.Hyperv); + break; + case LXC: hypervisorsListInUse.add(Hypervisor.HypervisorType.LXC); + break; + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while listing hypervisors in use", e); + } + + Map NewTemplateNameList = new HashMap(){ + { put(Hypervisor.HypervisorType.XenServer, "systemvm-xenserver-4.3"); + put(Hypervisor.HypervisorType.VMware, "systemvm-vmware-4.3"); + put(Hypervisor.HypervisorType.KVM, "systemvm-kvm-4.3"); + put(Hypervisor.HypervisorType.LXC, "systemvm-lxc-4.3"); + put(Hypervisor.HypervisorType.Hyperv, "systemvm-hyperv-4.3"); + } + }; + + Map routerTemplateConfigurationNames = new HashMap(){ + { put(Hypervisor.HypervisorType.XenServer, "router.template.xen"); + put(Hypervisor.HypervisorType.VMware, "router.template.vmware"); + put(Hypervisor.HypervisorType.KVM, "router.template.kvm"); + put(Hypervisor.HypervisorType.LXC, "router.template.lxc"); + put(Hypervisor.HypervisorType.Hyperv, "router.template.hyperv"); + } + }; + + Map newTemplateUrl = new HashMap(){ + { put(Hypervisor.HypervisorType.XenServer, "http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-xen.vhd.bz2"); + put(Hypervisor.HypervisorType.VMware, "http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-vmware.ova"); + put(Hypervisor.HypervisorType.KVM, "http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-kvm.qcow2.bz2"); + put(Hypervisor.HypervisorType.LXC, "http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-kvm.qcow2.bz2"); + put(Hypervisor.HypervisorType.Hyperv, "http://download.cloud.com/templates/4.3/systemvm64template-2013-12-23-hyperv.vhd.bz2"); + } + }; + + Map newTemplateChecksum = new HashMap(){ + { put(Hypervisor.HypervisorType.XenServer, "74b92f031cc5c2089ee89efb81344dcf"); + put(Hypervisor.HypervisorType.VMware, "ef593a061f3b7594ab0bfd9b0ed0a0d4"); + put(Hypervisor.HypervisorType.KVM, "85a1bed07bf43cbf022451cb2ecae4ff"); + put(Hypervisor.HypervisorType.LXC, "85a1bed07bf43cbf022451cb2ecae4ff"); + put(Hypervisor.HypervisorType.Hyperv, "5df45ee6ebe1b703a8805f4e1f4d0818"); + } + }; + + for (Map.Entry hypervisorAndTemplateName : NewTemplateNameList.entrySet()){ + s_logger.debug("Updating " + hypervisorAndTemplateName.getKey() + " System Vms"); + try { + //Get 4.3.0 system Vm template Id for corresponding hypervisor + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = ? and removed is null order by id desc limit 1"); + pstmt.setString(1, hypervisorAndTemplateName.getValue()); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); +// // Mark the old system templates as removed +// pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` SET removed = now() WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null"); +// pstmt.setString(1, hypervisorAndTemplateName.getKey().toString()); +// pstmt.executeUpdate(); +// pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = ?"); + pstmt.setLong(1, templateId); + pstmt.setString(2, hypervisorAndTemplateName.getKey().toString()); + pstmt.executeUpdate(); + pstmt.close(); + // Change value of global configuration parameter router.template.* for the corresponding hypervisor + pstmt = conn.prepareStatement("UPDATE `cloud`.`configuration` SET value = ? WHERE name = ?"); + pstmt.setString(1, hypervisorAndTemplateName.getValue()); + pstmt.setString(2, routerTemplateConfigurationNames.get(hypervisorAndTemplateName.getKey())); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())){ + throw new CloudRuntimeException("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.3.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. " + hypervisorAndTemplateName.getKey() + " hypervisor is not used, so not failing upgrade"); + // Update the latest template URLs for corresponding hypervisor + pstmt = conn.prepareStatement("UPDATE `cloud`.`vm_template` SET url = ? , checksum = ? WHERE hypervisor_type = ? AND type = 'SYSTEM' AND removed is null order by id desc limit 1"); + pstmt.setString(1, newTemplateUrl.get(hypervisorAndTemplateName.getKey())); + pstmt.setString(2, newTemplateChecksum.get(hypervisorAndTemplateName.getKey())); + pstmt.setString(3, hypervisorAndTemplateName.getKey().toString()); + pstmt.executeUpdate(); + pstmt.close(); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating "+ hypervisorAndTemplateName.getKey() +" systemVm template", e); + } + } + s_logger.debug("Updating System Vm Template IDs Complete"); + } finally { + try { + if (rs != null) { + rs.close(); + } + + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + } + + private void encryptImageStoreDetails(Connection conn) { + s_logger.debug("Encrypting image store details"); + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + pstmt = conn.prepareStatement("select id, value from `cloud`.`image_store_details` where name = 'key' or name = 'secretkey'"); + rs = pstmt.executeQuery(); + while (rs.next()) { + long id = rs.getLong(1); + String value = rs.getString(2); + if (value == null) { + continue; + } + String encryptedValue = DBEncryptionUtil.encrypt(value); + pstmt = conn.prepareStatement("update `cloud`.`image_store_details` set value=? where id=?"); + pstmt.setBytes(1, encryptedValue.getBytes("UTF-8")); + pstmt.setLong(2, id); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable encrypt image_store_details values ", e); + } catch (UnsupportedEncodingException e) { + throw new CloudRuntimeException("Unable encrypt image_store_details values ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + s_logger.debug("Done encrypting image_store_details"); + } + @Override public File[] getCleanupScripts() { String script = Script.findScript("", "db/schema-421to430-cleanup.sql"); diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java index 8ee1db7d39d..3b967e79dc5 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java @@ -19,7 +19,11 @@ package com.cloud.upgrade.dao; import java.io.File; import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import com.cloud.network.Network; import org.apache.log4j.Logger; import com.cloud.utils.exception.CloudRuntimeException; @@ -55,8 +59,148 @@ public class Upgrade430to440 implements DbUpgrade { @Override public void performDataMigration(Connection conn) { + secondaryIpsAccountAndDomainIdsUpdate(conn); } + + + private void secondaryIpsAccountAndDomainIdsUpdate(Connection conn) { + PreparedStatement pstmt = null; + PreparedStatement pstmtVm = null; + PreparedStatement pstmtNw = null; + PreparedStatement pstmtUpdate = null; + + ResultSet rs1 = null; + ResultSet vmRs = null; + ResultSet networkRs = null; + + String secondIpsSql = "SELECT id, vmId, network_id, account_id, domain_id, ip4_address FROM `cloud`.`nic_secondary_ips`"; + + try { + pstmt = conn.prepareStatement(secondIpsSql); + rs1 = pstmt.executeQuery(); + + while(rs1.next()) { + long ipId = rs1.getLong(1); + long vmId = rs1.getLong(2); + long networkId = rs1.getLong(3); + long accountId = rs1.getLong(4); + long domainId = rs1.getLong(5); + String ipAddr = rs1.getString(6); + + pstmtVm = conn.prepareStatement("SELECT account_id, domain_id FROM `cloud`.`vm_instance` where id = ?"); + pstmtVm.setLong(1,vmId); + + vmRs = pstmtVm.executeQuery(); + + if (vmRs.next()) { + long vmAccountId = vmRs.getLong(1); + long vmDomainId = vmRs.getLong(2); + + if (vmAccountId != accountId && vmAccountId != domainId) { + // update the secondary ip accountid and domainid to vm accountid domainid + // check the network type. If network is shared accountid doaminid needs to be updated in + // in both nic_secondary_ips table and user_ip_address table + + pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`nic_secondary_ips` SET account_id = ?, domain_id= ? WHERE id = ?"); + pstmtUpdate.setLong(1, vmAccountId); + pstmtUpdate.setLong(2,vmDomainId); + pstmtUpdate.setLong(3,ipId); + pstmtUpdate.executeUpdate(); + pstmtUpdate.close(); + + pstmtNw = conn.prepareStatement("SELECT guest_type FROM `cloud`.`networks` where id = ?"); + pstmtNw.setLong(1,networkId); + + networkRs = pstmtNw.executeQuery(); + if (networkRs.next()) { + String guesttype = networkRs.getString(1); + + if (guesttype == Network.GuestType.Shared.toString()) { + pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`user_ip_address` SET account_id = ?, domain_id= ? WHERE public_ip_address = ?"); + pstmtUpdate.setLong(1,vmAccountId); + pstmtUpdate.setLong(2,vmDomainId); + pstmtUpdate.setString(3,ipAddr); + pstmtUpdate.executeUpdate(); + pstmtUpdate.close(); + + } + } + networkRs.close(); + networkRs = null; + pstmtNw.close(); + pstmtNw = null; + } + } //if + + pstmtVm.close(); + pstmtVm = null; + vmRs.close(); + vmRs = null; + } // while + + + } catch (SQLException e) { + throw new CloudRuntimeException("Exception while Moving private zone information to dedicated resources", e); + } finally { + + if (pstmt != null) { + try { + pstmt.close(); + + } catch (SQLException e) { + } + } + + + if (rs1 != null) { + try { + rs1.close(); + } catch (SQLException e) { + } + } + + + + if (pstmtVm != null) { + try { + pstmtVm.close(); + } catch (SQLException e) { + } + } + + if (vmRs != null) { + try { + vmRs.close(); + } catch (SQLException e) { + } + } + + + + if (pstmtNw != null) { + try { + pstmtNw.close(); + + } catch (SQLException e) { + } + } + + + if (networkRs != null) { + try { + networkRs.close(); + } catch (SQLException e) { + } + } + } + s_logger.debug("Done updating vm nic secondary ip account and domain ids"); + } + + + + + @Override public File[] getCleanupScripts() { String script = Script.findScript("", "db/schema-430to440-cleanup.sql"); diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java index 9fbfa279089..39b8470b8c2 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java @@ -51,4 +51,6 @@ public interface NicSecondaryIpDao extends GenericDao { NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp); List getSecondaryIpAddressesForNic(long nicId); + + Long countByNicId(long nicId); } diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java index 2f3cc290b40..29af0198b47 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java @@ -35,6 +35,7 @@ import com.cloud.utils.db.SearchCriteria.Op; public class NicSecondaryIpDaoImpl extends GenericDaoBase implements NicSecondaryIpDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; + protected GenericSearchBuilder CountByNicId; protected NicSecondaryIpDaoImpl() { super(); @@ -50,6 +51,11 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase sc = CountByNicId.create(); + sc.setParameters("nic", nicId); + return customSearch(sc, null).get(0); + } } diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java index e6ea4a57e1c..453d222cdf2 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java @@ -69,6 +69,8 @@ public interface VMInstanceDao extends GenericDao, StateDao< List findVMInTransition(Date time, State... states); + List listByHostAndState(long hostId, State... states); + List listByTypes(VirtualMachine.Type... types); VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types); diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 605ece33314..2f25f577f47 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -48,7 +48,11 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; +import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicVO; @@ -76,6 +80,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected SearchBuilder TypesSearch; protected SearchBuilder IdTypesSearch; protected SearchBuilder HostIdTypesSearch; + protected SearchBuilder HostIdStatesSearch; protected SearchBuilder HostIdUpTypesSearch; protected SearchBuilder HostUpSearch; protected SearchBuilder InstanceNameSearch; @@ -182,6 +187,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem HostIdTypesSearch.and("types", HostIdTypesSearch.entity().getType(), Op.IN); HostIdTypesSearch.done(); + HostIdStatesSearch = createSearchBuilder(); + HostIdStatesSearch.and("hostId", HostIdStatesSearch.entity().getHostId(), Op.EQ); + HostIdStatesSearch.and("states", HostIdStatesSearch.entity().getState(), Op.IN); + HostIdStatesSearch.done(); + HostIdUpTypesSearch = createSearchBuilder(); HostIdUpTypesSearch.and("hostid", HostIdUpTypesSearch.entity().getHostId(), Op.EQ); HostIdUpTypesSearch.and("types", HostIdUpTypesSearch.entity().getType(), Op.IN); @@ -334,6 +344,15 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } + @Override + public List listByHostAndState(long hostId, State... states) { + SearchCriteria sc = HostIdStatesSearch.create(); + sc.setParameters("hostId", hostId); + sc.setParameters("states", (Object[])states); + + return listBy(sc); + } + @Override public List listUpByHostIdTypes(long hostid, Type... types) { SearchCriteria sc = HostIdUpTypesSearch.create(); @@ -702,60 +721,66 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem } @Override - public boolean updatePowerState(long instanceId, long powerHostId, VirtualMachine.PowerState powerState) { - boolean needToUpdate = false; - TransactionLegacy txn = TransactionLegacy.currentTxn(); - txn.start(); + public boolean updatePowerState(final long instanceId, final long powerHostId, final VirtualMachine.PowerState powerState) { + return Transaction.execute(new TransactionCallback() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + boolean needToUpdate = false; + VMInstanceVO instance = findById(instanceId); + if (instance != null) { + Long savedPowerHostId = instance.getPowerHostId(); + if (instance.getPowerState() != powerState || savedPowerHostId == null + || savedPowerHostId.longValue() != powerHostId) { + instance.setPowerState(powerState); + instance.setPowerHostId(powerHostId); + instance.setPowerStateUpdateCount(1); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); + needToUpdate = true; + update(instanceId, instance); + } else { + // to reduce DB updates, consecutive same state update for more than 3 times + if (instance.getPowerStateUpdateCount() < MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT) { + instance.setPowerStateUpdateCount(instance.getPowerStateUpdateCount() + 1); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); + needToUpdate = true; + update(instanceId, instance); + } + } + } + return needToUpdate; + } + }); + } - VMInstanceVO instance = findById(instanceId); - if (instance != null) { - Long savedPowerHostId = instance.getPowerHostId(); - if (instance.getPowerState() != powerState || savedPowerHostId == null || savedPowerHostId.longValue() != powerHostId) { - instance.setPowerState(powerState); - instance.setPowerHostId(powerHostId); - instance.setPowerStateUpdateCount(1); - instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); - needToUpdate = true; - update(instanceId, instance); - } else { - // to reduce DB updates, consecutive same state update for more than 3 times - if (instance.getPowerStateUpdateCount() < MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT) { - instance.setPowerStateUpdateCount(instance.getPowerStateUpdateCount() + 1); + @Override + public void resetVmPowerStateTracking(final long instanceId) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + VMInstanceVO instance = findById(instanceId); + if (instance != null) { + instance.setPowerStateUpdateCount(0); instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); - needToUpdate = true; update(instanceId, instance); } } - } - - txn.commit(); - return needToUpdate; + }); } - @Override - public void resetVmPowerStateTracking(long instanceId) { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - txn.start(); - VMInstanceVO instance = findById(instanceId); - if (instance != null) { - instance.setPowerStateUpdateCount(0); - instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); - update(instanceId, instance); - } + @Override @DB + public void resetHostPowerStateTracking(final long hostId) { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("powerHostId", SearchCriteria.Op.EQ, hostId); - txn.commit(); - } + VMInstanceVO instance = createForUpdate(); + instance.setPowerStateUpdateCount(0); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); - @Override - @DB - public void resetHostPowerStateTracking(long hostId) { - SearchCriteria sc = createSearchCriteria(); - sc.addAnd("powerHostId", SearchCriteria.Op.EQ, hostId); - - VMInstanceVO instance = this.createForUpdate(); - instance.setPowerStateUpdateCount(0); - instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); - - this.update(instance, sc); + update(instance, sc); + } + }); } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 2c829141a1e..166b523e387 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -75,6 +75,7 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc; @@ -721,6 +722,13 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { + // for vmware template, we need to check if ova packing is needed, since template created from snapshot does not have .ova file + // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use extractURL to pass to following createTemplate. + // Need to understand what is the background to use two different urls for copy and extract. + if (srcTemplate.getFormat() == ImageFormat.OVA){ + ImageStoreEntity tmpltStore = (ImageStoreEntity)srcTemplate.getDataStore(); + tmpltStore.createEntityExtractUrl(srcTemplate.getInstallPath(), srcTemplate.getFormat(), srcTemplate); + } // generate a URL from source template ssvm to download to destination data store String url = generateCopyUrl(srcTemplate); if (url == null) { diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index e002ab3345c..7bb27e060e4 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -119,8 +119,6 @@ org.apache.httpcomponents httpclient - - 4.2.2 compile diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index bf5d646ef02..a4c423c861b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import org.springframework.stereotype.Component; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; @@ -35,6 +36,7 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -104,7 +106,12 @@ public class ImageStoreHelper { ImageStoreDetailVO detail = new ImageStoreDetailVO(); detail.setStoreId(store.getId()); detail.setName(key); - detail.setValue(details.get(key)); + String value = details.get(key); + // encrypt swift key or s3 secret key + if (key.equals(ApiConstants.KEY) || key.equals(ApiConstants.S3_SECRET_KEY)) { + value = DBEncryptionUtil.encrypt(value); + } + detail.setValue(value); imageStoreDetailsDao.persist(detail); } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java index 659a14894c6..56feb26e6bc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -24,9 +24,11 @@ import javax.ejb.Local; import org.springframework.stereotype.Component; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -68,7 +70,12 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase details = listBy(sc); Map detailsMap = new HashMap(); for (ImageStoreDetailVO detail : details) { - detailsMap.put(detail.getName(), detail.getValue()); + String name = detail.getName(); + String value = detail.getValue(); + if (name.equals(ApiConstants.KEY) || name.equals(ApiConstants.S3_SECRET_KEY)) { + value = DBEncryptionUtil.decrypt(value); + } + detailsMap.put(name, value); } return detailsMap; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index ac507cf4629..3e5a5466fd0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -158,8 +158,9 @@ public class VolumeServiceImpl implements VolumeService { return null; } + @Override public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { - DataStoreDriver dataStoreDriver = dataStore.getDriver(); + DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null; if (dataStoreDriver instanceof PrimaryDataStoreDriver) { return ((PrimaryDataStoreDriver)dataStoreDriver).connectVolumeToHost(volumeInfo, host, dataStore); @@ -168,8 +169,9 @@ public class VolumeServiceImpl implements VolumeService { return false; } + @Override public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { - DataStoreDriver dataStoreDriver = dataStore.getDriver(); + DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null; if (dataStoreDriver instanceof PrimaryDataStoreDriver) { ((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore); diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManager.java b/framework/cluster/src/com/cloud/cluster/ClusterManager.java index f59e63cc52c..ffdf3663f7b 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManager.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManager.java @@ -26,7 +26,6 @@ public interface ClusterManager extends Manager { "Interval to check for the heart beat between management server nodes", false); final ConfigKey HeartbeatThreshold = new ConfigKey(Integer.class, "cluster.heartbeat.threshold", "management-server", "150000", "Threshold before self-fence the management server", true); - final ConfigKey ManagementHostIPAdr = new ConfigKey("Advanced", String.class, "host", "localhost", "The ip address of management server", true); void OnReceiveClusterServicePdu(ClusterServicePdu pdu); diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java index ca0b031a5c2..622aa62f073 100644 --- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java +++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java @@ -1099,7 +1099,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {HeartbeatInterval, HeartbeatThreshold, ManagementHostIPAdr}; + return new ConfigKey[] {HeartbeatInterval, HeartbeatThreshold}; } private boolean pingManagementNode(ManagementServerHostVO mshost) { diff --git a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java index 7df00493d45..1ed37ab9969 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java @@ -27,4 +27,8 @@ public interface ConfigDepot { ConfigKey get(String paramName); Set> getConfigListByScope(String scope); + + void set(ConfigKey key, T value); + + void createOrUpdateConfigObject(String componentName, ConfigKey key, String value); } diff --git a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java b/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java index 2f6e524e860..c1ab6b89101 100644 --- a/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java +++ b/framework/config/src/org/apache/cloudstack/framework/config/impl/ConfigDepotImpl.java @@ -27,15 +27,14 @@ import java.util.Set; import javax.annotation.PostConstruct; import javax.inject.Inject; -import org.apache.commons.lang.ObjectUtils; -import org.apache.log4j.Logger; - import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.ScopedConfigStorage; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.commons.lang.ObjectUtils; +import org.apache.log4j.Logger; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @@ -116,23 +115,8 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { } _allKeys.put(key.key(), new Pair>(configurable.getConfigComponentName(), key)); - ConfigurationVO vo = _configDao.findById(key.key()); - if (vo == null) { - vo = new ConfigurationVO(configurable.getConfigComponentName(), key); - vo.setUpdated(date); - _configDao.persist(vo); - } else { - if (vo.isDynamic() != key.isDynamic() || !ObjectUtils.equals(vo.getDescription(), key.description()) || - !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue()) || - !ObjectUtils.equals(vo.getScope(), key.scope().toString())) { - vo.setDynamic(key.isDynamic()); - vo.setDescription(key.description()); - vo.setDefaultValue(key.defaultValue()); - vo.setScope(key.scope().toString()); - vo.setUpdated(date); - _configDao.persist(vo); - } - } + createOrupdateConfigObject(date, configurable.getConfigComponentName(), key, null); + if ((key.scope() != null) && (key.scope() != ConfigKey.Scope.Global)) { Set> currentConfigs = _scopeLevelConfigsMap.get(key.scope()); currentConfigs.add(key); @@ -142,6 +126,28 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { _configured.add(configurable); } + private void createOrupdateConfigObject(Date date, String componentName, ConfigKey key, String value) { + ConfigurationVO vo = _configDao.findById(key.key()); + if (vo == null) { + vo = new ConfigurationVO(componentName, key); + vo.setUpdated(date); + if (value != null) { + vo.setValue(value); + } + _configDao.persist(vo); + } else { + if (vo.isDynamic() != key.isDynamic() || !ObjectUtils.equals(vo.getDescription(), key.description()) || !ObjectUtils.equals(vo.getDefaultValue(), key.defaultValue()) + || !ObjectUtils.equals(vo.getScope(), key.scope().toString())) { + vo.setDynamic(key.isDynamic()); + vo.setDescription(key.description()); + vo.setDefaultValue(key.defaultValue()); + vo.setScope(key.scope().toString()); + vo.setUpdated(date); + _configDao.persist(vo); + } + } + } + @Override public void populateConfiguration(Configurable configurable) { populateConfiguration(new Date(), configurable); @@ -172,7 +178,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { @Inject public void setScopedStorages(List scopedStorages) { - this._scopedStorages = scopedStorages; + _scopedStorages = scopedStorages; } public List getConfigurables() { @@ -181,7 +187,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { @Inject public void setConfigurables(List configurables) { - this._configurables = configurables; + _configurables = configurables; } @Override @@ -189,4 +195,14 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin { return _scopeLevelConfigsMap.get(ConfigKey.Scope.valueOf(scope)); } + @Override + public void set(ConfigKey key, T value) { + _configDao.update(key.key(), value.toString()); + } + + @Override + public void createOrUpdateConfigObject(String componentName, ConfigKey key, String value) { + createOrupdateConfigObject(new Date(), componentName, key, value); + + } } diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index 503d7591135..f282428b8de 100755 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -658,9 +658,21 @@ public abstract class GenericDaoBase extends Compone } } + /** + * Get a value from a result set. + * + * @param type + * the expected type of the result + * @param rs + * the result set + * @param index + * the index of the column + * @return the result in the requested type + * @throws SQLException + */ @DB() @SuppressWarnings("unchecked") - protected M getObject(Class type, ResultSet rs, int index) throws SQLException { + protected static M getObject(Class type, ResultSet rs, int index) throws SQLException { if (type == String.class) { byte[] bytes = rs.getBytes(index); if (bytes != null) { @@ -681,12 +693,12 @@ public abstract class GenericDaoBase extends Compone return (M)new Integer(rs.getInt(index)); } } else if (type == long.class) { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } else if (type == Long.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } } else if (type == Date.class) { final Object data = rs.getDate(index); @@ -696,44 +708,44 @@ public abstract class GenericDaoBase extends Compone return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)); } } else if (type == short.class) { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } else if (type == Short.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } } else if (type == boolean.class) { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } else if (type == Boolean.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } } else if (type == float.class) { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } else if (type == Float.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } } else if (type == double.class) { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } else if (type == Double.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } } else if (type == byte.class) { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } else if (type == Byte.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } } else if (type == Calendar.class) { final Object data = rs.getDate(index); diff --git a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java new file mode 100644 index 00000000000..b7febcb8994 --- /dev/null +++ b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java @@ -0,0 +1,134 @@ +// 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.utils.db; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GenericDaoBaseTest { + @Mock + ResultSet resultSet; + + @Test + public void getObjectBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(Boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(Short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(Float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(Double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(Long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveByte() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((byte) 1); + Mockito.when(resultSet.getByte(1)).thenReturn((byte) 1); + Assert.assertTrue((byte) 1 == GenericDaoBase.getObject(byte.class, + resultSet, 1)); + Mockito.verify(resultSet).getByte(1); + } + +} diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java index a2d9a7bced0..e93bbc2ad4a 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java @@ -20,17 +20,24 @@ package org.apache.cloudstack.framework.messagebus; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.apache.log4j.Logger; + public class MessageDispatcher implements MessageSubscriber { - private static Map, Method> s_handlerCache = new HashMap, Method>(); + private static final Logger s_logger = Logger.getLogger(MessageDispatcher.class); + + private static Map, List> s_handlerCache = new HashMap, List>(); private static Map s_targetMap = new HashMap(); private Object _targetObject; public MessageDispatcher(Object targetObject) { _targetObject = targetObject; + buildHandlerMethodCache(targetObject.getClass()); } @Override @@ -67,10 +74,13 @@ public class MessageDispatcher implements MessageSubscriber { try { handler.invoke(target, subject, senderAddress, args); } catch (IllegalArgumentException e) { + s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e); throw new RuntimeException("IllegalArgumentException when invoking event handler for subject: " + subject); } catch (IllegalAccessException e) { + s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e); throw new RuntimeException("IllegalAccessException when invoking event handler for subject: " + subject); } catch (InvocationTargetException e) { + s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e); throw new RuntimeException("InvocationTargetException when invoking event handler for subject: " + subject); } @@ -79,18 +89,18 @@ public class MessageDispatcher implements MessageSubscriber { public static Method resolveHandler(Class handlerClz, String subject) { synchronized (s_handlerCache) { - Method handler = s_handlerCache.get(handlerClz); - if (handler != null) - return handler; + List handlerList = s_handlerCache.get(handlerClz); + if (handlerList != null) { + for (Method method : handlerList) { + MessageHandler annotation = method.getAnnotation(MessageHandler.class); + assert (annotation != null); - for (Method method : handlerClz.getMethods()) { - MessageHandler annotation = method.getAnnotation(MessageHandler.class); - if (annotation != null) { if (match(annotation.topic(), subject)) { - s_handlerCache.put(handlerClz, method); return method; } } + } else { + s_logger.error("Handler class " + handlerClz.getName() + " is not registered"); } } @@ -100,4 +110,40 @@ public class MessageDispatcher implements MessageSubscriber { private static boolean match(String expression, String param) { return param.matches(expression); } + + private void buildHandlerMethodCache(Class handlerClz) { + if (s_logger.isInfoEnabled()) + s_logger.info("Build message handler cache for " + handlerClz.getName()); + + synchronized (s_handlerCache) { + List handlerList = s_handlerCache.get(handlerClz); + if (handlerList == null) { + handlerList = new ArrayList(); + s_handlerCache.put(handlerClz, handlerList); + + Class clz = handlerClz; + while (clz != null && clz != Object.class) { + for (Method method : clz.getDeclaredMethods()) { + MessageHandler annotation = method.getAnnotation(MessageHandler.class); + if (annotation != null) { + // allow private member access via reflection + method.setAccessible(true); + handlerList.add(method); + + if (s_logger.isInfoEnabled()) + s_logger.info("Add message handler " + handlerClz.getName() + "." + method.getName() + " to cache"); + } + } + + clz = clz.getSuperclass(); + } + } else { + if (s_logger.isInfoEnabled()) + s_logger.info("Message handler for class " + handlerClz.getName() + " is already in cache"); + } + } + + if (s_logger.isInfoEnabled()) + s_logger.info("Done building message handler cache for " + handlerClz.getName()); + } } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java index f558e013712..20125f43e66 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/AsyncJobExecutionContext.java @@ -30,7 +30,9 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; -public class AsyncJobExecutionContext { +public class AsyncJobExecutionContext { + private static final Logger s_logger = Logger.getLogger(AsyncJobExecutionContext.class); + private AsyncJob _job; static private AsyncJobManager s_jobMgr; @@ -112,7 +114,8 @@ public class AsyncJobExecutionContext { } // - // check failure exception before we disjoin the worker job + // check failure exception before we disjoin the worker job, work job usually fails with exception + // this will help propogate exception between jobs // TODO : it is ugly and this will become unnecessary after we switch to full-async mode // public void disjoinJob(long joinedJobId) throws InsufficientCapacityException, @@ -120,21 +123,34 @@ public class AsyncJobExecutionContext { assert (_job != null); AsyncJobJoinMapVO record = s_joinMapDao.getJoinRecord(_job.getId(), joinedJobId); - if (record.getJoinStatus() == JobInfo.Status.FAILED && record.getJoinResult() != null) { - Object exception = JobSerializerHelper.fromObjectSerializedString(record.getJoinResult()); - if (exception != null && exception instanceof Exception) { - if (exception instanceof InsufficientCapacityException) - throw (InsufficientCapacityException)exception; - else if (exception instanceof ConcurrentOperationException) - throw (ConcurrentOperationException)exception; - else if (exception instanceof ResourceUnavailableException) - throw (ResourceUnavailableException)exception; - else - throw new RuntimeException((Exception)exception); + s_jobMgr.disjoinJob(_job.getId(), joinedJobId); + + if (record.getJoinStatus() == JobInfo.Status.FAILED) { + if (record.getJoinResult() != null) { + Object exception = JobSerializerHelper.fromObjectSerializedString(record.getJoinResult()); + if (exception != null && exception instanceof Exception) { + if (exception instanceof InsufficientCapacityException) { + s_logger.error("Job " + joinedJobId + " failed with InsufficientCapacityException"); + throw (InsufficientCapacityException)exception; + } + else if (exception instanceof ConcurrentOperationException) { + s_logger.error("Job " + joinedJobId + " failed with ConcurrentOperationException"); + throw (ConcurrentOperationException)exception; + } + else if (exception instanceof ResourceUnavailableException) { + s_logger.error("Job " + joinedJobId + " failed with ResourceUnavailableException"); + throw (ResourceUnavailableException)exception; + } + else { + s_logger.error("Job " + joinedJobId + " failed with exception"); + throw new RuntimeException((Exception)exception); + } + } + } else { + s_logger.error("Job " + joinedJobId + " failed without providing an error object"); + throw new RuntimeException("Job " + joinedJobId + " failed without providing an error object"); } } - - s_jobMgr.disjoinJob(_job.getId(), joinedJobId); } public void completeJoin(JobInfo.Status joinStatus, String joinResult) { @@ -151,6 +167,8 @@ public class AsyncJobExecutionContext { public static AsyncJobExecutionContext getCurrentExecutionContext() { AsyncJobExecutionContext context = s_currentExectionContext.get(); if (context == null) { + // TODO, this has security implicitions + s_logger.warn("Job is executed without a context, setup psudo job for the executing thread"); context = registerPseudoExecutionContext(CallContext.current().getCallingAccountId(), CallContext.current().getCallingUserId()); } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java index a3dbddf0eb6..44e39e40291 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDao.java @@ -35,4 +35,6 @@ public interface VmWorkJobDao extends GenericDao { void updateStep(long workJobId, Step step); void expungeCompletedWorkJobs(Date cutDate); + + void expungeLeftoverWorkJobs(long msid); } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java index 5e0ffb68c39..cf3e17392b5 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java @@ -16,8 +16,11 @@ // under the License. package org.apache.cloudstack.framework.jobs.dao; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.Date; import java.util.List; +import java.util.TimeZone; import javax.annotation.PostConstruct; @@ -31,13 +34,16 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.vm.VirtualMachine; public class VmWorkJobDaoImpl extends GenericDaoBase implements VmWorkJobDao { protected SearchBuilder PendingWorkJobSearch; protected SearchBuilder PendingWorkJobByCommandSearch; - protected SearchBuilder ExpungeWorkJobSearch; public VmWorkJobDaoImpl() { } @@ -48,7 +54,6 @@ public class VmWorkJobDaoImpl extends GenericDaoBase implemen PendingWorkJobSearch.and("jobStatus", PendingWorkJobSearch.entity().getStatus(), Op.EQ); PendingWorkJobSearch.and("vmType", PendingWorkJobSearch.entity().getVmType(), Op.EQ); PendingWorkJobSearch.and("vmInstanceId", PendingWorkJobSearch.entity().getVmInstanceId(), Op.EQ); - PendingWorkJobSearch.and("step", PendingWorkJobSearch.entity().getStep(), Op.NEQ); PendingWorkJobSearch.done(); PendingWorkJobByCommandSearch = createSearchBuilder(); @@ -58,11 +63,6 @@ public class VmWorkJobDaoImpl extends GenericDaoBase implemen PendingWorkJobByCommandSearch.and("step", PendingWorkJobByCommandSearch.entity().getStep(), Op.NEQ); PendingWorkJobByCommandSearch.and("cmd", PendingWorkJobByCommandSearch.entity().getCmd(), Op.EQ); PendingWorkJobByCommandSearch.done(); - - ExpungeWorkJobSearch = createSearchBuilder(); - ExpungeWorkJobSearch.and("lastUpdated", ExpungeWorkJobSearch.entity().getLastUpdated(), Op.LT); - ExpungeWorkJobSearch.and("jobStatus", ExpungeWorkJobSearch.entity().getStatus(), Op.NEQ); - ExpungeWorkJobSearch.done(); } @Override @@ -115,11 +115,80 @@ public class VmWorkJobDaoImpl extends GenericDaoBase implemen } @Override - public void expungeCompletedWorkJobs(Date cutDate) { - SearchCriteria sc = ExpungeWorkJobSearch.create(); - sc.setParameters("lastUpdated", cutDate); - sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS); + public void expungeCompletedWorkJobs(final Date cutDate) { + // current DAO machenism does not support following usage + /* + SearchCriteria sc = ExpungeWorkJobSearch.create(); + sc.setParameters("lastUpdated",cutDate); + sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS); - expunge(sc); + expunge(sc); + */ + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + TransactionLegacy txn = TransactionLegacy.currentTxn(); + + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement( + "DELETE FROM vm_work_job WHERE id IN (SELECT id FROM async_job WHERE job_dispatcher='VmWorkJobDispatcher' AND job_status != 0 AND last_updated < ?)"); + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); + + pstmt.execute(); + } catch (SQLException e) { + } catch (Throwable e) { + } + + try { + pstmt = txn.prepareAutoCloseStatement( + "DELETE FROM async_job WHERE job_dispatcher='VmWorkJobDispatcher' AND job_status != 0 AND last_updated < ?"); + pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate)); + + pstmt.execute(); + } catch (SQLException e) { + } catch (Throwable e) { + } + } + }); + } + + @Override + public void expungeLeftoverWorkJobs(final long msid) { + // current DAO machenism does not support following usage + /* + SearchCriteria sc = ExpungePlaceHolderWorkJobSearch.create(); + sc.setParameters("dispatcher", "VmWorkJobPlaceHolder"); + sc.setParameters("msid", msid); + + expunge(sc); + */ + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + TransactionLegacy txn = TransactionLegacy.currentTxn(); + + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement( + "DELETE FROM vm_work_job WHERE id IN (SELECT id FROM async_job WHERE (job_dispatcher='VmWorkJobPlaceHolder' OR job_dispatcher='VmWorkJobDispatcher') AND job_init_msid=?)"); + pstmt.setLong(1, msid); + + pstmt.execute(); + } catch (SQLException e) { + } catch (Throwable e) { + } + + try { + pstmt = txn.prepareAutoCloseStatement( + "DELETE FROM async_job WHERE (job_dispatcher='VmWorkJobPlaceHolder' OR job_dispatcher='VmWorkJobDispatcher') AND job_init_msid=?"); + pstmt.setLong(1, msid); + + pstmt.execute(); + } catch (SQLException e) { + } catch (Throwable e) { + } + } + }); } } diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index bfd9f18caf9..c3ac0e67b8f 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -475,7 +475,9 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, if (jobDispatcher != null) { jobDispatcher.runJob(job); } else { - s_logger.error("Unable to find a wakeup dispatcher from the joined job: " + job); + // TODO, job wakeup is not in use yet + if (s_logger.isTraceEnabled()) + s_logger.trace("Unable to find a wakeup dispatcher from the joined job: " + job); } } else { AsyncJobDispatcher jobDispatcher = getDispatcher(job.getDispatcher()); diff --git a/framework/security/pom.xml b/framework/security/pom.xml index a5fa5f07a51..42627f524a8 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -25,7 +25,7 @@ cloudstack-framework 4.4.0-SNAPSHOT ../pom.xml - + org.apache.cloudstack @@ -42,6 +42,10 @@ cloud-framework-ipc ${project.version} + + commons-codec + commons-codec + org.apache.cloudstack cloud-framework-db @@ -51,6 +55,6 @@ org.apache.cloudstack cloud-framework-config ${project.version} - + diff --git a/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml b/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml index 3775565aeea..fe05bc11bb8 100644 --- a/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml +++ b/framework/security/resources/META-INF/cloudstack/core/spring-framework-security-core-context.xml @@ -28,4 +28,5 @@ > + diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java new file mode 100644 index 00000000000..d6d2e0149d2 --- /dev/null +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManager.java @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.framework.security.keys; + +import org.apache.cloudstack.framework.config.ConfigKey; + +/** + * + * Started this file to manage keys. Will be needed by other services. + * + */ +public interface KeysManager { + final ConfigKey EncryptionKey = new ConfigKey("Hidden", String.class, "security.encryption.key", null, "base64 encoded key data", false); + final ConfigKey EncryptionIV = new ConfigKey("Hidden", String.class, "security.encryption.iv", null, "base64 encoded IV data", false); + final ConfigKey HashKey = new ConfigKey("Hidden", String.class, "security.hash.key", null, "for generic key-ed hash", false); + + String getEncryptionKey(); + + String getEncryptionIV(); + + void resetEncryptionKeyIV(); + + String getHashKey(); +} diff --git a/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java new file mode 100644 index 00000000000..550bd155c95 --- /dev/null +++ b/framework/security/src/org/apache/cloudstack/framework/security/keys/KeysManagerImpl.java @@ -0,0 +1,127 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.framework.security.keys; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +import javax.inject.Inject; +import javax.net.ssl.KeyManager; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.framework.config.ConfigDepot; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +/** + * To be perfectly honest, I'm not sure why we need this class. This used + * to be in ManagementServerImpl. I moved the functionality because it seems + * many features will need this. However, the right thing will be for setup + * and upgrade to take care of key generation. Here, the methods appear to + * mainly be used for dynamic generation. I added this class because after + * talking to Kelven, we think there will be other functionalities we need + * to centralize to this class. We'll see how that works out. + * + * There's multiple problems here that we need to fix. + * - Multiple servers can be generating keys. This is not atomic. + * - The functionality of generating the keys should be moved over to setup/upgrade. + * + */ +public class KeysManagerImpl implements KeysManager, Configurable { + private static final Logger s_logger = Logger.getLogger(KeysManagerImpl.class); + + @Inject + ConfigurationDao _configDao; + @Inject + ConfigDepot _configDepot; + + @Override + public String getHashKey() { + String value = HashKey.value(); + if (value == null) { + _configDepot.set(HashKey, getBase64EncodedRandomKey(128)); + } + + return HashKey.value(); + } + + @Override + public String getEncryptionKey() { + String value = EncryptionKey.value(); + if (value == null) { + _configDepot.set(EncryptionKey, getBase64EncodedRandomKey(128)); + } + return EncryptionKey.value(); + } + + @Override + public String getEncryptionIV() { + String value = EncryptionIV.value(); + if (value == null) { + _configDepot.set(EncryptionIV, getBase64EncodedRandomKey(128)); + } + return EncryptionIV.value(); + } + + private static String getBase64EncodedRandomKey(int nBits) { + SecureRandom random; + try { + random = SecureRandom.getInstance("SHA1PRNG"); + byte[] keyBytes = new byte[nBits / 8]; + random.nextBytes(keyBytes); + return Base64.encodeBase64URLSafeString(keyBytes); + } catch (NoSuchAlgorithmException e) { + s_logger.error("Unhandled exception: ", e); + } + return null; + } + + @Override + @DB + public void resetEncryptionKeyIV() { + + SearchBuilder sb = _configDao.createSearchBuilder(); + sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.done(); + + SearchCriteria sc = sb.create(); + sc.setParameters("name1", EncryptionKey.key()); + sc.setParameters("name2", EncryptionIV.key()); + + _configDao.expunge(sc); + } + + @Override + public String getConfigComponentName() { + return KeyManager.class.getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {EncryptionKey, EncryptionIV, HashKey}; + } + +} diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index 14bcfbef6f7..33196a73ec2 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -20,6 +20,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-framework-spring-module + Apache CloudStack Framework - Spring Module org.apache.cloudstack cloud-maven-standard diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 7132d4f2cc4..83c598b07a7 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -43,7 +43,7 @@ Group: System Environment/Libraries Source0: %{name}-%{_maventag}.tgz BuildRoot: %{_tmppath}/%{name}-%{_maventag}-%{release}-build -BuildRequires: java-1.6.0-openjdk-devel +BuildRequires: java-1.7.0-openjdk-devel BuildRequires: tomcat6 BuildRequires: ws-commons-util BuildRequires: jpackage-utils @@ -60,7 +60,7 @@ intelligent IaaS cloud implementation. %package management Summary: CloudStack management server UI Requires: tomcat6 -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: python Requires: bash Requires: bzip2 @@ -111,7 +111,8 @@ The Apache CloudStack files shared between agent and management server %package agent Summary: CloudStack Agent for KVM hypervisors -Requires: java >= 1.6.0 +Requires: openssh-clients +Requires: java >= 1.7.0 Requires: %{name}-common = %{_ver} Requires: libvirt Requires: bridge-utils @@ -137,7 +138,7 @@ The CloudStack agent for KVM hypervisors %package usage Summary: CloudStack Usage calculation server -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: jsvc Requires: jakarta-commons-daemon Requires: jakarta-commons-daemon-jsvc diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs index 854427732aa..4bf424fa4b9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs @@ -45,7 +45,7 @@ namespace CloudStack.Plugin.AgentShell private void InitializeComponent() { components = new System.ComponentModel.Container(); - this.ServiceName = "CloudStack ServerResource"; + this.ServiceName = Program.serviceName; } #endregion diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs index e1870973511..9d66a5cd1bf 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.cs @@ -47,7 +47,7 @@ namespace CloudStack.Plugin.AgentShell logger.Info("Starting CloudStack agent"); InitializeComponent(); - UriBuilder baseUri = new UriBuilder("http", AgentSettings.Default.private_ip_address, AgentSettings.Default.port); + UriBuilder baseUri = new UriBuilder("https", AgentSettings.Default.private_ip_address, AgentSettings.Default.port); var config = new HttpSelfHostConfiguration(baseUri.Uri); diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config index 68ab80ee555..3ec08bd29c9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config @@ -10,9 +10,9 @@ - + - + @@ -25,13 +25,14 @@ + - + @@ -95,7 +96,7 @@ 2048 - 10.102.192.150 + 0.0.0.0 diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 89f0814214e..c336a3821e3 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -61,7 +61,7 @@ namespace HypervResource get { string uncPath = null; - if (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem")) + if (uri != null && (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem"))) { uncPath = @"\\" + uri.Host + uri.LocalPath; } @@ -73,8 +73,13 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + string user = null; + if (uri != null) + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + user = System.Web.HttpUtility.UrlDecode(queryDictionary["user"]); + } + return user; } } @@ -82,8 +87,13 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + string password = null; + if (uri != null) + { + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + password = System.Web.HttpUtility.UrlDecode(queryDictionary["password"]); + } + return password; } } @@ -91,12 +101,17 @@ namespace HypervResource { get { - var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); - if (queryDictionary["domain"] != null) + string domain = null; + if (uri != null) { - return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query); + if (queryDictionary["domain"] != null) + { + domain = System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]); + } + else domain = uri.Host; } - else return uri.Host; + return domain; } } @@ -239,7 +254,7 @@ namespace HypervResource // Assert if (result.dataStore == null || (result.primaryDataStore == null && result.nfsDataStore == null)) { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volumeObjectTOJson.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volumeObjectTOJson.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } @@ -277,7 +292,7 @@ namespace HypervResource } else { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volInfo.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volInfo.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } @@ -675,6 +690,20 @@ namespace HypervResource public String entityType; } + public class NicDetails + { + [JsonProperty("macAddress")] + public string macaddress; + [JsonProperty("vlanid")] + public int vlanid; + public NicDetails() { } + public NicDetails(String macaddress, int vlanid) + { + this.macaddress = macaddress; + this.vlanid = vlanid; + } + } + /// /// Fully qualified named for a number of types used in CloudStack. Used to specify the intended type for JSON serialised objects. /// @@ -723,6 +752,10 @@ namespace HypervResource public const string GetVmDiskStatsCommand = "com.cloud.agent.api.GetVmDiskStatsCommand"; public const string GetVmStatsAnswer = "com.cloud.agent.api.GetVmStatsAnswer"; public const string GetVmStatsCommand = "com.cloud.agent.api.GetVmStatsCommand"; + public const string GetVmConfigCommand = "com.cloud.agent.api.GetVmConfigCommand"; + public const string GetVmConfigAnswer = "com.cloud.agent.api.GetVmConfigAnswer"; + public const string ModifyVmNicConfigCommand = "com.cloud.agent.api.ModifyVmNicConfigCommand"; + public const string ModifyVmNicConfigAnswer = "com.cloud.agent.api.ModifyVmNicConfigAnswer"; public const string GetVncPortAnswer = "com.cloud.agent.api.GetVncPortAnswer"; public const string GetVncPortCommand = "com.cloud.agent.api.GetVncPortCommand"; public const string HostStatsEntry = "com.cloud.agent.api.HostStatsEntry"; diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 18f3158da46..ebb3bce2cf8 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -207,7 +207,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.AttachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.AttachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -268,7 +268,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.DettachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.DettachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -485,7 +485,7 @@ namespace HypervResource { JObject ansObj = Utils.CreateCloudStackObject(ansType, ansContent); JArray answer = new JArray(ansObj); - logger.Info(ansObj.ToString()); + logger.Info(Utils.CleanString(ansObj.ToString())); return answer; } @@ -496,7 +496,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -603,7 +603,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + cmd.ToString()); + logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; long size = 0; @@ -871,7 +871,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateStoragePoolCommand + Utils.CleanString(cmd.ToString())); object ansContent = new { result = true, @@ -889,7 +889,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.ModifyStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.ModifyStoragePoolCommand + Utils.CleanString(cmd.ToString())); string details = null; string localPath; StoragePoolType poolType; @@ -982,6 +982,24 @@ namespace HypervResource return true; } + // POST api/HypervResource/PlugNicCommand + [HttpPost] + [ActionName(CloudStackTypes.PlugNicCommand)] + public JContainer PlugNicCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.PlugNicCommand + cmd.ToString()); + object ansContent = new + { + result = true, + details = "instead of plug, change he network settings", + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer); + } + } + // POST api/HypervResource/CleanupNetworkRulesCmd [HttpPost] @@ -1045,7 +1063,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.StartCommand + cmd.ToString()); // TODO: Security hole? VM data printed to log + logger.Info(CloudStackTypes.StartCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -1144,7 +1162,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateObjectCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1264,6 +1282,88 @@ namespace HypervResource } } + // POST api/HypervResource/ModifyVmVnicVlanCommand + [HttpPost] + [ActionName(CloudStackTypes.ModifyVmNicConfigCommand)] + public JContainer ModifyVmNicConfigCommand([FromBody]dynamic cmd) + { + + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + uint vlan = (uint)cmd.vlan; + string macAddress = cmd.macAddress; + wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress); + + result = true; + + object ansContent = new + { + vmName = vmName, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyVmNicConfigAnswer); + } + + } + + // POST api/HypervResource/GetVmConfigCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVmConfigCommand)] + public JContainer GetVmConfigCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVmConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName); + List nicDetails = new List(); + var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm); + NicDetails nic = null; + String[] macAddress = new String[nicSettingsViaVm.Length]; + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + macAddress[index++] = item.Address; + } + + index = 0; + var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm); + int vlanid = 1; + foreach (EthernetPortAllocationSettingData item in ethernetConnections) + { + EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item); + if (vlanSettings == null) + { + vlanid = -1; + } + else + { + vlanid = vlanSettings.AccessVlanId; + } + nic = new NicDetails(macAddress[index++], vlanid); + nicDetails.Add(nic); + } + + result = true; + + object ansContent = new + { + vmName = vmName, + nics = nicDetails, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmConfigAnswer); + } + } + + + // POST api/HypervResource/GetVmStatsCommand [HttpPost] [ActionName(CloudStackTypes.GetVmStatsCommand)] @@ -1315,7 +1415,7 @@ namespace HypervResource using (log4net.NDC.Push(Guid.NewGuid().ToString())) { // Log command *after* we've removed security details from the command. - logger.Info(CloudStackTypes.CopyCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CopyCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1474,15 +1574,8 @@ namespace HypervResource { // TODO: thin provision instead of copying the full file. File.Copy(srcFile, destFile); - VolumeObjectTO volume = new VolumeObjectTO(); - volume.path = destFile; - volume.dataStore = destVolumeObjectTO.dataStore; - volume.name = destVolumeObjectTO.name; - volume.size = ulong.Parse(destVolumeObjectTO.size.ToString()); - volume.format = destVolumeObjectTO.format; - volume.nfsDataStore = destVolumeObjectTO.nfsDataStore; - volume.primaryDataStore = destVolumeObjectTO.primaryDataStore; - JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, volume); + destVolumeObjectTO.path = destFile; + JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO); newData = ansObj; result = true; } @@ -1597,6 +1690,11 @@ namespace HypervResource string templatePropFile = Path.Combine(path, "template.properties"); using (StreamWriter sw = new StreamWriter(File.Open(templatePropFile, FileMode.Create), Encoding.GetEncoding("iso-8859-1"))) { + if (format != null) + { + format = format.ToLower(); + } + sw.NewLine = "\n"; sw.WriteLine("id=" + templateId); sw.WriteLine("filename=" + templateUuid + "." + format); @@ -1606,7 +1704,7 @@ namespace HypervResource sw.WriteLine("virtualsize=" + virtualSize); sw.WriteLine(format + ".virtualsize=" + virtualSize); sw.WriteLine("size=" + physicalSize); - sw.WriteLine("vhd.size=" + physicalSize); + sw.WriteLine(format + ".size=" + physicalSize); sw.WriteLine("public=false"); } } @@ -1693,7 +1791,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.GetStorageStatsCommand + cmd.ToString()); + logger.Info(CloudStackTypes.GetStorageStatsCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; long capacity = 0; @@ -1923,6 +2021,7 @@ namespace HypervResource string productVersion = System.Environment.OSVersion.Version.Major.ToString() + "." + System.Environment.OSVersion.Version.Minor.ToString(); details.Add("product_version", productVersion); + details.Add("rdp.server.port", 2179); } // Detect CPUs, speed, memory @@ -2002,6 +2101,45 @@ namespace HypervResource } } + // POST api/HypervResource/GetVncPortCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVncPortCommand)] + public JContainer GetVncPortCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVncPortCommand + cmd.ToString()); + + string details = null; + bool result = false; + string address = null; + int port = -9; + + try + { + string vmName = (string)cmd.name; + var sys = wmiCallsV2.GetComputerSystem(vmName); + address = "instanceId=" + sys.Name ; + result = true; + } + catch (Exception sysEx) + { + details = CloudStackTypes.GetVncPortAnswer + " failed due to " + sysEx.Message; + logger.Error(details, sysEx); + } + + object ansContent = new + { + result = result, + details = details, + address = address, + port = port + }; + + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVncPortAnswer); + } + } + public static System.Net.NetworkInformation.NetworkInterface GetNicInfoFromIpAddress(string ipAddress, out string subnet) { System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index 5f814c59535..9042d7c5e12 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -66,5 +66,6 @@ namespace HypervResource void patchSystemVmIso(string vmName, string systemVmIso); void SetState(ComputerSystem vm, ushort requiredState); Dictionary GetVmSync(String privateIpAddress); + void ModifyVmVLan(string vmName, uint vlanid, string mac); } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs index c4b39ba24c2..6ebc5bf7f23 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs @@ -164,6 +164,16 @@ namespace HypervResource capacity = totalNumberOfBytes > 0 ? (long)totalNumberOfBytes : 0; } + public static string CleanString(string stringToClean) + { + string cleanString = null; + string regexQueryString = "(&|%26)?(password|accesskey|secretkey)(=|%3D).*?(?=(%26|[&'\"]))"; + string regexJson = "\"(password|accesskey|secretkey)\":\".*?\",?"; + cleanString = System.Text.RegularExpressions.Regex.Replace(stringToClean, regexQueryString, ""); + cleanString = System.Text.RegularExpressions.Regex.Replace(cleanString, regexJson, ""); + return cleanString; + } + // from http://stackoverflow.com/a/2541569/939250 #region imports [DllImport("advapi32.dll", SetLastError = true)] diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 2e3aca59675..b9694f00eca 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -443,6 +443,7 @@ namespace HypervResource nicCount++; } + // pass the boot args for the VM using KVP component. // We need to pass the boot args to system vm's to get them configured with cloudstack configuration. // Add new user data @@ -909,6 +910,37 @@ namespace HypervResource return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone()); } + + // Modify the systemvm nic's VLAN id + public void ModifyVmVLan(string vmName, uint vlanid, String mac) + { + ComputerSystem vm = GetComputerSystem(vmName); + SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm); + // Obtain controller for Hyper-V virtualisation subsystem + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + if (normalisedMAC.ToLower().Equals(item.Address.ToLower())) + { + break; + } + index++; + } + + //TODO: make sure the index wont be out of range. + + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); + + //Assign configuration to new NIC + vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; + vlanSettings.LateBoundObject["OperationMode"] = 1; + ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { + vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + public void AttachIso(string displayName, string iso) { logger.DebugFormat("Got request to attach iso {0} to vm {1}", iso, displayName); @@ -1420,6 +1452,36 @@ namespace HypervResource return vSwitch; } + + private static void ModifyFeatureVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) + { + // Resource settings are changed through the management service + System.Management.ManagementPath jobPath; + System.Management.ManagementPath[] results; + + var ret_val = vmMgmtSvc.ModifyFeatureSettings( + resourceSettings, + out jobPath, + out results); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted", + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) { // Resource settings are changed through the management service diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index 162fd641023..fca7cd93680 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -90,7 +90,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.12 diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java index 5845038bbff..1d9e7f619f9 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java @@ -16,15 +16,30 @@ // under the License. package com.cloud.hypervisor.hyperv.guru; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.hypervisor.HypervisorGuruBase; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.hypervisor.hyperv.manager.HypervManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -35,6 +50,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject private GuestOSDao _guestOsDao; + @Inject HypervManager _hypervMgr; + @Inject NetworkDao _networkDao; + @Inject NetworkModel _networkMgr; @Override public final HypervisorType getHypervisorType() { @@ -51,6 +69,78 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Override public final VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); + List nicProfiles = vm.getNics(); + + if(vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) { + + NicProfile publicNicProfile = null; + for(NicProfile nicProfile : nicProfiles) { + if(nicProfile.getTrafficType() == TrafficType.Public) { + publicNicProfile = nicProfile; + break; + } + } + + if(publicNicProfile != null) { + NicTO[] nics = to.getNics(); + + // reserve extra NICs + NicTO[] expandedNics = new NicTO[nics.length + _hypervMgr.getRouterExtraPublicNics()]; + int i = 0; + int deviceId = -1; + for(i = 0; i < nics.length; i++) { + expandedNics[i] = nics[i]; + if(nics[i].getDeviceId() > deviceId) + deviceId = nics[i].getDeviceId(); + } + deviceId++; + + long networkId = publicNicProfile.getNetworkId(); + NetworkVO network = _networkDao.findById(networkId); + + for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) { + NicTO nicTo = new NicTO(); + nicTo.setDeviceId(deviceId++); + nicTo.setBroadcastType(publicNicProfile.getBroadcastType()); + nicTo.setType(publicNicProfile.getTrafficType()); + nicTo.setIp("0.0.0.0"); + nicTo.setNetmask("255.255.255.255"); + nicTo.setName(publicNicProfile.getName()); + + try { + String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId); + nicTo.setMac(mac); + } catch (InsufficientAddressCapacityException e) { + throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId); + } + nicTo.setDns1(publicNicProfile.getDns1()); + nicTo.setDns2(publicNicProfile.getDns2()); + if (publicNicProfile.getGateway() != null) { + nicTo.setGateway(publicNicProfile.getGateway()); + } else { + nicTo.setGateway(network.getGateway()); + } + nicTo.setDefaultNic(false); + nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri()); + nicTo.setIsolationuri(publicNicProfile.getIsolationUri()); + + Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null); + nicTo.setNetworkRateMbps(networkRate); + + expandedNics[i] = nicTo; + } + to.setNics(expandedNics); + } + + StringBuffer sbMacSequence = new StringBuffer(); + for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) { + sbMacSequence.append(nicTo.getMac()).append("|"); + } + sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); + String bootArgs = to.getBootArgs(); + to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); + + } // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); @@ -59,6 +149,29 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { return to; } + private NicTO[] sortNicsByDeviceId(NicTO[] nics) { + + List listForSort = new ArrayList(); + for (NicTO nic : nics) { + listForSort.add(nic); + } + Collections.sort(listForSort, new Comparator() { + + @Override + public int compare(NicTO arg0, NicTO arg1) { + if (arg0.getDeviceId() < arg1.getDeviceId()) { + return -1; + } else if (arg0.getDeviceId() == arg1.getDeviceId()) { + return 0; + } + + return 1; + } + }); + + return listForSort.toArray(new NicTO[0]); + } + @Override public final boolean trackVmHostChange() { return false; diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java index 9030e29e7a4..5821fe4dcae 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java @@ -21,4 +21,5 @@ import com.cloud.utils.component.Manager; public interface HypervManager extends Manager { public String prepareSecondaryStorageStore(long zoneId); + int getRouterExtraPublicNics(); } diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java index a30eb7df005..71a619a0ad5 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java @@ -45,6 +45,8 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; @Local(value = {HypervManager.class}) public class HypervManagerImpl implements HypervManager { @@ -60,10 +62,11 @@ public class HypervManagerImpl implements HypervManager { Map _storageMounts = new HashMap(); StorageLayer _storage; - @Inject - ConfigurationDao _configDao; - @Inject - DataStoreManager _dataStoreMgr; + @Inject ConfigurationDao _configDao; + @Inject DataStoreManager _dataStoreMgr; + @Inject VMInstanceDao _vminstanceDao; + @Inject NicDao _nicDao; + int _routerExtraPublicNics = 2; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -77,7 +80,7 @@ public class HypervManagerImpl implements HypervManager { _storage = new JavaStorageLayer(); _storage.configure("StorageLayer", params); } - + _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); return true; } @@ -373,4 +376,9 @@ public class HypervManagerImpl implements HypervManager { } } } -} + + @Override + public int getRouterExtraPublicNics() { + return _routerExtraPublicNics; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index 72a59216c2f..2f645906317 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -25,23 +25,39 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.channels.SocketChannel; import java.rmi.RemoteException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringEscapeUtils; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.BasicClientConnectionManager; import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; @@ -55,7 +71,12 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.GetVmConfigAnswer; +import com.cloud.agent.api.GetVmConfigAnswer.NicDetails; +import com.cloud.agent.api.GetVmConfigCommand; import com.cloud.agent.api.HostVmStateReportEntry; +import com.cloud.agent.api.ModifyVmNicConfigAnswer; +import com.cloud.agent.api.ModifyVmNicConfigCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; @@ -101,11 +122,13 @@ import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.hyperv.manager.HypervManager; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; @@ -118,6 +141,7 @@ import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineName; + /** * Implementation of dummy resource to be returned from discoverer. **/ @@ -302,7 +326,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S URI agentUri = null; try { String cmdName = StartupCommand.class.getName(); - agentUri = new URI("http", null, _agentIp, _port, "/api/HypervResource/" + cmdName, null, null); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); } catch (URISyntaxException e) { // TODO add proper logging String errMsg = "Could not generate URI for Hyper-V agent"; @@ -339,7 +365,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S Answer answer = null; try { String cmdName = cmd.getClass().getName(); - agentUri = new URI("http", null, _agentIp, _port, "/api/HypervResource/" + cmdName, null, null); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); } catch (URISyntaxException e) { // TODO add proper logging String errMsg = "Could not generate URI for Hyper-V agent"; @@ -416,7 +444,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S // Only Answer instances are returned by remote agents. // E.g. see Response.getAnswers() Answer[] result = s_gson.fromJson(ansStr, Answer[].class); - s_logger.debug("executeRequest received response " + s_gson.toJson(result)); + String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result.toString())); + s_logger.debug("executeRequest received response " + logResult); if (result.length > 0) { return result[0]; } @@ -686,65 +715,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } } - // - // find mac address of a specified ethx device - // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 - // returns - // eth0:xx.xx.xx.xx - - // - // list IP with eth devices - // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' - // | awk -F: '{ print $1 ": " $3 }' - // - // returns - // eth0:xx.xx.xx.xx - // - // - - private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { - - s_logger.info("findRouterEthDeviceIndex. mac: " + mac); - - // TODO : this is a temporary very inefficient solution, will refactor it later - Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "ls /proc/sys/net/ipv4/conf"); - - // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS - // we use a waiting loop here as a workaround to synchronize activities in systems - long startTick = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTick < 15000) { - if (result.first()) { - String[] tokens = result.second().split("\\s+"); - for (String token : tokens) { - if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { - String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Run domr script " + cmd); - Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, - // TODO need to find the dev index inside router based on IP address - cmd); - if (s_logger.isDebugEnabled()) - s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); - - if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) - return Integer.parseInt(token.substring(3)); - } - } - } - - s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); - - try { - Thread.currentThread(); - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - - return -1; - } - protected Answer execute(SetPortForwardingRulesCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd)); @@ -1150,74 +1120,35 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd)); } - - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String controlIp = getRouterSshControlIp(cmd); + Map> data = new HashMap>(); + data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String vmIpAddress = cmd.getVmIpAddress(); - List vmData = cmd.getVmData(); - String[] vmDataArgs = new String[vmData.size() * 2 + 4]; - vmDataArgs[0] = "routerIP"; - vmDataArgs[1] = routerPrivateIpAddress; - vmDataArgs[2] = "vmIP"; - vmDataArgs[3] = vmIpAddress; - int i = 4; - for (String[] vmDataEntry : vmData) { - String folder = vmDataEntry[0]; - String file = vmDataEntry[1]; - String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none"; + String json = new Gson().toJson(data); + s_logger.debug("VM data JSON IS:" + json); - vmDataArgs[i] = folder + "," + file; - vmDataArgs[i + 1] = contents; - i += 2; - } + json = Base64.encodeBase64String(json.getBytes()); - String content = encodeDataArgs(vmDataArgs); - String tmpFileName = UUID.randomUUID().toString(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content); - } + String args = "-d " + json; try { - SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null); - - try { - Pair result = - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/userdata.py " + tmpFileName); - - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); - } - } finally { - - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName); + Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args); + if (!result.first()) { + s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); + return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); } if (s_logger.isInfoEnabled()) { s_logger.info("vm_data command on domain router " + controlIp + " completed"); } - } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + e; + String msg = "VmDataCommand failed due to " + e.getMessage(); s_logger.error(msg, e); return new Answer(cmd, false, msg); } return new Answer(cmd); } - private String encodeDataArgs(String[] dataArgs) { - StringBuilder sb = new StringBuilder(); - - for (String arg : dataArgs) { - sb.append(arg); - sb.append("\n"); - } - - return sb.toString(); - } - protected Answer execute(DhcpEntryCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd)); @@ -1366,6 +1297,102 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new Answer(cmd); } + // + // find mac address of a specified ethx device + // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 + // returns + // eth0:xx.xx.xx.xx + + // + // list IP with eth devices + // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' + // | awk -F: '{ print $1 ": " $3 }' + // + // returns + // eth0:xx.xx.xx.xx + // + // + + private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { + + s_logger.info("findRouterEthDeviceIndex. mac: " + mac); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first()) { + String[] tokens = result.second().split("\\s+"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) + return Integer.parseInt(token.substring(3)); + } + } + } + + s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); + + } + + return -1; + } + + private Pair findRouterFreeEthDeviceIndex(String routerIp) throws Exception { + + s_logger.info("findRouterFreeEthDeviceIndex. mac: "); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ip address | grep DOWN| cut -f2 -d :"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first() && !result.second().isEmpty()) { + String[] tokens = result.second().split("\\n"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + //TODO: don't check for eth0,1,2, as they will be empty by default. + //String cmd = String.format("ip address show %s ", token); + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().length() > 0) + return new Pair(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ; + } + } + } + + //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry..."); + + } + + return new Pair(-1, ""); + } + protected Answer execute(IpAssocCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd)); @@ -1381,7 +1408,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S String controlIp = getRouterSshControlIp(cmd); for (IpAddressTO ip : ips) { assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress()); + ip.getVlanNetmask(), ip.getVifMacAddress()); results[i++] = ip.getPublicIp() + " - success"; } @@ -1399,16 +1426,97 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new IpAssocAnswer(cmd, results); } + protected int getVmNics(String vmName, int vlanid) { + GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName); + URI agentUri = null; + int nicposition = -1; + try { + String cmdName = GetVmConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]); + List nics = ans.getNics(); + for (NicDetails nic : nics) { + if (nic.getVlanid() == vlanid) { + nicposition = nics.indexOf(nic); + break; + } + } + } + return nicposition; + } + + protected void modifyNicVlan(String vmName, int vlanId, String macAddress) { + ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress); + URI agentUri = null; + try { + String cmdName = ModifyVmNicConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]); + } + } + protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + + URI broadcastUri = BroadcastDomainType.fromString(broadcastId); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); + } + int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri)); + + int publicNicInfo = -1; + publicNicInfo = getVmNics(vmName, vlanId); boolean addVif = false; - if (add) { + if (add && publicNicInfo == -1) { if (s_logger.isDebugEnabled()) { s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); } addVif = true; } else if (!add && firstIP) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo); + } + } + + if (addVif) { + Pair nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress); + publicNicInfo = nicdevice.first(); + if (publicNicInfo > 0) { + modifyNicVlan(vmName, vlanId, nicdevice.second()); + // After modifying the vnic on VR, check the VR VNics config in the host and get the device position + publicNicInfo = getVmNics(vmName, vlanId); + // As a new nic got activated in the VR. add the entry in the NIC's table. + networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo); + } + else { + // we didn't find any eth device available in VR to configure the ip range with new VLAN + String msg = "No Nic is available on DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } } String args = null; @@ -1430,8 +1538,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S args += publicIpAddress + "/" + cidrSize; args += " -c "; - args += "eth" + "2"; // currently hardcoding to eth 2 (which is default public ipd)//publicNicInfo.first(); + args += "eth" + publicNicInfo; args += " -g "; args += vlanGateway; @@ -1444,7 +1552,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } Pair result = - SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); + SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); if (!result.first()) { s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); @@ -1662,10 +1770,37 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S // comment to use Apache HttpClient // http://stackoverflow.com/a/2793153/939250, but final comment is to // use Apache. - s_logger.debug("POST request to" + agentUri.toString() + " with contents" + jsonCmd); + String logMessage = StringEscapeUtils.unescapeJava(jsonCmd); + logMessage = cleanPassword(logMessage); + s_logger.debug("POST request to " + agentUri.toString() + + " with contents " + logMessage); // Create request - HttpClient httpClient = new DefaultHttpClient(); + HttpClient httpClient = null; + TrustStrategy easyStrategy = new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + return true; + } + }; + + try { + SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier()); + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("https", DEFAULT_AGENT_PORT, sf)); + ClientConnectionManager ccm = new BasicClientConnectionManager(registry); + httpClient = new DefaultHttpClient(ccm); + } catch (KeyManagementException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (KeyStoreException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } + String result = null; // TODO: are there timeout settings and worker thread settings to tweak? @@ -1678,7 +1813,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S StringEntity cmdJson = new StringEntity(jsonCmd); request.addHeader("content-type", "application/json"); request.setEntity(cmdJson); - s_logger.debug("Sending cmd to " + agentUri.toString() + " cmd data:" + jsonCmd); + s_logger.debug("Sending cmd to " + agentUri.toString() + + " cmd data:" + logMessage); HttpResponse response = httpClient.execute(request); // Unsupported commands will not route. @@ -1695,7 +1831,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return null; } else { result = EntityUtils.toString(response.getEntity()); - s_logger.debug("POST response is" + result); + String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result)); + s_logger.debug("POST response is " + logResult); } } catch (ClientProtocolException protocolEx) { // Problem with HTTP message exchange @@ -1791,7 +1928,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S sch.connect(addr); return null; } catch (IOException e) { - s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString()); + s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString()); if (e instanceof ConnectException) { // if connection is refused because of VM is being started, // we give it more sleep time @@ -1821,4 +1958,22 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return "Unable to connect"; } + public static String cleanPassword(String logString) { + String cleanLogString = null; + if (logString != null) { + cleanLogString = logString; + String[] temp = logString.split(","); + int i = 0; + if (temp != null) { + while (i < temp.length) { + temp[i] = StringUtils.cleanString(temp[i]); + i++; + } + List stringList = new ArrayList(); + Collections.addAll(stringList, temp); + cleanLogString = StringUtils.join(stringList, ","); + } + } + return cleanLogString; + } } diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 81cc372116e..5eba1e08f83 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -67,7 +67,6 @@ org.apache.maven.plugins maven-dependency-plugin - 2.5.1 copy-dependencies @@ -85,7 +84,6 @@ org.apache.maven.plugins maven-surefire-plugin - 2.14 **/Qemu*.java diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 71c8e979bc5..fd0078c6970 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -16,73 +16,12 @@ // under the License. package com.cloud.hypervisor.kvm.resource; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; -import org.libvirt.Connect; -import org.libvirt.Domain; -import org.libvirt.DomainBlockStats; -import org.libvirt.DomainInfo; -import org.libvirt.DomainInterfaceStats; -import org.libvirt.DomainSnapshot; -import org.libvirt.LibvirtException; -import org.libvirt.NodeInfo; - import com.ceph.rados.IoCTX; import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; - -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -155,7 +94,6 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -174,14 +112,9 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; -import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; @@ -202,6 +135,7 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; @@ -251,17 +185,77 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; +import com.cloud.utils.script.OutputInterpreter.AllLinesParser; import com.cloud.utils.script.Script; +import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainBlockStats; +import org.libvirt.DomainInfo; +import org.libvirt.DomainInterfaceStats; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; +import org.libvirt.NodeInfo; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * LibvirtComputingResource execute requests on the computing/routing host using @@ -286,7 +280,7 @@ import com.cloud.vm.VirtualMachine.State; * pool | the parent of the storage pool hierarchy * } **/ @Local(value = {ServerResource.class}) -public class LibvirtComputingResource extends ServerResourceBase implements ServerResource { +public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); private String _modifyVlanPath; @@ -323,6 +317,59 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; + @Override + public ExecutionResult executeInVR(String routerIp, String script, String args) { + final Script command = new Script(_routerProxyPath, _timeout, s_logger); + final AllLinesParser parser = new AllLinesParser(); + command.add(script); + command.add(routerIp); + if (args != null) { + command.add(args); + } + String details = command.execute(parser); + if (details == null) { + details = parser.getLines(); + } + return new ExecutionResult(command.getExitValue() == 0, details); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { + File permKey = new File("/root/.ssh/id_rsa.cloud"); + String error = null; + + try { + SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); + } catch (Exception e) { + s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); + error = e.getMessage(); + } + return new ExecutionResult(error == null, error); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -377,6 +424,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private boolean _canBridgeFirewall; protected String _localStoragePath; protected String _localStorageUUID; + protected boolean _noMemBalloon = false; protected String _guestCpuMode; protected String _guestCpuModel; private final Map _pifs = new HashMap(); @@ -538,7 +586,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv params.put("domr.scripts.dir", domrScriptsDir); - _virtRouterResource = new VirtualRoutingResource(); + _virtRouterResource = new VirtualRoutingResource(this); success = _virtRouterResource.configure(name, params); if (!success) { @@ -724,6 +772,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv value = (String)params.get("cmds.timeout"); _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; + value = (String) params.get("vm.memballoon.disable"); + if (Boolean.parseBoolean(value)) { + _noMemBalloon = true; + } + value = (String)params.get("host.reserved.mem.mb"); _dom0MinMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024; @@ -1259,16 +1312,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((PlugNicCommand)cmd); } else if (cmd instanceof UnPlugNicCommand) { return execute((UnPlugNicCommand)cmd); - } else if (cmd instanceof SetupGuestNetworkCommand) { - return execute((SetupGuestNetworkCommand)cmd); - } else if (cmd instanceof SetNetworkACLCommand) { - return execute((SetNetworkACLCommand)cmd); - } else if (cmd instanceof SetSourceNatCommand) { - return execute((SetSourceNatCommand)cmd); - } else if (cmd instanceof IpAssocVpcCommand) { - return execute((IpAssocVpcCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest(cmd); } else if (cmd instanceof CheckSshCommand) { @@ -1291,8 +1334,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (cmd instanceof PvlanSetupCommand) { return execute((PvlanSetupCommand)cmd); - } else if (cmd instanceof SetMonitorServiceCommand) { - return execute((SetMonitorServiceCommand)cmd); } else if (cmd instanceof CheckOnHostCommand) { return execute((CheckOnHostCommand)cmd); } else if (cmd instanceof OvsFetchInterfaceCommand) { @@ -1980,25 +2021,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connect conn; NicTO nic = cmd.getNic(); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2013,75 +2039,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } if (routerNic == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); + return new ExecutionResult(false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); } - String dev = "eth" + nic.getDeviceId(); - String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); - String result = _virtRouterResource.assignGuestNetwork(dev, routerIP, routerGIP, gateway, cidr, netmask, dns, domainName); - - if (result != null) { - return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + return new ExecutionResult(true, null); } catch (LibvirtException e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - private Answer execute(SetMonitorServiceCommand cmd) { - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String config = cmd.getConfiguration(); - - String result = _virtRouterResource.configureMonitor(routerIp, config); - - if (result != null) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed"); - } - return new Answer(cmd); - - } - - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); - - try { - String[][] rules = cmd.generateFwRules(); - String[] aclRules = rules[0]; - NicTO nic = cmd.getNic(); - String dev = "eth" + nic.getDeviceId(); - String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - String rule = sb.toString(); - String result = _virtRouterResource.assignNetworkACL(routerIp, dev, nic.getIp(), netmask, rule, privateGw); - - if (result != null) { - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - - return new SetNetworkACLAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connect conn; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -2102,7 +2071,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /*skip over, no physical bridge device exists*/ } else if (pluggedVlanId == null) { /*this should only be true in the case of link local bridge*/ - return new SetSourceNatAnswer(cmd, false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + + return new ExecutionResult(false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + " on router " + routerName); } else if (pluggedVlanId.equals(pubVlan)) { break; @@ -2110,26 +2079,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv devNum++; } - String dev = "eth" + devNum; - String result = _virtRouterResource.assignSourceNat(routerIP, pubIP.getPublicIp(), dev); + pubIP.setNicDevId(devNum); - if (result != null) { - return new SetSourceNatAnswer(cmd, false, "KVM plugin \"vpc_snat\" failed:" + result); - } - return new SetSourceNatAnswer(cmd, true, "success"); + return new ExecutionResult(true, "success"); } catch (LibvirtException e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connect conn; - String[] results = new String[cmd.getIpAddresses().length]; int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2152,31 +2115,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } for (IpAddressTO ip : ips) { - String nicName = "eth" + broadcastUriToNicNum.get(ip.getBroadcastUri()); - String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - _virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(), nicName, ip.getVlanGateway(), netmask, subnet, ip.isSourceNat()); - results[i++] = ip.getPublicIp() + " - success"; + ip.setNicDevId(broadcastUriToNicNum.get(ip.getBroadcastUri())); } + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; - } catch (InternalErrorException e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); } - public Answer execute(IpAssocCommand cmd) { + public ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getIpAddresses().length]; - for (int i = 0; i < results.length; i++) { - results[i] = IpAssocAnswer.errorResult; - } Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2198,11 +2149,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv nicPos++; } IpAddressTO[] ips = cmd.getIpAddresses(); - int i = 0; - String result = null; int nicNum = 0; - boolean newNic = false; for (IpAddressTO ip : ips) { + boolean newNic = false; if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress()); @@ -2211,21 +2160,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri()); networkUsage(routerIp, "addVif", "eth" + nicNum); - result = - _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), nicNum, newNic); - if (result == null) { - results[i++] = ip.getPublicIp() + " - success"; - } + ip.setNicDevId(nicNum); + ip.setNewNic(newNic); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } catch (InternalErrorException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } } @@ -2988,10 +2933,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp() + "/system"); /* - * Hard code lm flags: VIR_MIGRATE_LIVE(1<<0) and - * VIR_MIGRATE_PERSIST_DEST(1<<3) + * Hard code lm flag: VIR_MIGRATE_LIVE(1<<0) */ - destDomain = dm.migrate(dconn, (1 << 0) | (1 << 3), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); + destDomain = dm.migrate(dconn, (1 << 0), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(cmd.getVirtualMachine()); } catch (LibvirtException e) { @@ -3159,8 +3103,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; @@ -3201,8 +3145,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; @@ -3488,7 +3432,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv GuestResourceDef grd = new GuestResourceDef(); - if (vmTO.getMinRam() != vmTO.getMaxRam()) { + if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { grd.setMemBalloning(true); grd.setCurrentMem(vmTO.getMinRam() / 1024); grd.setMemorySize(vmTO.getMaxRam() / 1024); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 9fd058fa3eb..5aeacdafae0 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -162,6 +162,8 @@ public class LibvirtVMDef { } if (_memBalloning) { resBuidler.append("\n" + "\n" + "\n"); + } else { + resBuidler.append("\n" + "\n" + "\n"); } if (_vcpu != -1) { resBuidler.append("" + _vcpu + "\n"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index fafbee08e36..bbd1c24ac99 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -386,7 +386,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), volumeUuid); + StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid); KVMPhysicalDisk disk; LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol); disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); @@ -471,7 +471,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String targetPath = pdef.getTargetPath(); if (targetPath != null && targetPath.equals(path)) { s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname + - ", undefining so we can re-define with correct name " + name); + ", undefining so we can re-define with correct name " + name); if (p.isPersistent() == 1) { p.destroy(); p.undefine(); @@ -527,8 +527,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String error = e.toString(); if (error.contains("Storage source conflict")) { throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " + - " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + - error); + " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + + error); } else { throw new CloudRuntimeException(error); } @@ -556,7 +556,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { /* * Some storage pools, like RBD also have 'secret' information stored in libvirt * Destroy them if they exist - */ + */ try { s = conn.secretLookupByUUIDString(uuid); } catch (LibvirtException e) { @@ -580,7 +580,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (e.toString().contains("exit status 16")) { String targetPath = _mountPoint + File.separator + uuid; s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble" + "unmounting the pool. Trying umount location " + targetPath + - "again in a few seconds"); + "again in a few seconds"); String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath); if (result == null) { s_logger.error("Succeeded in unmounting " + targetPath); @@ -624,7 +624,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { IoCTX io = r.ioCtxCreate(pool.getSourceDir()); Rbd rbd = new Rbd(io); - rbd.create(name, size, this.rbdFeatures, this.rbdOrder); + rbd.create(name, size, rbdFeatures, rbdOrder); r.ioCtxDestroy(io); } catch (RadosException e) { @@ -702,7 +702,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { Connect conn = LibvirtConnection.getConnection(); - StoragePool pool = conn.storagePoolLookupByUUIDString(poolUuid); + conn.storagePoolLookupByUUIDString(poolUuid); deleteStoragePool(poolUuid); @@ -753,7 +753,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), uuid); + StorageVol vol = getVolume(libvirtPool.getPool(), uuid); deleteVol(libvirtPool, vol); vol.free(); return true; @@ -784,7 +784,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { So for RBD we don't create the image, but let qemu-img do that for us. We then create a KVMPhysicalDisk object that we can return - */ + */ try { if (destPool.getType() != StoragePoolType.RBD) { disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize()); @@ -815,8 +815,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { QemuImg qemu = new QemuImg(timeout); QemuImgFile srcFile; QemuImgFile destFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), - destPool.getAuthSecret(), disk.getPath())); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), + destPool.getAuthSecret(), disk.getPath())); destFile.setFormat(format); if (srcPool.getType() != StoragePoolType.RBD) { @@ -850,9 +850,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (srcImage.isOldFormat()) { /* The source image is RBD format 1, we have to do a regular copy */ s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); + " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); - rbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage destImage = rbd.open(disk.getName()); s_logger.debug("Starting to copy " + srcImage.getName() + " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir()); @@ -862,10 +862,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { rbd.close(destImage); } else { s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 2. We will perform a RBD clone using snapshot " + this.rbdTemplateSnapName); + " is RBD format 2. We will perform a RBD clone using snapshot " + rbdTemplateSnapName); /* The source image is format 2, we can do a RBD snapshot+clone (layering) */ - rbd.clone(template.getName(), this.rbdTemplateSnapName, io, disk.getName(), this.rbdFeatures, this.rbdOrder); - s_logger.debug("Succesfully cloned " + template.getName() + "@" + this.rbdTemplateSnapName + " to " + disk.getName()); + rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder); + s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName()); } rbd.close(srcImage); @@ -893,14 +893,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd dRbd = new Rbd(dIO); s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " + - destPool.getSourceDir()); - dRbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + destPool.getSourceDir()); + dRbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage srcImage = sRbd.open(template.getName()); RbdImage destImage = dRbd.open(disk.getName()); s_logger.debug("Copying " + template.getName() + " from Ceph cluster " + rSrc.confGet("mon_host") + " to " + disk.getName() + " on cluster " + - rDest.confGet("mon_host")); + rDest.confGet("mon_host")); sRbd.copy(srcImage, destImage); sRbd.close(srcImage); @@ -923,7 +923,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } if (disk == null) { - throw new CloudRuntimeException("Failed to create " + disk.getPath() + " from template " + template.getName()); + throw new CloudRuntimeException("Failed to create disk from template " + template.getName()); } return disk; @@ -942,7 +942,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { String[] vols = virtPool.listVolumes(); for (String volName : vols) { - KVMPhysicalDisk disk = this.getPhysicalDisk(volName, pool); + KVMPhysicalDisk disk = getPhysicalDisk(volName, pool); disks.add(disk); } return disks; @@ -1036,11 +1036,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) { /** - * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first - * which we then convert to RBD format 2. - * - * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step - */ + * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first + * which we then convert to RBD format 2. + * + * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step + */ s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2"); String sourceFile; boolean useTmpFile = false; @@ -1069,7 +1069,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd rbd = new Rbd(io); s_logger.debug("Creating RBD image " + name + " in Ceph pool " + destPool.getSourceDir() + " with RBD format 2"); - rbd.create(name, disk.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(name, disk.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage image = rbd.open(name); @@ -1098,10 +1098,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } /* Snapshot the image and protect that snapshot so we can clone (layer) from it */ - s_logger.debug("Creating RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapCreate(this.rbdTemplateSnapName); - s_logger.debug("Protecting RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapProtect(this.rbdTemplateSnapName); + s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapCreate(rbdTemplateSnapName); + s_logger.debug("Protecting RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapProtect(rbdTemplateSnapName); rbd.close(image); r.ioCtxDestroy(io); @@ -1125,8 +1125,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { it doesn't benefit us. It's better to keep the current code in place which works */ srcFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), - sourcePath)); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), + sourcePath)); srcFile.setFormat(sourceFormat); destFile = new QemuImgFile(destPath); destFile.setFormat(destFormat); diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java new file mode 100644 index 00000000000..54036b3c848 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java @@ -0,0 +1,55 @@ +/* + * 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.hypervisor.kvm.resource; + +import junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef.usage; + +public class LibvirtSecretDefTest extends TestCase { + + public void testVolumeSecretDef() { + String uuid = "db66f42b-a79e-4666-9910-9dfc8a024427"; + String name = "myEncryptedQCOW2"; + usage use = usage.VOLUME; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setVolumeVolume(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + + public void testCephSecretDef() { + String uuid = "a9febe83-ac5c-467a-bf19-eb75325ec23c"; + String name = "admin"; + usage use = usage.CEPH; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setCephName(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java new file mode 100644 index 00000000000..687432b3d71 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java @@ -0,0 +1,84 @@ +/* + * 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.hypervisor.kvm.resource; + +import junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.poolType; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.authType; + +public class LibvirtStoragePoolDefTest extends TestCase { + + public void testSetGetStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "d7846cb0-f610-4a5b-8d38-ee6e8d63f37b"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + int port = 1234; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, targetPath); + + assertEquals(type, pool.getPoolType()); + assertEquals(name, pool.getPoolName()); + assertEquals(host, pool.getSourceHost()); + assertEquals(port, pool.getSourcePort()); + assertEquals(dir, pool.getSourceDir()); + assertEquals(targetPath, pool.getTargetPath()); + } + + public void testNfsStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "89a605bc-d470-4637-b3df-27388be452f5"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, dir, targetPath); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n\n\n\n" + + "" + targetPath + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } + + public void testRbdStoragePool() { + poolType type = poolType.RBD; + String name = "myRBDPool"; + String uuid = "921ef8b2-955a-4c18-a697-66bb9adf6131"; + String host = "127.0.0.1"; + String dir = "cloudstackrbdpool"; + String authUsername = "admin"; + String secretUuid = "08c2fa02-50d0-4a78-8903-b742d3f34934"; + authType auth = authType.CEPH; + int port = 6789; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, authUsername, auth, secretUuid); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n" + dir + "\n" + + "\n\n" + + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java index 90b8c3b7a2f..aa7570c3638 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java @@ -20,6 +20,7 @@ package com.cloud.hypervisor.kvm.resource; import junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; public class LibvirtVMDefTest extends TestCase { @@ -65,4 +66,28 @@ public class LibvirtVMDefTest extends TestCase { } + public void testDiskDef() { + String filePath = "/var/lib/libvirt/images/disk.qcow2"; + String diskLabel = "vda"; + + DiskDef disk = new DiskDef(); + DiskDef.diskBus bus = DiskDef.diskBus.VIRTIO; + DiskDef.diskFmtType type = DiskDef.diskFmtType.QCOW2; + DiskDef.diskCacheMode cacheMode = DiskDef.diskCacheMode.WRITEBACK; + + disk.defFileBasedDisk(filePath, diskLabel, bus, type); + disk.setCacheMode(cacheMode); + + assertEquals(filePath, disk.getDiskPath()); + assertEquals(diskLabel, disk.getDiskLabel()); + assertEquals(bus, disk.getBusType()); + assertEquals(DiskDef.deviceType.DISK, disk.getDeviceType()); + + String xmlDef = disk.toString(); + String expectedXml = "\n\n" + + "\n\n\n"; + + assertEquals(xmlDef, expectedXml); + } + } diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index 85f7e856f80..0eeef82c055 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -32,6 +32,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.user.AccountManager; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -87,6 +89,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage MockStorageManager _storageMgr = null; @Inject ResourceManager _resourceMgr; + @Inject private AccountManager _accountMgr; SimulatorSecondaryDiscoverer discoverer; @Inject @@ -303,8 +306,10 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage @Override @DB public void run() { + CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (this.mode.equalsIgnoreCase("Stop")) { handleSystemVMStop(); + CallContext.unregister(); return; } @@ -359,10 +364,12 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage _resourceMgr.discoverHosts(cmd); } catch (DiscoveryException e) { s_logger.debug("Failed to discover host: " + e.toString()); + CallContext.unregister(); return; } } catch (ConfigurationException e) { s_logger.debug("Failed to load secondary storage resource: " + e.toString()); + CallContext.unregister(); return; } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java index c31dab61712..93533bc6e61 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/LegacyZoneVO.java @@ -27,13 +27,15 @@ import javax.persistence.Table; import com.cloud.utils.NumbersUtil; /** -* LegacyZoneVO contains id of CloudStack zone containing clusters from multiple VMware vCetners and/or VMware Datacenters. -*/ + * LegacyZoneVO contains id of CloudStack zone containing clusters from multiple VMware vCetners and/or VMware Datacenters. + */ @Entity @Table(name = "legacy_zones") public class LegacyZoneVO implements LegacyZone { + private static final long serialVersionUID = -3979866054555152793L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -60,7 +62,7 @@ public class LegacyZoneVO implements LegacyZone { @Override public boolean equals(Object obj) { if (obj instanceof LegacyZoneVO) { - return ((LegacyZoneVO)obj).getId() == this.getId(); + return ((LegacyZoneVO)obj).getId() == getId(); } else { return false; } @@ -70,7 +72,7 @@ public class LegacyZoneVO implements LegacyZone { } public LegacyZoneVO(long zoneId) { - this.id = zoneId; + id = zoneId; } public LegacyZoneVO(long id, long zoneId) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java index b7746f945c0..d3b001ae9eb 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareCleanupMaid.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.hypervisor.vmware; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -98,16 +97,6 @@ public class VmwareCleanupMaid { return _checkPoint; } - private synchronized static void addLeftOverVM(VmwareCleanupMaid cleanupMaid) { - List l = s_leftoverDummyVMs.get(cleanupMaid.getVCenterServer()); - if (l == null) { - l = new ArrayList(); - s_leftoverDummyVMs.put(cleanupMaid.getVCenterServer(), l); - } - - l.add(cleanupMaid); - } - public synchronized static void gcLeftOverVMs(VmwareContext context) { List l = s_leftoverDummyVMs.get(context.getServerAddress()); VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java index 881b44fb074..86597b2e5c9 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java @@ -37,6 +37,8 @@ import com.cloud.utils.db.Encrypt; @Table(name = "vmware_data_center") public class VmwareDatacenterVO implements VmwareDatacenter { + private static final long serialVersionUID = -9114941929893819232L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -105,11 +107,11 @@ public class VmwareDatacenterVO implements VmwareDatacenter { } public void setVmwareDatacenterName(String name) { - this.vmwareDatacenterName = name; + vmwareDatacenterName = name; } public void setVcenterHost(String vCenterHost) { - this.vcenterHost = vCenterHost; + vcenterHost = vCenterHost; } public void setUser(String user) { @@ -134,17 +136,17 @@ public class VmwareDatacenterVO implements VmwareDatacenter { @Override public boolean equals(Object obj) { if (obj instanceof VmwareDatacenterVO) { - return ((VmwareDatacenterVO)obj).getId() == this.getId(); + return ((VmwareDatacenterVO)obj).getId() == getId(); } else { return false; } } public VmwareDatacenterVO(String guid, String name, String vCenterHost, String user, String password) { - this.uuid = UUID.randomUUID().toString(); - this.vmwareDatacenterName = name; + uuid = UUID.randomUUID().toString(); + vmwareDatacenterName = name; this.guid = guid; - this.vcenterHost = vCenterHost; + vcenterHost = vCenterHost; this.user = user; this.password = password; } @@ -155,7 +157,7 @@ public class VmwareDatacenterVO implements VmwareDatacenter { } public VmwareDatacenterVO() { - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java index ae9ccbf6f95..a8d88b40502 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java @@ -32,6 +32,8 @@ import javax.persistence.Table; @Table(name = "vmware_data_center_zone_map") public class VmwareDatacenterZoneMapVO implements VmwareDatacenterZoneMap { + private static final long serialVersionUID = -2155826205976479040L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index ad3620dd03f..e6ecbc9adbc 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -126,7 +126,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer @Override public Map> - find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { + find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { if (s_logger.isInfoEnabled()) s_logger.info("Discover host. dc: " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + url.getHost()); @@ -158,7 +158,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer if (usernameNotProvided || passwordNotProvided) { // Retrieve credentials associated with VMware DC s_logger.info("Username and/or Password not provided while adding cluster to cloudstack zone. " - + "Hence using both username & password provided while adding VMware DC to CloudStack zone."); + + "Hence using both username & password provided while adding VMware DC to CloudStack zone."); username = vmwareDc.getUser(); password = vmwareDc.getPassword(); clusterDetails.put("username", username); @@ -166,7 +166,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer _clusterDetailsDao.persist(clusterId, clusterDetails); } String updatedInventoryPath = validateCluster(url, vmwareDc); - if (url.getPath() != updatedInventoryPath) { + if (!url.getPath().equals(updatedInventoryPath)) { // If url from API doesn't specify DC then update url in database with DC associated with this zone. clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath); _clusterDetailsDao.persist(clusterId, clusterDetails); @@ -252,7 +252,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer // Process traffic label information provided at zone level and cluster level publicTrafficLabelObj = - getTrafficInfo(TrafficType.Public, publicTrafficLabel, defaultVirtualSwitchType, paramPublicVswitchType, paramPublicVswitchName, clusterId); + getTrafficInfo(TrafficType.Public, publicTrafficLabel, defaultVirtualSwitchType, paramPublicVswitchType, paramPublicVswitchName, clusterId); // Configuration Check: A physical network cannot be shared by different types of virtual switches. // @@ -272,7 +272,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer if (pNetworkListGuestTraffic.contains(pNetworkPublic)) { if (publicTrafficLabelObj.getVirtualSwitchType() != guestTrafficLabelObj.getVirtualSwitchType()) { String msg = - "Both public traffic and guest traffic is over same physical network " + pNetworkPublic + + "Both public traffic and guest traffic is over same physical network " + pNetworkPublic + ". And virtual switch type chosen for each traffic is different" + ". A physical network cannot be shared by different types of virtual switches."; s_logger.error(msg); @@ -295,7 +295,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer } Pair vsmInfo = new Pair(false, 0L); if (nexusDVS && (guestTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) || - ((zoneType == NetworkType.Advanced) && (publicTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch))) { + ((zoneType == NetworkType.Advanced) && (publicTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch))) { // Expect Cisco Nexus VSM details only if following 2 condition met // 1) The global config parameter vmware.use.nexus.vswitch // 2) Atleast 1 traffic type uses Nexus distributed virtual switch as backend. @@ -335,14 +335,14 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer context.registerStockObject("vsmcredentials", vsmCredentials); } } - List morHosts = _vmwareMgr.addHostToPodCluster(context, dcId, podId, clusterId, URLDecoder.decode(url.getPath())); + List morHosts = _vmwareMgr.addHostToPodCluster(context, dcId, podId, clusterId, URLDecoder.decode(url.getPath(), "UTF-8")); if (morHosts == null) s_logger.info("Found 0 hosts."); if (privateTrafficLabel != null) context.uregisterStockObject("privateTrafficLabel"); if (morHosts == null) { - s_logger.error("Unable to find host or cluster based on url: " + URLDecoder.decode(url.getPath())); + s_logger.error("Unable to find host or cluster based on url: " + URLDecoder.decode(url.getPath(), "UTF-8")); return null; } @@ -350,7 +350,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer clusterDetails = _clusterDetailsDao.findDetails(clusterId); if (clusterDetails.get("url") != null) { URI uriFromCluster = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url"))); - morCluster = context.getHostMorByPath(URLDecoder.decode(uriFromCluster.getPath())); + morCluster = context.getHostMorByPath(URLDecoder.decode(uriFromCluster.getPath(), "UTF-8")); if (morCluster == null || !morCluster.getType().equalsIgnoreCase("ClusterComputeResource")) { s_logger.warn("Cluster url does not point to a valid vSphere cluster, url: " + clusterDetails.get("url")); @@ -491,13 +491,13 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer if (!vCenterHost.equalsIgnoreCase(url.getHost())) { msg = - "This cluster " + clusterName + " belongs to vCenter " + url.getHost() + ". But this zone is associated with VMware DC from vCenter " + vCenterHost + + "This cluster " + clusterName + " belongs to vCenter " + url.getHost() + ". But this zone is associated with VMware DC from vCenter " + vCenterHost + ". Make sure the cluster being added belongs to vCenter " + vCenterHost + " and VMware DC " + vmwareDcNameFromDb; s_logger.error(msg); throw new DiscoveryException(msg); } else if (!vmwareDcNameFromDb.equalsIgnoreCase(vmwareDcNameFromApi)) { msg = - "This cluster " + clusterName + " belongs to VMware DC " + vmwareDcNameFromApi + " .But this zone is associated with VMware DC " + vmwareDcNameFromDb + + "This cluster " + clusterName + " belongs to VMware DC " + vmwareDcNameFromApi + " .But this zone is associated with VMware DC " + vmwareDcNameFromDb + ". Make sure the cluster being added belongs to VMware DC " + vmwareDcNameFromDb + " in vCenter " + vCenterHost; s_logger.error(msg); throw new DiscoveryException(msg); @@ -567,8 +567,8 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer if (tmplt == null) { id = _tmpltDao.getNextInSequence(Long.class, "id"); VMTemplateVO template = - VMTemplateVO.createPreHostIso(id, isoName, isoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64, Account.ACCOUNT_ID_SYSTEM, - null, "VMware Tools Installer ISO", false, 1, false, HypervisorType.VMware); + VMTemplateVO.createPreHostIso(id, isoName, isoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64, Account.ACCOUNT_ID_SYSTEM, + null, "VMware Tools Installer ISO", false, 1, false, HypervisorType.VMware); _tmpltDao.persist(template); } else { id = tmplt.getId(); @@ -627,7 +627,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer } private VmwareTrafficLabel getTrafficInfo(TrafficType trafficType, String zoneWideTrafficLabel, VirtualSwitchType defaultVirtualSwitchType, String vSwitchType, - String vSwitchName, Long clusterId) { + String vSwitchName, Long clusterId) { VmwareTrafficLabel trafficLabelObj = null; Map clusterDetails = null; try { @@ -664,7 +664,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer } private VmwareTrafficLabel getTrafficInfo(TrafficType trafficType, String zoneWideTrafficLabel, Map clusterDetails, - VirtualSwitchType defVirtualSwitchType) { + VirtualSwitchType defVirtualSwitchType) { VmwareTrafficLabel trafficLabelObj = null; try { trafficLabelObj = new VmwareTrafficLabel(zoneWideTrafficLabel, trafficType, defVirtualSwitchType); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java index a77679faa35..91a03ca6098 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java @@ -21,7 +21,6 @@ import java.util.List; import com.vmware.vim25.ManagedObjectReference; import com.cloud.agent.api.Command; -import com.cloud.hypervisor.vmware.mo.DatastoreMO; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -34,11 +33,9 @@ public interface VmwareHostService { String getWorkerName(VmwareContext context, Command cmd, int workerSequence); - ManagedObjectReference getVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber, String iqn, - String initiatorChapName, String initiatorChapSecret, String mutualChapName, String mutualChapSecret) throws Exception; - - void createVmdk(Command cmd, DatastoreMO dsMo, String volumeDatastorePath, Long volumeSize) throws Exception; - + ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName, + String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret, + String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception; void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception; void removeManagedTargetsFromCluster(List managedIqns) throws Exception; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 96f411e9559..482e8a626aa 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -40,7 +40,6 @@ import org.apache.log4j.Logger; import com.google.gson.Gson; import com.vmware.vim25.AboutInfo; -import com.vmware.vim25.HostConnectSpec; import com.vmware.vim25.ManagedObjectReference; import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; @@ -94,11 +93,9 @@ import com.cloud.hypervisor.vmware.mo.DiskControllerType; import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO; import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; -import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VmwareHostType; import com.cloud.hypervisor.vmware.resource.VmwareContextFactory; -import com.cloud.hypervisor.vmware.util.VmwareClient; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.network.CiscoNexusVSMDeviceVO; @@ -400,7 +397,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public List addHostToPodCluster(VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath) - throws Exception { + throws Exception { ManagedObjectReference mor = null; if (serviceContext != null) { mor = serviceContext.getHostMorByPath(hostInventoryPath); @@ -415,7 +412,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw List returnedHostList = new ArrayList(); if (mor.getType().equals("ComputeResource")) { - List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); + List hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (hosts != null && hosts.size() > 0); // For ESX host, we need to enable host firewall to allow VNC access @@ -425,7 +422,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw returnedHostList.add(hosts.get(0)); return returnedHostList; } else if (mor.getType().equals("ClusterComputeResource")) { - List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); + List hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (hosts != null); if (hosts.size() > 0) { @@ -462,45 +459,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return null; } - @Deprecated - private ManagedObjectReference - addHostToVCenterCluster(VmwareContext serviceContext, ManagedObjectReference morCluster, String host, String userName, String password) throws Exception { - - VmwareClient vclient = serviceContext.getVimClient(); - ManagedObjectReference morHost = vclient.getDecendentMoRef(morCluster, "HostSystem", host); - if (morHost == null) { - HostConnectSpec hostSpec = new HostConnectSpec(); - hostSpec.setUserName(userName); - hostSpec.setPassword(password); - hostSpec.setHostName(host); - hostSpec.setForce(true); // forcely take over the host - - ManagedObjectReference morTask = serviceContext.getService().addHostTask(morCluster, hostSpec, true, null, null); - boolean taskResult = vclient.waitForTask(morTask); - if (!taskResult) { - s_logger.error("Unable to add host " + host + " to vSphere cluster due to " + TaskMO.getTaskFailureInfo(serviceContext, morTask)); - throw new CloudRuntimeException("Unable to add host " + host + " to vSphere cluster due to " + taskResult); - } - serviceContext.waitForTaskProgressDone(morTask); - - // init morHost after it has been created - morHost = vclient.getDecendentMoRef(morCluster, "HostSystem", host); - if (morHost == null) { - throw new CloudRuntimeException( - "Successfully added host into vSphere but unable to find it later on?!. Please make sure you are either using IP address or full qualified domain name for host"); - } - } - - // For ESX host, we need to enable host firewall to allow VNC access - HostMO hostMo = new HostMO(serviceContext, morHost); - HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO(); - if (firewallMo != null) { - firewallMo.enableRuleset("vncServer"); - firewallMo.refreshFirewall(); - } - return morHost; - } - @Override public String getSecondaryStorageStoreUrl(long dcId) { @@ -579,7 +537,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return false; } - long startTick = Long.parseLong(tokens[0]); + Long.parseLong(tokens[0]); long msid = Long.parseLong(tokens[1]); long runid = Long.parseLong(tokens[2]); @@ -603,7 +561,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw s_logger.info("Worker VM expired, seconds elapsed: " + (System.currentTimeMillis() - startTick) / 1000); return true; } - */ + */ return false; } @@ -631,7 +589,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw _configServer.updateKeyPairs(); s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: " + srcIso.getAbsolutePath() + ", destination: " + - destIso.getAbsolutePath()); + destIso.getAbsolutePath()); try { FileUtil.copyfile(srcIso, destIso); } catch (IOException e) { @@ -1040,7 +998,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw if (vCenterHost == null) { throw new InvalidParameterValueException("Missing or invalid parameter name. " - + "Please provide valid VMware vCenter server's IP address or fully qualified domain name."); + + "Please provide valid VMware vCenter server's IP address or fully qualified domain name."); } if (zoneId == null) { @@ -1060,11 +1018,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw VmwareDatacenterVO associatedVmwareDc = _vmwareDcDao.findById(associatedVmwareDcId); if (associatedVmwareDc.getVcenterHost().equalsIgnoreCase(vCenterHost) && associatedVmwareDc.getVmwareDatacenterName().equalsIgnoreCase(vmwareDcName)) { s_logger.info("Ignoring API call addVmwareDc, because VMware DC " + vCenterHost + "/" + vmwareDcName + - " is already associated with specified zone with id " + zoneId); + " is already associated with specified zone with id " + zoneId); return associatedVmwareDc; } else { throw new CloudRuntimeException("Zone " + zoneId + " is already associated with a VMware datacenter. " + - "Only 1 VMware DC can be associated with a zone."); + "Only 1 VMware DC can be associated with a zone."); } } // Zone validation to check if the zone already has resources. @@ -1158,8 +1116,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw String userName; String password; DatacenterMO dcMo = null; - Transaction txn; - final VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId); // Check if zone is associated with VMware DC if (vmwareDcZoneMap == null) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index a7089cedda2..e37bf38a5af 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -198,9 +198,6 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { String installPath = volume.getPath(); int index = installPath.lastIndexOf(File.separator); String volumeUuid = installPath.substring(index + 1); - String details = null; - boolean success = false; - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); //The real volume path String volumePath = installPath + File.separator + volumeUuid + ".ova"; @@ -351,8 +348,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } snapshotBackupUuid = - backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, - hostService.getWorkerName(context, cmd, 1)); + backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, + hostService.getWorkerName(context, cmd, 1)); success = (snapshotBackupUuid != null); if (success) { @@ -407,7 +404,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (vmMo == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + - ", try within datacenter"); + ", try within datacenter"); } vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); @@ -419,8 +416,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } Ternary result = - createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath, - hostService.getWorkerName(context, cmd, 0)); + createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath, + hostService.getWorkerName(context, cmd, 0)); return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), cmd.getUniqueName(), ImageFormat.OVA); @@ -477,8 +474,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { Pair result; if (cmd.toSecondaryStorage()) { result = - copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL, - hostService.getWorkerName(context, cmd, 0)); + copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL, + hostService.getWorkerName(context, cmd, 0)); } else { StorageFilerTO poolTO = cmd.getPool(); @@ -549,10 +546,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // templateName: name in secondary storage // templateUuid: will be used at hypervisor layer private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, - String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { + String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + - templatePathAtSecondaryStorage + ", templateName: " + templateName); + templatePathAtSecondaryStorage + ", templateName: " + templateName); String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl); s_logger.info("Secondary storage mount point: " + secondaryMountPoint); @@ -587,7 +584,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); if (vmMo == null) { String msg = - "Failed to import OVA template. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + + "Failed to import OVA template. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + ", templateName: " + templateName + ", templateUuid: " + templateUuid; s_logger.error(msg); throw new Exception(msg); @@ -605,7 +602,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, String secStorageUrl, - String volumePath, String workerVmName) throws Exception { + String volumePath, String workerVmName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); @@ -670,7 +667,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Ternary createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, String secStorageUrl, long volumeId, - String backedUpSnapshotUuid) throws Exception { + String backedUpSnapshotUuid) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); @@ -854,14 +851,14 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, long accountId, long volumeId, - String secStorageUrl, String snapshotBackupUuid) throws Exception { + String secStorageUrl, String snapshotBackupUuid) throws Exception { restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid); return null; } private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir, - String backupName) throws Exception { + String backupName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension(); @@ -921,7 +918,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, long accountId, long volumeId, String volumePath, String snapshotUuid, String secStorageUrl, - String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { String backupUuid = UUID.randomUUID().toString(); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName); @@ -929,7 +926,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName, - String workerVmName) throws Exception { + String workerVmName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; @@ -973,40 +970,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } } - private String deleteSnapshotOnSecondaryStorge(long accountId, long volumeId, String secStorageUrl, String backupUuid) throws Exception { - - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); - String snapshotMountRoot = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId); - File file = new File(snapshotMountRoot + "/" + backupUuid + ".ovf"); - if (file.exists()) { - File snapshotdir = new File(snapshotMountRoot); - File[] ssfiles = snapshotdir.listFiles(); - // List filenames = new ArrayList(); - for (int i = 0; i < ssfiles.length; i++) { - String vmdkfile = ssfiles[i].getName(); - if (vmdkfile.toLowerCase().startsWith(backupUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) { - // filenames.add(vmdkfile); - new File(vmdkfile).delete(); - } - } - if (file.delete()) { - return null; - } - } else { - File file1 = new File(snapshotMountRoot + "/" + backupUuid + ".ova"); - if (file1.exists()) { - if (file1.delete()) { - return null; - } - } else { - return "Backup file does not exist. backupUuid: " + backupUuid; - } - } - return "Failed to delete snapshot backup file, backupUuid: " + backupUuid; - } - private Pair copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd, String vmName, - long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName) throws Exception { + long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName) throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; VirtualMachineMO workerVm = null; @@ -1043,7 +1008,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, - hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); + hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); return new Pair(volumeFolder, exportName); } finally { @@ -1066,7 +1031,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName) - throws Exception { + throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; String newVolume = UUID.randomUUID().toString().replaceAll("-", ""); @@ -1085,69 +1050,54 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { s_logger.info("getOVAfromMetaFile: " + metafileName); try { strm = new FileInputStream(ova_metafile); - if (null == strm) { - String msg = "Cannot read ova meta file."; + + s_logger.info("loading properties from ova meta file: " + metafileName); + props = new Properties(); + props.load(strm); + ovaFileName = props.getProperty("ova.filename"); + s_logger.info("ovafilename: " + ovaFileName); + String ovfFileName = props.getProperty("ovf"); + s_logger.info("ovffilename: " + ovfFileName); + int diskNum = Integer.parseInt(props.getProperty("numDisks")); + if (diskNum <= 0) { + String msg = "VMDK disk file number is 0. Error"; s_logger.error(msg); throw new Exception(msg); } - - s_logger.info("loading properties from ova meta file: " + metafileName); - if (null != ova_metafile) { - props = new Properties(); - props.load(strm); - if (props == null) { - s_logger.info("getOVAfromMetaFile: props is null. "); - } + String[] disks = new String[diskNum]; + for (int i = 0; i < diskNum; i++) { + // String diskNameKey = "disk" + Integer.toString(i+1) + ".name"; // Fang use this + String diskNameKey = "disk1.name"; + disks[i] = props.getProperty(diskNameKey); + s_logger.info("diskname " + disks[i]); } - if (null != props) { - ovaFileName = props.getProperty("ova.filename"); - s_logger.info("ovafilename: " + ovaFileName); - String ovfFileName = props.getProperty("ovf"); - s_logger.info("ovffilename: " + ovfFileName); - int diskNum = Integer.parseInt(props.getProperty("numDisks")); - if (diskNum <= 0) { - String msg = "VMDK disk file number is 0. Error"; - s_logger.error(msg); - throw new Exception(msg); - } - String[] disks = new String[diskNum]; - for (int i = 0; i < diskNum; i++) { - // String diskNameKey = "disk" + Integer.toString(i+1) + ".name"; // Fang use this - String diskNameKey = "disk1.name"; - disks[i] = props.getProperty(diskNameKey); - s_logger.info("diskname " + disks[i]); - } - String exportDir = ova_metafile.getParent(); - s_logger.info("exportDir: " + exportDir); - // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature) - s_logger.info("Sync file system before we package OVA..., before tar "); - s_logger.info("ova: " + ovaFileName + ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + "."); - Script commandSync = new Script(true, "sync", 0, s_logger); - commandSync.execute(); - Script command = new Script(false, "tar", 0, s_logger); - command.setWorkDir(exportDir); // Fang: pass this in to the method? - command.add("-cf", ovaFileName); - command.add(ovfFileName); // OVF file should be the first file in OVA archive - for (String diskName : disks) { - command.add(diskName); - } - command.execute(); - s_logger.info("Package OVA for template in dir: " + exportDir + "cmd: " + command.toString()); - // to be safe, physically test existence of the target OVA file - if ((new File(exportDir + ovaFileName)).exists()) { - s_logger.info("ova file is created and ready to extract "); - return (ovaFileName); - } else { - String msg = exportDir + File.separator + ovaFileName + ".ova is not created as expected"; - s_logger.error(msg); - throw new Exception(msg); - } + String exportDir = ova_metafile.getParent(); + s_logger.info("exportDir: " + exportDir); + // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature) + s_logger.info("Sync file system before we package OVA..., before tar "); + s_logger.info("ova: " + ovaFileName + ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + "."); + Script commandSync = new Script(true, "sync", 0, s_logger); + commandSync.execute(); + Script command = new Script(false, "tar", 0, s_logger); + command.setWorkDir(exportDir); // Fang: pass this in to the method? + command.add("-cf", ovaFileName); + command.add(ovfFileName); // OVF file should be the first file in OVA archive + for (String diskName : disks) { + command.add(diskName); + } + command.execute(); + s_logger.info("Package OVA for template in dir: " + exportDir + "cmd: " + command.toString()); + // to be safe, physically test existence of the target OVA file + if ((new File(exportDir + ovaFileName)).exists()) { + s_logger.info("ova file is created and ready to extract "); + return (ovaFileName); } else { - String msg = "Error reading the ova meta file: " + metafileName; + String msg = exportDir + File.separator + ovaFileName + ".ova is not created as expected"; s_logger.error(msg); throw new Exception(msg); } } catch (Exception e) { + s_logger.error("Exception in getOVAFromMetafile", e); return null; // Do something, re-throw the exception } finally { @@ -1252,7 +1202,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // wait if there are already VM snapshot task running ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager(); - List tasks = (ArrayList)context.getVimClient().getDynamicProperty(taskmgr, "recentTask"); + List tasks = context.getVimClient().getDynamicProperty(taskmgr, "recentTask"); for (ManagedObjectReference taskMor : tasks) { TaskInfo info = (TaskInfo)(context.getVimClient().getDynamicProperty(taskMor, "info")); @@ -1465,7 +1415,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // wait if there are already VM revert task running ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager(); - List tasks = (ArrayList)context.getVimClient().getDynamicProperty(taskmgr, "recentTask"); + List tasks = context.getVimClient().getDynamicProperty(taskmgr, "recentTask"); for (ManagedObjectReference taskMor : tasks) { TaskInfo info = (TaskInfo)(context.getVimClient().getDynamicProperty(taskMor, "info")); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 8b252763e78..407327592bc 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -60,7 +60,6 @@ import com.vmware.vim25.DistributedVirtualPort; import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DistributedVirtualSwitchPortCriteria; import com.vmware.vim25.DynamicProperty; -import com.vmware.vim25.GuestInfo; import com.vmware.vim25.HostCapability; import com.vmware.vim25.HostHostBusAdapter; import com.vmware.vim25.HostInternetScsiHba; @@ -115,17 +114,12 @@ import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; @@ -139,8 +133,6 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -186,7 +178,6 @@ import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -206,35 +197,11 @@ import com.cloud.agent.api.ValidateSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; @@ -248,20 +215,19 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.configuration.Config; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Vlan; +import com.cloud.exception.CloudException; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -292,13 +258,10 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareGuestOsMapper; import com.cloud.hypervisor.vmware.util.VmwareHelper; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.VmwareTrafficLabel; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Storage; @@ -311,9 +274,11 @@ import com.cloud.storage.resource.VmwareStorageProcessor; import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.DateUtil; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; +import com.cloud.utils.Ternary; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionUtil; @@ -328,7 +293,7 @@ import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VmDetailConstants; -public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { +public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); protected String _name; @@ -377,6 +342,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected StorageSubsystemCommandHandler storageHandler; + protected VirtualRoutingResource _vrResource; + protected static HashMap s_powerStatesTable; static { s_powerStatesTable = new HashMap(); @@ -426,26 +393,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa Class clz = cmd.getClass(); if (clz == CreateCommand.class) { answer = execute((CreateCommand)cmd); - } else if (clz == SetPortForwardingRulesCommand.class) { - answer = execute((SetPortForwardingRulesCommand)cmd); - } else if (clz == SetStaticNatRulesCommand.class) { - answer = execute((SetStaticNatRulesCommand)cmd); - } else if (clz == LoadBalancerConfigCommand.class) { - answer = execute((LoadBalancerConfigCommand)cmd); - } else if (clz == IpAssocCommand.class) { - answer = execute((IpAssocCommand)cmd); - } else if (clz == SavePasswordCommand.class) { - answer = execute((SavePasswordCommand)cmd); - } else if (clz == DhcpEntryCommand.class) { - answer = execute((DhcpEntryCommand)cmd); - } else if (clz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clz == VmDataCommand.class) { - answer = execute((VmDataCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clz == ReadyCommand.class) { answer = execute((ReadyCommand)cmd); } else if (clz == GetHostStatsCommand.class) { @@ -522,62 +471,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((NetworkUsageCommand)cmd); } else if (clz == StartCommand.class) { answer = execute((StartCommand)cmd); - } else if (clz == RemoteAccessVpnCfgCommand.class) { - answer = execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clz == VpnUsersCfgCommand.class) { - answer = execute((VpnUsersCfgCommand)cmd); } else if (clz == CheckSshCommand.class) { answer = execute((CheckSshCommand)cmd); - } else if (clz == CheckRouterCommand.class) { - answer = execute((CheckRouterCommand)cmd); - } else if (clz == SetFirewallRulesCommand.class) { - answer = execute((SetFirewallRulesCommand)cmd); - } else if (clz == BumpUpPriorityCommand.class) { - answer = execute((BumpUpPriorityCommand)cmd); - } else if (clz == GetDomRVersionCmd.class) { - answer = execute((GetDomRVersionCmd)cmd); } else if (clz == CheckNetworkCommand.class) { answer = execute((CheckNetworkCommand)cmd); - } else if (clz == SetupGuestNetworkCommand.class) { - answer = execute((SetupGuestNetworkCommand)cmd); - } else if (clz == IpAssocVpcCommand.class) { - answer = execute((IpAssocVpcCommand)cmd); } else if (clz == PlugNicCommand.class) { answer = execute((PlugNicCommand)cmd); } else if (clz == UnPlugNicCommand.class) { answer = execute((UnPlugNicCommand)cmd); - } else if (clz == SetSourceNatCommand.class) { - answer = execute((SetSourceNatCommand)cmd); - } else if (clz == SetNetworkACLCommand.class) { - answer = execute((SetNetworkACLCommand)cmd); } else if (cmd instanceof CreateVMSnapshotCommand) { return execute((CreateVMSnapshotCommand)cmd); } else if (cmd instanceof DeleteVMSnapshotCommand) { return execute((DeleteVMSnapshotCommand)cmd); } else if (cmd instanceof RevertToVMSnapshotCommand) { return execute((RevertToVMSnapshotCommand)cmd); - } else if (clz == SetPortForwardingRulesVpcCommand.class) { - answer = execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clz == Site2SiteVpnCfgCommand.class) { - answer = execute((Site2SiteVpnCfgCommand)cmd); - } else if (clz == CheckS2SVpnConnectionsCommand.class) { - answer = execute((CheckS2SVpnConnectionsCommand)cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand)cmd); } else if (clz == UnregisterVMCommand.class) { - return execute((UnregisterVMCommand)cmd); + return execute((UnregisterVMCommand) cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clz == SetStaticRouteCommand.class) { - answer = execute((SetStaticRouteCommand)cmd); } else if (clz == UnregisterNicCommand.class) { answer = execute((UnregisterNicCommand)cmd); - } else if (clz == SetMonitorServiceCommand.class) { - answer = execute((SetMonitorServiceCommand)cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -600,7 +519,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _cmdMBeans.remove(0); JmxUtil.unregisterMBean("VMware " + _morHyperHost.getValue(), - "Command " + mbeanToRemove.getProp("Sequence") + "-" + mbeanToRemove.getProp("Name")); + "Command " + mbeanToRemove.getProp("Sequence") + "-" + mbeanToRemove.getProp("Name")); } } catch (Exception e) { if (s_logger.isTraceEnabled()) @@ -693,52 +612,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return answer; } - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetStaticRouteCommand: " + _gson.toJson(cmd)); - } - - boolean endResult = true; - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getStaticRoutes().length]; - int i = 0; - - // Extract and build the arguments for the command to be sent to the VR. - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int j = 0; j < srRules.length; j++) { - sb.append(srRules[j]).append(','); - } - args += " -a " + sb.toString(); - - // Send over the command for execution, via ssh, to the VR. - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticroute.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticroute.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetStaticRouteCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - return new SetStaticRouteAnswer(cmd, endResult, results); - - } - protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { String privateIp = cmd.getPrivateIP(); String option = cmd.getOption(); @@ -760,499 +633,72 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/vpc_netusage.sh " + args + " on DomR " + privateIp); + + ExecutionResult callResult = executeInVR(privateIp, "vpc_netusage.sh", args); + + if (!callResult.isSuccess()) { + s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + callResult.getDetails()); + } + + if (option.equals("get") || option.equals("vpn")) { + String result = callResult.getDetails(); + if (result == null || result.isEmpty()) { + s_logger.error(" vpc network usage get returns empty "); } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair resultPair = - SshHelper.sshExecute(privateIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_netusage.sh " + args); - - if (!resultPair.first()) { - throw new Exception(" vpc network usage plugin call failed "); - - } - - if (option.equals("get") || option.equals("vpn")) { - String result = resultPair.second(); - if (result == null || result.isEmpty()) { - throw new Exception(" vpc network usage get returns empty "); - } - long[] stats = new long[2]; - if (result != null) { - String[] splitResult = result.split(":"); - int i = 0; - while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); - } - return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); + long[] stats = new long[2]; + if (result != null) { + String[] splitResult = result.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += (new Long(splitResult[i++])).longValue(); + stats[1] += (new Long(splitResult[i++])).longValue(); } + return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); } - return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } catch (Throwable e) { - - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e); } return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - protected Answer execute(SetMonitorServiceCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetMonitorServiceCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String config = cmd.getConfiguration(); - - String args = ""; - - args += " -c " + config; - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/monitor_service.sh " + args); - - if (!result.first()) { - String msg = "monitor_service.sh failed on domain router " + controlIp + " failed " + result.second(); - s_logger.error(msg); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "SetMonitorServiceCommand failed due to " + VmwareHelper.getExceptionMessage(e)); - } - } - - protected Answer execute(SetPortForwardingRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - args += rule.revoked() ? " -D " : " -A "; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange(); - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/firewall.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args); - - if (!result.first()) { - s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetPortForwardingRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - - String[][] rules = cmd.generateFwRules(); - String args = ""; - args += " -F "; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E "; - if (egressDefault.equals("true")) { - args += " -P 1 "; - } else if (egressDefault.equals("System")) { - args += " -P 2 "; - } else { - args += " -P 0 "; - } - } - - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = null; - - if (trafficType == FirewallRule.TrafficType.Egress) { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/firewallRule_egress.sh " + args); - } else { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/firewall_rule.sh " + args); - } - - if (s_logger.isDebugEnabled()) { - if (trafficType == FirewallRule.TrafficType.Egress) { - s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewallRule_egress.sh " + args); - } else { - s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall_rule.sh " + args); - } - } - - if (!result.first()) { - s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - - return new SetFirewallRulesAnswer(cmd, false, results); - } - } catch (Throwable e) { - s_logger.error("SetFirewallRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetFirewallRulesAnswer(cmd, false, results); - } - - return new SetFirewallRulesAnswer(cmd, true, results); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetVPCStaticNatRulesCommand: " + _gson.toJson(cmd)); - } - - String[] results = new String[cmd.getRules().length]; - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - // Prepare command to be send to VPC VR - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - // Invoke command on VPC VR. - try { - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticnat.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticnat.sh " + args); - - if (!result.first()) { - s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetVPCStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(SetStaticNatRulesCommand cmd) { - - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd)); - } - - String args = null; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - // 1:1 NAT needs instanceip;publicip;domrip;op - args = rule.revoked() ? " -D " : " -A "; - - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - if (rule.getProtocol() != null) { - args += " -P " + rule.getProtocol().toLowerCase(); - } - - args += " -d " + rule.getStringSrcPortRange(); - args += " -G "; - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/firewall.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /root/firewall.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; - endResult = false; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) { + @Override + public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); File keyFile = mgr.getSystemVMKeyFile(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - - String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } + boolean result = true; try { - SshHelper.scpTo(controlIp, DefaultDomRSshPort, "root", keyFile, null, "/etc/haproxy/", tmpCfgFileContents.getBytes(), "haproxy.cfg.new", null); - - try { - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - String ip = cmd.getNic().getIp(); - args += " -i " + ip; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - // Invoke the command - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_loadbalancer.sh " + args); - - if (!result.first()) { - String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new Answer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("VPCLoadBalancerConfigCommand on domain router " + routerIp + " completed"); - } - } finally { - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "rm " + tmpCfgFilePath); - } - return new Answer(cmd); - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "VPCLoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e)); + SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(), fileName, null); + } catch (Exception e) { + s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e); + return new ExecutionResult(false, e.getMessage()); } + return new ExecutionResult(true, null); } - protected Answer execute(final LoadBalancerConfigCommand cmd) { + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(getRouterSshControlIp(cmd)); + assert cmd.getRouterAccessIp() != null; - if (cmd.getVpcId() != null) { - return VPCLoadBalancerConfig(cmd); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - File keyFile = mgr.getSystemVMKeyFile(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - - String[][] rules = cfgtr.generateFwRules(cmd); - String tmpCfgFilePath = "/tmp/" + routerIp.replace('.', '_') + ".cfg"; - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } - - try { - SshHelper.scpTo(controlIp, DefaultDomRSshPort, "root", keyFile, null, "/tmp/", tmpCfgFileContents.getBytes(), routerIp.replace('.', '_') + ".cfg", null); - - try { - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - args += "-i " + routerIp; - args += " -f " + tmpCfgFilePath; - - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "scp " + tmpCfgFilePath + - " /etc/haproxy/haproxy.cfg.new"); - - if (!result.first()) { - s_logger.error("Unable to copy haproxy configuration file"); - return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to uanble to copy haproxy configuration file"); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + routerIp + ", /root/loadbalancer.sh " + args); - } - - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/loadbalancer.sh " + args); - - if (!result.first()) { - String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new Answer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed"); - } - } finally { - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "rm " + tmpCfgFilePath); - } - - return new Answer(cmd); - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e)); + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); } + return new ExecutionResult(true, null); } - // - // list available ethx devices - // ls /proc/sys/net/ipv4/conf - // - private int allocRouterEthDeviceIndex(String domrName, String routerIp) throws Exception { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "ls /proc/sys/net/ipv4/conf"); - - if (result.first()) { - String[] tokens = result.second().split("\\s+"); - HashMap deviceNames = new HashMap(); - for (String token : tokens) { - if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { - deviceNames.put(token, token); - } - } - - for (int i = 1;; i++) { - if (!deviceNames.containsKey("eth" + i)) - return i; - } - } - - return -1; + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); } - // - // find mac address of a specified ethx device - // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 - // returns - // eth0:xx.xx.xx.xx - // // list IP with eth devices // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' @@ -1283,8 +729,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (s_logger.isDebugEnabled()) s_logger.debug("Run domr script " + cmd); Pair result2 = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, - // TODO need to find the dev index inside router based on IP address - cmd); + // TODO need to find the dev index inside router based on IP address + cmd); if (s_logger.isDebugEnabled()) s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); @@ -1318,77 +764,26 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return null; } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { - - s_logger.info("Executing resource SetupGuestNetworkCommand " + _gson.toJson(cmd)); - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { NicTO nic = cmd.getNic(); - String routerIp = getRouterSshControlIp(cmd); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); - String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } + String domrName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac()); - s_logger.info("find interface index. routerIp: " + routerIp + ", mac: " + nic.getMac() + ", index: " + ethDeviceNum); - - String args = (cmd.isAdd() ? "-C" : "-D"); - String dev = "eth" + ethDeviceNum; - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_guestnw.sh " + args); - - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetupGuestNetworkAnswer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("SetupGuestNetworkCommand on domain router " + routerIp + " completed"); - } - - return new SetupGuestNetworkAnswer(cmd, true, "success"); + int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetupGuestNetwork failed due to " + e.toString(); + String msg = "Prepare SetupGuestNetwork failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IpAssocVpcCommand " + _gson.toJson(cmd)); - } - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; + private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); @@ -1396,229 +791,58 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + continue; + } + } + + ip.setNicDevId(ethDeviceNum); } } catch (Exception e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.toString()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetSourceNatCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); IpAddressTO pubIp = cmd.getIpAddress(); + try { int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); - String args = ""; - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_snat.sh " + args); - - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetSourceNatAnswer(cmd, false, msg); - } - - return new SetSourceNatAnswer(cmd, true, "success"); + pubIp.setNicDevId(ethDeviceNum); } catch (Exception e) { - String msg = "Ip SNAT failure due to " + e.toString(); + String msg = "Prepare Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, e.toString()); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetNetworkACLCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { + NicTO nic = cmd.getNic(); + String routerName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; try { - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - if (aclRules.length == 0) { - return new SetNetworkACLAnswer(cmd, true, results); - } - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - NicTO nic = cmd.getNic(); - int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); - String args = ""; - Pair result; - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - args += " -d " + "eth" + ethDeviceNum; - args += " -a " + sb.toString(); - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privategw_acl.sh " + args); - - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - args = ""; - args += " -d " + "eth" + ethDeviceNum; - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_acl.sh " + args); - - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - return new SetNetworkACLAnswer(cmd, true, results); + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); + return new ExecutionResult(false, msg); } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesVpcCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - try { - Pair sshResult = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_portforwarding.sh " + args); - - if (!sshResult.first()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Exception e) { - results[i++] = "Failed"; - endResult = false; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource Site2SiteVpnCfgCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String args = ""; - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - - Pair result; - try { - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipsectunnel.sh " + args); - - if (!result.first()) { - s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "Setup site2site VPN falied due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, "Setup site2site VPN failed due to " + VmwareHelper.getExceptionMessage(e)); - } - return new Answer(cmd, true, result.second()); + return new ExecutionResult(true, null); } private PlugNicAnswer execute(PlugNicCommand cmd) { @@ -1653,7 +877,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.debug(errMsg); return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + errMsg); } - */ + */ // TODO need a way to specify the control of NIC device type VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.E1000; @@ -1677,13 +901,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid); nic = - VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), deviceNumber, - deviceNumber + 1, true, true); + VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), deviceNumber, + deviceNumber + 1, true, true); } else { s_logger.info("Preparing NIC device on network " + networkInfo.second()); nic = - VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), deviceNumber, deviceNumber + 1, true, - true); + VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), deviceNumber, deviceNumber + 1, true, + true); } VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); @@ -1735,7 +959,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.debug(errMsg); return new UnPlugNicAnswer(cmd, false, "Unable to execute unPlugNicCommand due to " + errMsg); } - */ + */ VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac()); if (nic == null) { return new UnPlugNicAnswer(cmd, true, "success"); @@ -1758,185 +982,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected void assignVPCPublicIpAddress(String domrName, String routerIp, IpAddressTO ip) throws Exception { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource assignVPCPublicIpAddress. domrName: " + domrName + ", routerIp: " + routerIp + ", ip: " + _gson.toJson(ip)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); - if (ethDeviceNum < 0) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_ipassoc.sh " + args); - - if (!result.first()) { - throw new InternalErrorException("Unable to assign public IP address"); - } - - if (ip.isSourceNat()) { - snatArgs += " -l "; - snatArgs += ip.getPublicIp(); - snatArgs += " -c "; - snatArgs += "eth" + ethDeviceNum; - - Pair result_gateway = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privateGateway.sh " + snatArgs); - - if (!result_gateway.first()) { - throw new InternalErrorException("Unable to configure source NAT for public IP address."); - } - } - } - - protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, - final boolean firstIP, final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) - throws Exception { - - /** - * TODO support other networks - */ - URI broadcastUri = BroadcastDomainType.fromString(broadcastId); - if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { - throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); - } - String vlanId = BroadcastDomainType.getValue(broadcastUri); - - String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); - Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); - } - - boolean addVif = false; - boolean removeVif = false; - if (add && publicNicInfo.first().intValue() == -1) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); - } - - addVif = true; - } else if (!add && firstIP) { - removeVif = true; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unplug NIC " + publicNicInfo.first()); - } - } - - if (addVif) { - plugPublicNic(vmMo, vlanId, vifMacAddress); - publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - if (publicNicInfo.first().intValue() >= 0) { - networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo.first()); - } - } - - if (publicNicInfo.first().intValue() < 0) { - String msg = "Failed to find DomR VIF to associate/disassociate IP with."; - s_logger.error(msg); - throw new InternalErrorException(msg); - } - - String args = null; - - if (add) { - args = " -A "; - } else { - args = " -D "; - } - - if (sourceNat) { - args += " -s "; - } - if (firstIP) { - args += " -f "; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + publicNicInfo.first(); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - args += " -n "; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + privateIpAddress + ", /opt/cloud/bin/ipassoc.sh " + args); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); - - if (!result.first()) { - s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); - throw new Exception("ipassoc failed due to " + result.second()); - } - - if (removeVif) { - - String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); - int nicMasks = Integer.parseInt(nicMasksStr); - nicMasks &= ~(1 << publicNicInfo.first().intValue()); - vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); - - HostMO hostMo = vmMo.getRunningHost(); - List networks = vmMo.getNetworksWithDetails(); - for (NetworkDetails netDetails : networks) { - if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { - if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { - cleanupNetwork(hostMo, netDetails); - } - } - } - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed"); - } - } - private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { // TODO : probably need to set traffic shaping Pair networkInfo = null; @@ -1950,13 +995,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) { synchronized (vmMo.getRunningHost().getMor().getValue().intern()) { networkInfo = - HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, - _opsTimeout, true, BroadcastDomainType.Vlan, null); + HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, + _opsTimeout, true, BroadcastDomainType.Vlan, null); } } else { networkInfo = - HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, null, - _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan); + HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, null, + _opsTimeout, vSwitchType, _portsPerDvPortGroup, null, false, BroadcastDomainType.Vlan); } int nicIndex = allocPublicNicIndex(vmMo); @@ -2019,11 +1064,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception("Could not allocate a free public NIC"); } - protected Answer execute(IpAssocCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IPAssocCommand: " + _gson.toJson(cmd)); - } - + private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { int i = 0; String[] results = new String[cmd.getIpAddresses().length]; @@ -2053,450 +1094,158 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } for (IpAddressTO ip : ips) { - assignPublicIpAddress(vmMo, routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress()); - results[i++] = ip.getPublicIp() + " - success"; + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); + + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } + + boolean addVif = false; + if (ip.isAdd() && publicNicInfo.first().intValue() == -1) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp()); + } + addVif = true; + } + + if (addVif) { + plugPublicNic(vmMo, vlanId, ip.getVifMacAddress()); + publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + if (publicNicInfo.first().intValue() >= 0) { + networkUsage(controlIp, "addVif", "eth" + publicNicInfo.first()); + } + } + + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + ip.setNicDevId(publicNicInfo.first().intValue()); + ip.setNewNic(addVif); } } catch (Throwable e) { s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); - - for (; i < cmd.getIpAddresses().length; i++) { - results[i++] = IpAssocAnswer.errorResult; - } + return new ExecutionResult(false, e.toString()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected Answer execute(SavePasswordCommand cmd) { - if (s_logger.isInfoEnabled()) { - - s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - String controlIp = getRouterSshControlIp(cmd); - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - // Run save_password_to_domr.sh - String args = " -v " + vmIpAddress; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + controlIp + ", /opt/cloud/bin/savepassword.sh " + args + " -p " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - args += " -p " + password; + private ExecutionResult NetworkElementCommandnup(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + VmwareContext context = getServiceContext(); try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/savepassword.sh " + args); + VmwareHypervisorHost hyperHost = getHyperHost(context); - if (!result.first()) { - s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); + IpAddressTO[] ips = cmd.getIpAddresses(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String controlIp = VmwareResource.getRouterSshControlIp(cmd); - return new Answer(cmd, false, "SavePassword failed due to " + result.second()); - } + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName); - if (s_logger.isInfoEnabled()) { - s_logger.info("savepassword command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "SavePasswordCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - return new Answer(cmd); - } - - protected Answer execute(DhcpEntryCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd)); - } - - // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null - - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); - } - args += " -h " + cmd.getVmName(); - - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } - - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/edithosts.sh " + args); - - if (!result.first()) { - s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "DhcpEntry failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("dhcp_entry command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "DhcpEntryCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing createIpAlias command: " + _gson.toJson(cmd)); - } - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/createIpAlias " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/createIpAlias.sh " + args); - - if (!result.first()) { - s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "createipAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("createIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "createIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing deleteIpAlias command: " + _gson.toJson(cmd)); - } - String args = ""; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - args = args + "- "; - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/deleteIpAlias " + args); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/deleteIpAlias.sh " + args); - - if (!result.first()) { - s_logger.error("deleteIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "deleteIpAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("deleteIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "deleteIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing dnsmasqConfig command: " + _gson.toJson(cmd)); - } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - File keyFile = mgr.getSystemVMKeyFile(); - - try { - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/dnsmasq.sh " + args); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + routerIp + ", /root/dnsmasq.sh"); - } - - if (!result.first()) { - s_logger.error("Unable update dnsmasq config file"); - return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed"); - } - } catch (Throwable e) { - String msg = "Dnsmasqconfig command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkbatchs2svpn.sh "); - } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - String cmdline = "/opt/cloud/bin/checkbatchs2svpn.sh "; - for (String ip : cmd.getVpnIps()) { - cmdline += " " + ip; - } - - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, cmdline); - - if (!result.first()) { - s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + - result.second()); - - return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckS2SVpnConnectionsCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second()); - } - - protected Answer execute(CheckRouterCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkrouter.sh "); - } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/checkrouter.sh "); - - if (!result.first()) { - s_logger.error("check router command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new CheckRouterAnswer(cmd, "CheckRouter failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check router command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckRouterCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckRouterAnswer(cmd, msg); - } - return new CheckRouterAnswer(cmd, result.second(), true); - } - - protected Answer execute(GetDomRVersionCmd cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource GetDomRVersionCmd: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/get_template_version.sh "); - } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/get_template_version.sh "); - - if (!result.first()) { - s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "GetDomRVersionCmd failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new GetDomRVersionAnswer(cmd, msg); - } - String[] lines = result.second().split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result.second()); - } - return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]); - } - - protected Answer execute(BumpUpPriorityCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource BumpUpPriorityCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/bumpup_priority.sh "); - } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/bumpup_priority.sh "); - - if (!result.first()) { - s_logger.error("BumpUpPriority command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("BumpUpPriorityCommand on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "BumpUpPriorityCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - if (result.second() == null || result.second().isEmpty()) { - return new Answer(cmd, true, result.second()); - } - return new Answer(cmd, false, result.second()); - } - - protected Answer execute(VmDataCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource VmDataCommand: " + _gson.toJson(cmd)); - } - - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - String vmIpAddress = cmd.getVmIpAddress(); - List vmData = cmd.getVmData(); - String[] vmDataArgs = new String[vmData.size() * 2 + 4]; - vmDataArgs[0] = "routerIP"; - vmDataArgs[1] = routerPrivateIpAddress; - vmDataArgs[2] = "vmIP"; - vmDataArgs[3] = vmIpAddress; - int i = 4; - for (String[] vmDataEntry : vmData) { - String folder = vmDataEntry[0]; - String file = vmDataEntry[1]; - String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none"; - - vmDataArgs[i] = folder + "," + file; - vmDataArgs[i + 1] = contents; - i += 2; - } - - String content = encodeDataArgs(vmDataArgs); - String tmpFileName = UUID.randomUUID().toString(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content); - } - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - SshHelper.scpTo(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null); - - try { - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/root/userdata.py " + tmpFileName); - - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); + // command may sometimes be redirect to a wrong host, we relax + // the check and will try to find it within cluster + if (vmMo == null) { + if (hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(routerName); } - } finally { - - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName); } - if (s_logger.isInfoEnabled()) { - s_logger.info("vm_data command on domain router " + controlIp + " completed"); + if (vmMo == null) { + String msg = "Router " + routerName + " no longer exists to execute IPAssoc command"; + s_logger.error(msg); + throw new Exception(msg); } + for (IpAddressTO ip : ips) { + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); + + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } + + boolean removeVif = false; + if (!ip.isAdd() && ip.isFirstIP()) { + removeVif = true; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo.first()); + } + } + + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + + if (removeVif) { + String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); + int nicMasks = Integer.parseInt(nicMasksStr); + nicMasks &= ~(1 << publicNicInfo.first().intValue()); + vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); + + HostMO hostMo = vmMo.getRunningHost(); + List networks = vmMo.getNetworksWithDetails(); + for (NetworkDetails netDetails : networks) { + if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { + if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { + cleanupNetwork(hostMo, netDetails); + } + } + } + } + } } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); + return new ExecutionResult(false, e.toString()); } - return new Answer(cmd); + return new ExecutionResult(true, null); } - private String encodeDataArgs(String[] dataArgs) { - StringBuilder sb = new StringBuilder(); + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { + Pair result; - for (String arg : dataArgs) { - sb.append(arg); - sb.append("\n"); + //TODO: Password should be masked, cannot output to log directly + if (s_logger.isDebugEnabled()) { + s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args); } - return sb.toString(); + try { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args); + } catch (Exception e) { + String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg); + result = new Pair(false, msg); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug(script + " execution result: " + result.first().toString()); + } + return new ExecutionResult(result.first(), result.second()); } protected CheckSshAnswer execute(CheckSshCommand cmd) { @@ -2590,7 +1339,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa hotaddMemoryLimitInMb = vmMo.getHotAddMemoryLimitInMb(); if (requestedMaxMemoryInMb > hotaddMemoryLimitInMb) { throw new CloudRuntimeException("Memory of VM " + vmMo.getVmName() + " cannot be scaled to " + requestedMaxMemoryInMb + "MB." + - " Requested memory limit is beyond the hotadd memory limit for this VM at the moment is " + hotaddMemoryLimitInMb + "MB."); + " Requested memory limit is beyond the hotadd memory limit for this VM at the moment is " + hotaddMemoryLimitInMb + "MB."); } // Check increment is multiple of increment size @@ -2602,7 +1351,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // Check if license supports the feature VmwareHelper.isFeatureLicensed(hyperHost, FeatureKeyConstants.HOTPLUG); VmwareHelper.setVmScaleUpConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(), (int)requestedMaxMemoryInMb, ramMb, - vmSpec.getLimitCpuUse()); + vmSpec.getLimitCpuUse()); if (!vmMo.configureVm(vmConfigSpec)) { throw new Exception("Unable to execute ScaleVmCommand"); @@ -2640,8 +1389,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa DiskTO[] disks = validateDisks(vmSpec.getDisks()); assert (disks.length > 0); NicTO[] nics = vmSpec.getNics(); + Map iqnToPath = new HashMap(); - HashMap> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks); + HashMap> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks, iqnToPath, cmd); if ((dataStoresDetails == null) || (dataStoresDetails.isEmpty())) { String msg = "Unable to locate datastore details of the volumes to be attached"; s_logger.error(msg); @@ -2699,6 +1449,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa for (DiskTO vol : disks) { if (vol.getType() == Volume.Type.ROOT) { DataStoreTO primaryStore = vol.getData().getDataStore(); + /** @todo Mike T. update this in 4.4 to support root disks on managed storage */ rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid()); } } @@ -2708,12 +1459,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter)) { s_logger.warn("WARN!!! Folder already exists on datastore for new VM " + vmNameOnVcenter + ", erase it"); rootDiskDataStoreDetails.second().deleteFile(String.format("[%s] %s/", rootDiskDataStoreDetails.second().getName(), vmNameOnVcenter), - dcMo.getMor(), false); + dcMo.getMor(), false); } if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), - getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), - translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) { + getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), + translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), rootDiskDataStoreDetails.first(), false)) { throw new Exception("Failed to create VM. vmName: " + vmInternalCSName); } } @@ -2740,14 +1491,20 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(); VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), - getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), - guestOsId, vmSpec.getLimitCpuUse()); + getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), + guestOsId, vmSpec.getLimitCpuUse()); // Check for hotadd settings vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId)); vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId)); configNestedHVSupport(vmMo, vmSpec, vmConfigSpec); + // Check for multi-cores per socket settings + String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket"); + if (coresPerSocket != null) { + vmConfigSpec.setNumCoresPerSocket(NumbersUtil.parseInt(coresPerSocket, 1)); + } + VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices]; int i = 0; int ideUnitNumber = 0; @@ -2780,8 +1537,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); Pair isoInfo = - VmwareHelper.prepareIsoDevice(vmMo, String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), - true, true, ideUnitNumber++, i + 1); + VmwareHelper.prepareIsoDevice(vmMo, String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), + true, true, ideUnitNumber++, i + 1); deviceConfigSpecArray[i].setDevice(isoInfo.first()); if (isoInfo.second()) { if (s_logger.isDebugEnabled()) @@ -2811,7 +1568,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); Pair isoInfo = - VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1); + VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1); deviceConfigSpecArray[i].setDevice(isoInfo.first()); if (isoInfo.second()) { if (s_logger.isDebugEnabled()) @@ -2859,20 +1616,35 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); DataStoreTO primaryStore = volumeTO.getDataStore(); - Pair volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid()); + Map details = vol.getDetails(); + boolean managed = false; + String iScsiName = null; + + if (details != null) { + managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + iScsiName = details.get(DiskTO.IQN); + } + + // if the storage is managed, iScsiName should not be null + String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid(); + Pair volumeDsDetails = dataStoresDetails.get(datastoreName); + assert (volumeDsDetails != null); - String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails); - if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber)) + String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, + vol, matchingExistingDisk, + dataStoresDetails); + if(controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber)) scsiUnitNumber++; - VirtualDevice device = - VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), + VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, + diskChain, + volumeDsDetails.first(), (controllerKey == ideControllerKey) ? ideUnitNumber++ : scsiUnitNumber++, i + 1); deviceConfigSpecArray[i].setDevice(device); deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); - if (s_logger.isDebugEnabled()) + if(s_logger.isDebugEnabled()) s_logger.debug("Prepare volume at new device " + _gson.toJson(device)); i++; @@ -2910,12 +1682,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid); nic = - VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), nicUnitNumber++, - i + 1, true, true); + VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), nicUnitNumber++, + i + 1, true, true); } else { s_logger.info("Preparing NIC device on network " + networkInfo.second()); nic = - VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true); + VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true); } deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); @@ -2951,7 +1723,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmSpec.getDetails() != null) keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD); vmConfigSpec.getExtraConfig().addAll( - Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout))); + Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout))); // // Configure VM @@ -2976,7 +1748,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } state = State.Running; - return new StartAnswer(cmd); + + StartAnswer startAnswer = new StartAnswer(cmd); + + startAnswer.setIqnToPath(iqnToPath); + + return startAnswer; } catch (Throwable e) { if (e instanceof RemoteException) { s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); @@ -2997,6 +1774,25 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + @Override + public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName, + String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret, + String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception { + ManagedObjectReference morDs = getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName), + storageHost, storagePort, VmwareResource.trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, + chapTargetUsername, chapTargetSecret); + + DatastoreMO dsMo = new DatastoreMO(getServiceContext(null), morDs); + + String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName()); + + if (!dsMo.fileExists(volumeDatastorePath)) { + createVmdk(cmd, dsMo, volumeDatastorePath, size); + } + + return morDs; + } + int getReservedMemoryMb(VirtualMachineTO vmSpec) { if (vmSpec.getDetails().get(Config.VmwareReserveMem.key()).equalsIgnoreCase("true")) { return (int)(vmSpec.getMinRam() / (1024 * 1024)); @@ -3012,7 +1808,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return vmSpec.getMinSpeed(); } else if (vmSpec.getMinSpeed().intValue() != vmSpec.getMaxSpeed().intValue()) { s_logger.warn("cpu overprovisioning factor is set to " + (vmSpec.getMaxSpeed().intValue() / vmSpec.getMinSpeed().intValue()) + - " ignoring the flag vmware.reserve.cpu"); + " ignoring the flag vmware.reserve.cpu"); return vmSpec.getMinSpeed(); } return 0; @@ -3020,16 +1816,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // return the finalized disk chain for startup, from top to bottom private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO vol, VirtualMachineDiskInfo diskInfo, - HashMap> dataStoresDetails) throws Exception { + HashMap> dataStoresDetails) throws Exception { VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); DataStoreTO primaryStore = volumeTO.getDataStore(); Map details = vol.getDetails(); - boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + boolean isManaged = false; + String iScsiName = null; + + if (details != null) { + isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + iScsiName = details.get(DiskTO.IQN); + } + + // if the storage is managed, iScsiName should not be null + String datastoreName = isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid(); + Pair volumeDsDetails = dataStoresDetails.get(datastoreName); - Pair volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid()); if (volumeDsDetails == null) + { throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host."); + } + DatastoreMO dsMo = volumeDsDetails.second(); // we will honor vCenter's meta if it exists @@ -3262,7 +2070,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED)); VirtualMachineDiskInfo diskInfo = - diskInfoBuilder.getDiskInfoByBackingFileBaseName(isManaged ? new DatastoreFile(volume.getPath()).getFileBaseName() : volume.getPath()); + diskInfoBuilder.getDiskInfoByBackingFileBaseName(isManaged ? new DatastoreFile(volume.getPath()).getFileBaseName() : volume.getPath()); if (diskInfo != null) { s_logger.info("Found existing disk info from volume path: " + volume.getPath()); return diskInfo; @@ -3314,11 +2122,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER) != null) { if (vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER).equalsIgnoreCase("scsi")) { s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: " + - vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); + vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); controllerKey = scsiControllerKey; } else { s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: " + - vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); + vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); controllerKey = ideControllerKey; } } else { @@ -3336,7 +2144,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey, int scsiControllerKey) - throws Exception { + throws Exception { VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); @@ -3374,32 +2182,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return null; } - @Deprecated - private Map validateVmDetails(Map vmDetails) { - - Map validatedDetails = new HashMap(); - - if (vmDetails != null && vmDetails.size() > 0) { - for (Map.Entry entry : vmDetails.entrySet()) { - if ("machine.id".equalsIgnoreCase(entry.getKey())) - continue; - else if ("devices.hotplug".equalsIgnoreCase(entry.getKey())) - continue; - else if ("RemoteDisplay.vnc.enabled".equalsIgnoreCase(entry.getKey())) - continue; - else if ("RemoteDisplay.vnc.password".equalsIgnoreCase(entry.getKey())) - continue; - else if ("RemoteDisplay.vnc.port".equalsIgnoreCase(entry.getKey())) - continue; - else if ("RemoteDisplay.vnc.keymap".equalsIgnoreCase(entry.getKey())) - continue; - else - validatedDetails.put(entry.getKey(), entry.getValue()); - } - } - return validatedDetails; - } - private static NicTO[] sortNicsByDeviceId(NicTO[] nics) { List listForSort = new ArrayList(); @@ -3435,7 +2217,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa public int compare(DiskTO arg0, DiskTO arg1) { if (arg0.getDiskSeq() < arg1.getDiskSeq()) { return -1; - } else if (arg0.getDiskSeq() == arg1.getDiskSeq()) { + } else if (arg0.getDiskSeq().equals(arg1.getDiskSeq())) { return 0; } @@ -3447,51 +2229,103 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } private HashMap> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context, - DiskTO[] disks) throws Exception { - HashMap> poolMors = new HashMap>(); + DiskTO[] disks, Map iqnToPath, Command cmd) throws Exception { + HashMap> mapIdToMors = new HashMap>(); assert (hyperHost != null) && (context != null); + for (DiskTO vol : disks) { if (vol.getType() != Volume.Type.ISO) { VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); DataStoreTO primaryStore = volumeTO.getDataStore(); String poolUuid = primaryStore.getUuid(); - if (poolMors.get(poolUuid) == null) { + + if (mapIdToMors.get(poolUuid) == null) { boolean isManaged = false; - String iScsiName = null; Map details = vol.getDetails(); if (details != null) { isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); - iScsiName = details.get(DiskTO.IQN); } - ManagedObjectReference morDataStore = - HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : poolUuid); - if (morDataStore == null) { - String msg = "Failed to get the mounted datastore for the volume's pool " + poolUuid; - s_logger.error(msg); - throw new Exception(msg); + if (isManaged) { + String iScsiName = details.get(DiskTO.IQN); // details should not be null for managed storage (it may or may not be null for non-managed storage) + String datastoreName = VmwareResource.getDatastoreName(iScsiName); + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, datastoreName); + + // if the datastore is not present, we need to discover the iSCSI device that will support it, + // create the datastore, and create a VMDK file in the datastore + if (morDatastore == null) { + morDatastore = prepareManagedStorage(hyperHost, iScsiName, + details.get(DiskTO.STORAGE_HOST), Integer.parseInt(details.get(DiskTO.STORAGE_PORT)), + details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET), + details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET), + Long.parseLong(details.get(DiskTO.VOLUME_SIZE)), cmd); + + DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDatastore); + String datastoreVolumePath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk"); + + iqnToPath.put(iScsiName, datastoreVolumePath); + + volumeTO.setPath(datastoreVolumePath); + vol.setPath(datastoreVolumePath); + } + + mapIdToMors.put(datastoreName, new Pair(morDatastore, new DatastoreMO(context, morDatastore))); + } + else { + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid); + + if (morDatastore == null) { + String msg = "Failed to get the mounted datastore for the volume's pool " + poolUuid; + + s_logger.error(msg); + + throw new Exception(msg); + } + + mapIdToMors.put(poolUuid, new Pair(morDatastore, new DatastoreMO(context, morDatastore))); } - poolMors.put(poolUuid, new Pair(morDataStore, new DatastoreMO(context, morDataStore))); } } } - return poolMors; + + return mapIdToMors; } private DatastoreMO getDatastoreThatRootDiskIsOn(HashMap> dataStoresDetails, DiskTO disks[]) { - Pair rootDiskDataStoreDetails = null; + for (DiskTO vol : disks) { if (vol.getType() == Volume.Type.ROOT) { - DataStoreTO primaryStore = vol.getData().getDataStore(); - rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid()); + Map details = vol.getDetails(); + boolean managed = false; + + if (details != null) { + managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + } + + if (managed) { + String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN)); + + rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName); + + break; + } + else { + DataStoreTO primaryStore = vol.getData().getDataStore(); + + rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid()); + + break; + } } } - if (rootDiskDataStoreDetails != null) + if (rootDiskDataStoreDetails != null) { return rootDiskDataStoreDetails.second(); + } + return null; } @@ -3528,24 +2362,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return defaultVlan; } - private Pair prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType) - throws Exception { - Pair switchName; - TrafficType trafficType; - VirtualSwitchType switchType; + private Pair prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType) throws Exception { - switchName = getTargetSwitch(nicTo); - trafficType = nicTo.getType(); - // Get switch type from resource property which is dictated by cluster property - // If a virtual switch type is specified while adding cluster that will be used. - // Else If virtual switch type is specified in physical traffic label that will be used - // Else use standard vSwitch - switchType = VirtualSwitchType.StandardVirtualSwitch; - if (trafficType == TrafficType.Guest && _guestTrafficInfo != null) { - switchType = _guestTrafficInfo.getVirtualSwitchType(); - } else if (trafficType == TrafficType.Public && _publicTrafficInfo != null) { - switchType = _publicTrafficInfo.getVirtualSwitchType(); - } + Ternary switchDetails = getTargetSwitch(nicTo); + nicTo.getType(); + VirtualSwitchType switchType = VirtualSwitchType.getType(switchDetails.second()); + String switchName = switchDetails.first(); + String vlanToken = switchDetails.third(); String namePrefix = getNetworkNamePrefix(nicTo); Pair networkInfo = null; @@ -3553,13 +2376,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix); if (VirtualSwitchType.StandardVirtualSwitch == switchType) { - synchronized (hostMo.getMor().getValue().intern()) { - networkInfo = - HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()), nicTo.getNetworkRateMbps(), - nicTo.getNetworkRateMulticastMbps(), _opsTimeout, !namePrefix.startsWith("cloud.private"), nicTo.getBroadcastType(), nicTo.getUuid()); + synchronized(hostMo.getMor().getValue().intern()) { + networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), + nicTo.getNetworkRateMulticastMbps(), _opsTimeout, + !namePrefix.startsWith("cloud.private"), nicTo.getBroadcastType(), nicTo.getUuid()); } - } else { - String vlanId = getVlanInfo(nicTo, switchName.second()); + } + else { + String vlanId = getVlanInfo(nicTo, vlanToken); String svlanId = null; boolean pvlannetwork = (getPvlanInfo(nicTo) == null) ? false : true; if (vmType != null && vmType.equals(VirtualMachine.Type.DomainRouter) && pvlannetwork) { @@ -3569,48 +2393,65 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // plumb this network to the isolated vlan. svlanId = getPvlanInfo(nicTo); } - networkInfo = - HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, vlanId, svlanId, nicTo.getNetworkRateMbps(), - nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType, _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, - nicTo.getBroadcastType()); + networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId, + nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType, + _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType()); } return networkInfo; } - // return Pair - private Pair getTargetSwitch(NicTO nicTo) throws Exception { - if (nicTo.getType() == Networks.TrafficType.Guest) { - return new Pair(_guestTrafficInfo.getVirtualSwitchName(), Vlan.UNTAGGED); - } else if (nicTo.getType() == Networks.TrafficType.Public) { - return new Pair(_publicTrafficInfo.getVirtualSwitchName(), Vlan.UNTAGGED); + // return Ternary + private Ternary getTargetSwitch(NicTO nicTo) throws CloudException { + TrafficType[] supportedTrafficTypes = + new TrafficType[] { + TrafficType.Guest, + TrafficType.Public, + TrafficType.Control, + TrafficType.Management, + TrafficType.Storage + }; + + TrafficType trafficType = nicTo.getType(); + if (!Arrays.asList(supportedTrafficTypes).contains(trafficType)) { + throw new CloudException("Traffic type " + trafficType.toString() + " for nic " + nicTo.toString() + " is not supported."); } - if (nicTo.getName() != null && !nicTo.getName().isEmpty()) { + String switchName = null; + VirtualSwitchType switchType = VirtualSwitchType.StandardVirtualSwitch; + String vlanToken = Vlan.UNTAGGED; + + // Get switch details from the nicTO object + if(nicTo.getName() != null && !nicTo.getName().isEmpty()) { String[] tokens = nicTo.getName().split(","); // Format of network traffic label is ,, // If all 3 fields are mentioned then number of tokens would be 3. // If only , are mentioned then number of tokens would be 2. - if (tokens.length == 2 || tokens.length == 3) { - String vlanToken = tokens[1]; + switchName = tokens[0]; + if(tokens.length == 2 || tokens.length == 3) { + vlanToken = tokens[1]; if (vlanToken.isEmpty()) { vlanToken = Vlan.UNTAGGED; } - return new Pair(tokens[0], vlanToken); - } else { - return new Pair(nicTo.getName(), Vlan.UNTAGGED); + if (tokens.length == 3) { + switchType = VirtualSwitchType.getType(tokens[2]); + } + } + } else { + if (trafficType == TrafficType.Guest && _guestTrafficInfo != null) { + switchType = _guestTrafficInfo.getVirtualSwitchType(); + switchName = _guestTrafficInfo.getVirtualSwitchName(); + } else if (trafficType == TrafficType.Public && _publicTrafficInfo != null) { + switchType = _publicTrafficInfo.getVirtualSwitchType(); + switchName = _publicTrafficInfo.getVirtualSwitchName(); } } - if (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management) { - return new Pair(_privateNetworkVSwitchName, Vlan.UNTAGGED); - } else if (nicTo.getType() == Networks.TrafficType.Storage) { - return new Pair(_privateNetworkVSwitchName, Vlan.UNTAGGED); - } else if (nicTo.getType() == Networks.TrafficType.Vpn) { - throw new Exception("Unsupported traffic type: " + nicTo.getType().toString()); - } else { - throw new Exception("Unsupported traffic type: " + nicTo.getType().toString()); + if (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management || nicTo.getType() == Networks.TrafficType.Storage) { + switchName = _privateNetworkVSwitchName; } + + return new Ternary(switchName, switchType.toString(), vlanToken); } private String getNetworkNamePrefix(NicTO nicTo) throws Exception { @@ -3629,101 +2470,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected Answer execute(final RemoteAccessVpnCfgCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - StringBuffer argsBuf = new StringBuffer(); - if (cmd.isCreate()) { - argsBuf.append(" -r ") - .append(cmd.getIpRange()) - .append(" -p ") - .append(cmd.getPresharedKey()) - .append(" -s ") - .append(cmd.getVpnServerIp()) - .append(" -l ") - .append(cmd.getLocalIp()) - .append(" -c "); - - } else { - argsBuf.append(" -d ").append(" -s ").append(cmd.getVpnServerIp()); - } - argsBuf.append(" -C ").append(cmd.getLocalCidr()); - argsBuf.append(" -i ").append(cmd.getPublicInterface()); - - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("RemoteAccessVpnCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "RemoteAccessVpnCfg command failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("RemoteAccessVpnCfg command on domain router " + argsBuf.toString() + " completed"); - } - - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "RemoteAccessVpnCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - } - - protected Answer execute(final VpnUsersCfgCommand cmd) { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String controlIp = getRouterSshControlIp(cmd); - for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { - StringBuffer argsBuf = new StringBuffer(); - if (!userpwd.isAdd()) { - argsBuf.append(" -U ").append(userpwd.getUsername()); - } else { - argsBuf.append(" -u ").append(userpwd.getUsernamePassword()); - } - - try { - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("VpnUserCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "VpnUserCfg command failed due to " + result.second()); - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "VpnUserCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - } - - return new Answer(cmd); - } - private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost hyperHost, String vmName) throws Exception { VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName); @@ -4203,8 +2949,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VirtualMachineRelocateSpecDiskLocator diskLocator = null; boolean isFirstDs = true; - String srcDiskName = ""; - String srcDsName = ""; String tgtDsName = ""; String tgtDsNfsHost; String tgtDsNfsPath; @@ -4243,7 +2987,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa volume = entry.getKey(); filerTo = entry.getValue(); - srcDsName = volume.getPoolUuid().replace("-", ""); tgtDsName = filerTo.getUuid().replace("-", ""); tgtDsNfsHost = filerTo.getHost(); tgtDsNfsPath = filerTo.getPath(); @@ -4270,8 +3013,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa relocateSpec.setDatastore(morDsAtSource); isFirstDs = false; } - srcDiskName = - VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(new DatastoreMO(srcHyperHost.getContext(), morDsAtSource), vmName, volume.getPath() + + VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(new DatastoreMO(srcHyperHost.getContext(), morDsAtSource), vmName, volume.getPath() + ".vmdk"); diskLocator = new VirtualMachineRelocateSpecDiskLocator(); diskLocator.setDatastore(morDsAtSource); @@ -4337,7 +3079,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa srcHyperHost.unmountDatastore(mountedDatastore); } catch (Exception unmountEx) { s_logger.debug("Failed to unmount datastore " + mountedDatastore + " at " + _hostName + ". Seems the datastore is still being used by " + _hostName + - ". Please unmount manually to cleanup."); + ". Please unmount manually to cleanup."); } s_logger.debug("Successfully unmounted datastore " + mountedDatastore + " at " + _hostName); } @@ -4366,7 +3108,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa List diskLocators = new ArrayList(); VirtualMachineRelocateSpecDiskLocator diskLocator = null; - String srcDiskName = ""; String tgtDsName = ""; try { @@ -4390,8 +3131,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception(msg); } - srcDiskName = - VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(new DatastoreMO(srcHyperHost.getContext(), morDs), vmName, volumePath + ".vmdk"); + VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(new DatastoreMO(srcHyperHost.getContext(), morDs), vmName, volumePath + ".vmdk"); diskLocator = new VirtualMachineRelocateSpecDiskLocator(); diskLocator.setDatastore(morDs); diskLocator.setDiskId(getVirtualDiskInfo(vmMo, volumePath + ".vmdk")); @@ -4461,7 +3201,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid()); if (morDatastore == null) morDatastore = - hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", "")); + hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", "")); assert (morDatastore != null); DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary(); @@ -4511,7 +3251,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return str.replace('/', '-'); } - public static String trimIqn(String iqn) { + private static String trimIqn(String iqn) { String[] tmp = iqn.split("/"); if (tmp.length != 3) { @@ -4525,8 +3265,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return tmp[1].trim(); } - @Override - public void createVmdk(Command cmd, DatastoreMO dsMo, String vmdkDatastorePath, Long volumeSize) throws Exception { + private void createVmdk(Command cmd, DatastoreMO dsMo, String vmdkDatastorePath, Long volumeSize) throws Exception { VmwareContext context = getServiceContext(); VmwareHypervisorHost hyperHost = getHyperHost(context); @@ -4550,7 +3289,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VmwareContext context = getServiceContext(); VmwareHypervisorHost hyperHost = getHyperHost(context); - deleteVmfsDatastore(hyperHost, getDatastoreName(iqn), storageHost, storagePort, trimIqn(iqn)); + deleteVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iqn), storageHost, storagePort, VmwareResource.trimIqn(iqn)); } protected Answer execute(AttachVolumeCommand cmd) { @@ -4575,18 +3314,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa ManagedObjectReference morDs = null; if (cmd.getAttach() && cmd.isManaged()) { - morDs = - getVmfsDatastore(hyperHost, getDatastoreName(cmd.get_iScsiName()), cmd.getStorageHost(), cmd.getStoragePort(), trimIqn(cmd.get_iScsiName()), - cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), cmd.getChapTargetUsername(), cmd.getChapTargetPassword()); - - DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDs); - - String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName()); - - if (!dsMo.fileExists(volumeDatastorePath)) { - createVmdk(cmd, dsMo, volumeDatastorePath, cmd.getVolumeSize()); - } - } else { + morDs = prepareManagedStorage(hyperHost, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.getStoragePort(), + cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), + cmd.getChapTargetUsername(), cmd.getChapTargetPassword(), cmd.getVolumeSize(), cmd); + } + else { morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid()); } @@ -4670,7 +3402,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } private void addRemoveInternetScsiTargetsToAllHosts(final boolean add, final List lstTargets, - final List> lstHosts) throws Exception { + final List> lstHosts) throws Exception { VmwareContext context = getServiceContext(); ExecutorService executorService = Executors.newFixedThreadPool(lstHosts.size()); @@ -4786,9 +3518,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - @Override - public ManagedObjectReference getVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber, String iqn, - String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception { + private ManagedObjectReference getVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber, + String iqn, String chapName, String chapSecret, String mutualChapName, String mutualChapSecret) throws Exception { VmwareContext context = getServiceContext(); ManagedObjectReference morCluster = hyperHost.getHyperHostCluster(); ClusterMO cluster = new ClusterMO(context, morCluster); @@ -5025,7 +3756,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String actualSnapshotBackupUuid = null; String actualSnapshotUuid = null; return new ValidateSnapshotAnswer(cmd, false, "ValidateSnapshotCommand is not supported for vmware yet", expectedSnapshotBackupUuid, actualSnapshotBackupUuid, - actualSnapshotUuid); + actualSnapshotUuid); } protected Answer execute(ManageSnapshotCommand cmd) { @@ -5212,7 +3943,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (s_logger.isDebugEnabled()) { s_logger.debug("Datastore summary info, storageId: " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + - cmd.getPooltype() + ", capacity: " + capacity + ", free: " + free + ", used: " + used); + cmd.getPooltype() + ", capacity: " + capacity + ", free: " + free + ", used: " + used); } if (summary.getCapacity() <= 0) { @@ -5222,8 +3953,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new GetStorageStatsAnswer(cmd, capacity, used); } else { String msg = - "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + - cmd.getPooltype(); + "Could not find datastore for GetStorageStatsCommand storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + + cmd.getPooltype(); s_logger.error(msg); return new GetStorageStatsAnswer(cmd, msg); @@ -5235,7 +3966,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } String msg = - "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + + "Unable to execute GetStorageStatsCommand(storageId : " + cmd.getStorageId() + ", localPath: " + cmd.getLocalPath() + ", poolType: " + cmd.getPooltype() + ") due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg, e); return new GetStorageStatsAnswer(cmd, msg); @@ -5313,7 +4044,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new Answer(cmd); } catch (Exception e) { s_logger.error( - "Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e); + "Unable to execute ping command on DomR (" + controlIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e); } return new Answer(cmd, false, "PingTestCommand failed"); } @@ -5644,7 +4375,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, String vmdkName, ManagedObjectReference morDatastore, - ManagedObjectReference morPool) throws Exception { + ManagedObjectReference morPool) throws Exception { if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) dsMo.deleteFile(String.format("[%s] %s/", dsMo.getName(), vmdkName), dcMo.getMor(), false); @@ -5660,16 +4391,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // to move files s_logger.info("Move volume out of volume-wrapper VM "); dsMo.moveDatastoreFile(String.format("[%s] %s/%s.vmdk", dsMo.getName(), vmdkName, vmdkName), dcMo.getMor(), dsMo.getMor(), - String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); dsMo.moveDatastoreFile(String.format("[%s] %s/%s-flat.vmdk", dsMo.getName(), vmdkName, vmdkName), dcMo.getMor(), dsMo.getMor(), - String.format("[%s] %s-flat.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + String.format("[%s] %s-flat.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); return true; } private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, String vmdkName, ManagedObjectReference morDatastore, - ManagedObjectReference morPool) throws Exception { + ManagedObjectReference morPool) throws Exception { ManagedObjectReference morBaseSnapshot = vmTemplate.getSnapshotMor("cloud.template.base"); if (morBaseSnapshot == null) { @@ -5692,10 +4423,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // to move files s_logger.info("Move volume out of volume-wrapper VM "); dsMo.moveDatastoreFile(String.format("[%s] %s/%s.vmdk", dsMo.getName(), vmdkName, vmdkName), dcMo.getMor(), dsMo.getMor(), - String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); dsMo.moveDatastoreFile(String.format("[%s] %s/%s-delta.vmdk", dsMo.getName(), vmdkName, vmdkName), dcMo.getMor(), dsMo.getMor(), - String.format("[%s] %s-delta.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + String.format("[%s] %s-delta.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); return true; } @@ -5742,8 +4473,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.detachDisk(volumeDatastorePath, false); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), vmdkName, dskch.getSize(), - null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), vmdkName, dskch.getSize(), + null); return new CreateAnswer(cmd, vol); } finally { vmMo.detachAllDisks(); @@ -5779,7 +4510,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa dsMo.deleteFile(srcFile, dcMo.getMor(), true); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), vmdkName, dskch.getSize(), null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), vmdkName, dskch.getSize(), null); return new CreateAnswer(cmd, vol); } } else { @@ -5801,8 +4532,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.detachDisk(volumeDatastorePath, false); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), volumeUuid, dskch.getSize(), - null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), dskch.getName(), pool.getPath(), volumeUuid, dskch.getSize(), + null); return new CreateAnswer(cmd, vol); } finally { s_logger.info("Destroy dummy VM after volume creation"); @@ -6001,7 +4732,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa DatastoreSummary dsSummary = dsMo.getSummary(); String address = hostMo.getHostName(); StoragePoolInfo pInfo = - new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.LVM, dsSummary.getCapacity(), dsSummary.getFreeSpace()); + new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.LVM, dsSummary.getCapacity(), dsSummary.getFreeSpace()); StartupStorageCommand cmd = new StartupStorageCommand(); cmd.setName(poolUuid); cmd.setPoolInfo(pInfo); @@ -6219,7 +4950,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (oldState != State.Starting && oldState != State.Migrating) { s_logger.debug("VM " + vm + - " is now missing from host report and VM is not at starting/migrating state, remove it from host VM-sync map, oldState: " + oldState); + " is now missing from host report and VM is not at starting/migrating state, remove it from host VM-sync map, oldState: " + oldState); _vms.remove(vm); } else { s_logger.debug("VM " + vm + " is missing from host report, but we will ignore VM " + vm + " in transition state " + oldState); @@ -6265,7 +4996,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } protected OptionValue[] configureVnc(OptionValue[] optionsToMerge, VmwareHypervisorHost hyperHost, String vmName, String vncPassword, String keyboardLayout) - throws Exception { + throws Exception { VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); @@ -6468,7 +5199,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa PerfCounterInfo rxPerfCounterInfo = null; PerfCounterInfo txPerfCounterInfo = null; - List cInfo = (List)getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); + List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); for (PerfCounterInfo info : cInfo) { if ("net".equalsIgnoreCase(info.getGroupInfo().getKey())) { if ("transmitted".equalsIgnoreCase(info.getNameInfo().getKey())) { @@ -6487,7 +5218,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String instanceNameCustomField = "value[" + key + "]"; ObjectContent[] ocs = - hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "summary.config.numCpu", "summary.quickStats.overallCpuUsage", instanceNameCustomField}); + hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "summary.config.numCpu", "summary.quickStats.overallCpuUsage", instanceNameCustomField}); if (ocs != null && ocs.length > 0) { for (ObjectContent oc : ocs) { List objProps = oc.getPropSet(); @@ -6509,7 +5240,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa maxCpuUsage = objProp.getVal().toString(); } } - VirtualMachineMO vmMo = new VirtualMachineMO(hyperHost.getContext(), oc.getObj()); + new VirtualMachineMO(hyperHost.getContext(), oc.getObj()); if (vmInternalCSName != null) { name = vmInternalCSName; } else { @@ -6523,13 +5254,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa ManagedObjectReference vmMor = hyperHost.findVmOnHyperHost(name).getMor(); assert (vmMor != null); - ArrayList vmNetworkMetrics = new ArrayList(); + ArrayList vmNetworkMetrics = new ArrayList(); // get all the metrics from the available sample period List perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMor, null, null, null); if (perfMetrics != null) { for (int index = 0; index < perfMetrics.size(); ++index) { if (((rxPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rxPerfCounterInfo.getKey())) || - ((txPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == txPerfCounterInfo.getKey()))) { + ((txPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == txPerfCounterInfo.getKey()))) { vmNetworkMetrics.add(perfMetrics.get(index)); } } @@ -6542,7 +5273,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmNetworkMetrics.size() != 0) { PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmMor); - PerfMetricId[] availableMetricIds = (PerfMetricId[])vmNetworkMetrics.toArray(new PerfMetricId[0]); + PerfMetricId[] availableMetricIds = vmNetworkMetrics.toArray(new PerfMetricId[0]); qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); List qSpecs = new ArrayList(); qSpecs.add(qSpec); @@ -6595,28 +5326,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += ethName; } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); - } + ExecutionResult result = executeInVR(privateIpAddress, "netusage.sh", args); - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); - - if (!result.first()) { - return null; - } - - return result.second(); - } catch (Throwable e) { - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to " + - VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + return null; } - return null; + return result.getDetails(); } private long[] getNetworkStats(String privateIP) { @@ -6782,7 +5498,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager()); cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID); if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch || _guestTrafficInfo != null && - _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) { + _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) { cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP); } cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC); @@ -6797,7 +5513,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa Map vsmCredentials; if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch || - _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) { + _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) { vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster)); if (vsmCredentials != null) { s_logger.info("Stocking credentials while configuring resource."); @@ -6837,8 +5553,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _portsPerDvPortGroup = intObj.intValue(); s_logger.info("VmwareResource network configuration info." + " private traffic over vSwitch: " + _privateNetworkVSwitchName + ", public traffic over " + - _publicTrafficInfo.getVirtualSwitchType() + " : " + _publicTrafficInfo.getVirtualSwitchName() + ", guest traffic over " + - _guestTrafficInfo.getVirtualSwitchType() + " : " + _guestTrafficInfo.getVirtualSwitchName()); + _publicTrafficInfo.getVirtualSwitchType() + " : " + _publicTrafficInfo.getVirtualSwitchName() + ", guest traffic over " + + _guestTrafficInfo.getVirtualSwitchType() + " : " + _guestTrafficInfo.getVirtualSwitchName()); value = params.get("vmware.create.full.clone").toString(); if (value != null && value.equalsIgnoreCase("true")) { @@ -6858,9 +5574,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa int timeout = NumbersUtil.parseInt(value, 1440) * 1000; VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); VmwareStorageProcessor storageProcessor = - new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null); + new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null); storageHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor); + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } return true; } finally { recycleServiceContext(); @@ -7029,9 +5749,4 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new Answer(cmd, false, msg); } } - - private boolean isVMWareToolsInstalled(VirtualMachineMO vmMo) throws Exception { - GuestInfo guestInfo = vmMo.getVmGuestInfo(); - return (guestInfo != null && guestInfo.getGuestState() != null && guestInfo.getGuestState().equalsIgnoreCase("running")); - } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java b/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java index afc52b56edf..0cb40286e3d 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java +++ b/plugins/hypervisors/vmware/src/com/cloud/network/CiscoNexusVSMDeviceVO.java @@ -40,6 +40,8 @@ public class CiscoNexusVSMDeviceVO implements CiscoNexusVSMDevice { // We need to know what properties a VSM has. Put them here. + private static final long serialVersionUID = 3091674059522739481L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -167,11 +169,11 @@ public class CiscoNexusVSMDeviceVO implements CiscoNexusVSMDevice { // Setter methods public void setHostId(long hostid) { - this.hostId = hostid; + hostId = hostid; } public void setVsmUserName(String username) { - this.vsmUserName = username; + vsmUserName = username; } public void setVsmName(String vsmName) { @@ -179,7 +181,7 @@ public class CiscoNexusVSMDeviceVO implements CiscoNexusVSMDevice { } public void setVsmPassword(String password) { - this.vsmPassword = password; + vsmPassword = password; } public void setMgmtIpAddr(String ipaddr) { @@ -187,50 +189,50 @@ public class CiscoNexusVSMDeviceVO implements CiscoNexusVSMDevice { } public void setManagementVlan(int vlan) { - this.managementVlan = vlan; + managementVlan = vlan; } public void setControlVlan(int vlan) { - this.controlVlan = vlan; + controlVlan = vlan; } public void setPacketVlan(int vlan) { - this.packetVlan = vlan; + packetVlan = vlan; } public void setStorageVlan(int vlan) { - this.storageVlan = vlan; + storageVlan = vlan; } public void setVsmDomainId(long id) { - this.vsmDomainId = id; + vsmDomainId = id; } public void setVsmConfigMode(VSMConfigMode mode) { - this.vsmConfigMode = mode; + vsmConfigMode = mode; } public void setVsmConfigState(VSMConfigState state) { - this.vsmConfigState = state; + vsmConfigState = state; } public void setVsmDeviceState(VSMDeviceState devState) { - this.vsmDeviceState = devState; + vsmDeviceState = devState; } // Constructors. public CiscoNexusVSMDeviceVO(String vsmIpAddr, String username, String password) { // Set all the VSM's properties here. - this.uuid = UUID.randomUUID().toString(); - this.setMgmtIpAddr(vsmIpAddr); - this.setVsmUserName(username); - this.setVsmPassword(password); - this.setVsmName(vsmName); - this.setVsmDeviceState(VSMDeviceState.Enabled); + uuid = UUID.randomUUID().toString(); + setMgmtIpAddr(vsmIpAddr); + setVsmUserName(username); + setVsmPassword(password); + setVsmName(vsmName); + setVsmDeviceState(VSMDeviceState.Enabled); } public CiscoNexusVSMDeviceVO() { - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java index e92954e99b8..c33af27d244 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java +++ b/plugins/hypervisors/vmware/src/com/cloud/network/element/CiscoNexusVSMElement.java @@ -269,8 +269,6 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme throw new CloudRuntimeException(msg); } - Transaction txn; - // If VSM already exists and is mapped to a cluster, fail this operation. vsm = _vsmDao.getVSMbyIpaddress(vsmIp); if (vsm != null) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index 7e08aeceac9..baaaf217332 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -42,13 +42,11 @@ import com.cloud.hypervisor.vmware.manager.VmwareStorageManager; import com.cloud.hypervisor.vmware.manager.VmwareStorageManagerImpl; import com.cloud.hypervisor.vmware.manager.VmwareStorageMount; import com.cloud.hypervisor.vmware.mo.ClusterMO; -import com.cloud.hypervisor.vmware.mo.DatastoreMO; import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.VmwareHostType; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostNetworkSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; -import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.serializer.GsonHelper; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -126,7 +124,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe } protected Answer execute(CreateEntityDownloadURLCommand cmd) { - boolean result = _storageMgr.execute(this, cmd); + _storageMgr.execute(this, cmd); return _resource.defaultAction(cmd); } @@ -316,54 +314,10 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe return _resource.getRootDir(storageUrl); } - private boolean validateContext(VmwareContext context, Command cmd) { - String guid = cmd.getContextParam("guid"); - assert (guid != null); - - String[] tokens = guid.split("@"); - assert (tokens != null && tokens.length == 2); - - ManagedObjectReference morHyperHost = new ManagedObjectReference(); - String[] hostTokens = tokens[0].split(":"); - assert (hostTokens.length == 2); - - morHyperHost.setType(hostTokens[0]); - morHyperHost.setValue(hostTokens[1]); - - if (morHyperHost.getType().equalsIgnoreCase("HostSystem")) { - HostMO hostMo = new HostMO(context, morHyperHost); - try { - VmwareHypervisorHostNetworkSummary netSummary = - hostMo.getHyperHostNetworkSummary(hostMo.getHostType() == VmwareHostType.ESXi ? cmd.getContextParam("manageportgroup") - : cmd.getContextParam("serviceconsole")); - assert (netSummary != null); - if (netSummary.getHostIp() != null && !netSummary.getHostIp().isEmpty()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Context validation succeeded. Validated via host: " + netSummary.getHostIp() + ", guid: " + guid); - } - return true; - } - - s_logger.warn("Context validation failed due to invalid host network summary"); - return false; - } catch (Throwable e) { - s_logger.warn("Context validation failed due to " + VmwareHelper.getExceptionMessage(e)); - return false; - } - } - - assert (false); - return true; - } - @Override - public ManagedObjectReference getVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber, String iqn, - String initiatorChapName, String initiatorChapSecret, String mutualChapName, String mutualChapSecret) throws Exception { - throw new OperationNotSupportedException(); - } - - @Override - public void createVmdk(Command cmd, DatastoreMO dsMo, String volumeDatastorePath, Long volumeSize) throws Exception { + public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName, + String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret, + String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception { throw new OperationNotSupportedException(); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 70c8c885817..6157bd681c4 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -957,7 +957,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String backupUuid = UUID.randomUUID().toString(); Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName); - return new Ternary(backupUuid + "/" + backupUuid, snapshotInfo.first(), snapshotInfo.second()); + return new Ternary(backupUuid, snapshotInfo.first(), snapshotInfo.second()); } @Override @@ -1040,8 +1040,25 @@ public class VmwareStorageProcessor implements StorageProcessor { answer = new CopyCmdAnswer(details); } else { details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage."; + + // Get snapshot physical size + long physicalSize = 0l; + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid; + File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles(); + if(files != null) { + for(File file : files) { + String fileName = file.getName(); + if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) { + physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length(); + break; + } + } + } + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(destSnapshot.getPath() + "/" + snapshotBackupUuid); + newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid); + newSnapshot.setPhysicalSize(physicalSize); answer = new CopyCmdAnswer(newSnapshot); } } finally { @@ -1155,22 +1172,13 @@ public class VmwareStorageProcessor implements StorageProcessor { if (isAttach && isManaged) { Map details = disk.getDetails(); - morDs = - hostService.getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort, VmwareResource.trimIqn(iScsiName), - details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET), details.get(DiskTO.CHAP_TARGET_USERNAME), - details.get(DiskTO.CHAP_TARGET_SECRET)); - - DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs); - - String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), dsMo.getName()); - - if (!dsMo.fileExists(volumeDatastorePath)) { - hostService.createVmdk(cmd, dsMo, volumeDatastorePath, volumeTO.getSize()); - } - } else { - morDs = - HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, - isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid()); + morDs = hostService.prepareManagedStorage(hyperHost, iScsiName, storageHost, storagePort, + details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET), + details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET), + volumeTO.getSize(), cmd); + } + else { + morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid()); } if (morDs == null) { diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java index 3930d8ec68d..e1527f96b15 100644 --- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java +++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java @@ -99,7 +99,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -119,7 +119,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -157,7 +157,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java index 9f817add11d..2e3d41c0485 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java @@ -86,7 +86,7 @@ public class VmwareResourceTest { doReturn(false).when(vmSpec).getLimitCpuUse(); when(vmMo.configureVm(vmConfigSpec)).thenReturn(true); - ScaleVmAnswer answer = _resource.execute(cmd); + _resource.execute(cmd); verify(_resource).execute(cmd); } diff --git a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java b/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java index 44296c93b2b..e3cc2f6056f 100644 --- a/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java +++ b/plugins/hypervisors/vmware/test/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategyTest.java @@ -142,7 +142,7 @@ public class VmwareStorageMotionStrategyTest { when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock); strategy.copyAsync(volumeMap, to, srcHost, destHost, caller); - assertTrue("Migration within cluster isn't successful.", this.result.isSuccess()); + assertTrue("Migration within cluster isn't successful.", result.isSuccess()); } @Test @@ -166,7 +166,7 @@ public class VmwareStorageMotionStrategyTest { when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock); strategy.copyAsync(volumeMap, to, srcHost, destHost, caller); - assertFalse("Migration within cluster didn't fail.", this.result.isSuccess()); + assertFalse("Migration within cluster didn't fail.", result.isSuccess()); } @Test @@ -190,7 +190,7 @@ public class VmwareStorageMotionStrategyTest { when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock); strategy.copyAsync(volumeMap, to, srcHost, destHost, caller); - assertTrue("Migration across cluster isn't successful.", this.result.isSuccess()); + assertTrue("Migration across cluster isn't successful.", result.isSuccess()); } @Test @@ -214,25 +214,20 @@ public class VmwareStorageMotionStrategyTest { when(agentMgr.send(anyLong(), isA(MigrateWithStorageCommand.class))).thenReturn(migAnswerMock); strategy.copyAsync(volumeMap, to, srcHost, destHost, caller); - assertFalse("Migration across cluster didn't fail.", this.result.isSuccess()); + assertFalse("Migration across cluster didn't fail.", result.isSuccess()); } private class MockContext extends AsyncRpcContext { - final Map volumeToPool; - final AsyncCallFuture future; - /** * @param callback */ public MockContext(AsyncCompletionCallback callback, AsyncCallFuture future, Map volumeToPool) { super(callback); - this.volumeToPool = volumeToPool; - this.future = future; } } protected Void mockCallBack(AsyncCallbackDispatcher callback, MockContext context) { - this.result = callback.getResult(); + result = callback.getResult(); return null; } diff --git a/plugins/hypervisors/xen/pom.xml b/plugins/hypervisors/xen/pom.xml index 7011218bdbc..39c0908070e 100644 --- a/plugins/hypervisors/xen/pom.xml +++ b/plugins/hypervisors/xen/pom.xml @@ -33,8 +33,6 @@ org.apache.httpcomponents httpclient - - 4.2.2 compile diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java index 4f21a021b75..529e26125f3 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java @@ -108,7 +108,11 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru if (volume.getVolumeType() == Volume.Type.DATADISK) { StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId()); - if (storagePool.isManaged()) { + // storagePool should be null if we are expunging a volume that was never + // attached to a VM that was started (the "trick" for storagePool to be null + // is that none of the VMs this volume may have been attached to were ever started, + // so the volume was never assigned to a storage pool) + if (storagePool != null && storagePool.isManaged()) { DataTO volTO = _volFactory.getVolume(volume.getId()).getTO(); DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index cd1b30b9f71..58fe0159815 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -195,8 +195,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L String hostIp = ia.getHostAddress(); Queue pass = new LinkedList(); pass.add(password); - String masterIp = _connPool.getMasterIp(hostIp, username, pass); - conn = _connPool.masterConnect(masterIp, username, pass); + conn = _connPool.getConnect(hostIp, username, pass); if (conn == null) { String msg = "Unable to get a connection to " + url; s_logger.debug(msg); @@ -398,7 +397,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L password = host.getDetail("password"); pass.add(password); String address = host.getPrivateIpAddress(); - Connection hostConn = _connPool.slaveConnect(address, username, pass); + Connection hostConn = _connPool.getConnect(address, username, pass); if (hostConn == null) { continue; } @@ -411,9 +410,9 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } catch (Exception e) { s_logger.warn("Can not get master ip address from host " + address); } finally { - try { - Session.localLogout(hostConn); - } catch (Exception e) { + try{ + Session.logout(hostConn); + } catch (Exception e ) { } hostConn.dispose(); hostConn = null; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index accaa85230f..200a72ff219 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -45,10 +45,6 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.w3c.dom.Document; @@ -56,22 +52,48 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; +import com.trilead.ssh2.SCPClient; +import com.xensource.xenapi.Bond; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Console; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.HostCpu; +import com.xensource.xenapi.HostMetrics; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PBD; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Session; +import com.xensource.xenapi.Task; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VBDMetrics; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.VMGuestMetrics; +import com.xensource.xenapi.XenAPIObject; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; + import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; @@ -84,8 +106,6 @@ import com.cloud.agent.api.CreateVMSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -145,7 +165,6 @@ import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -165,35 +184,11 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; @@ -203,28 +198,23 @@ import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; import com.cloud.storage.Storage; @@ -235,6 +225,7 @@ import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -247,33 +238,6 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.snapshot.VMSnapshot; -import com.google.gson.Gson; -import com.trilead.ssh2.SCPClient; -import com.xensource.xenapi.Bond; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Console; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.HostCpu; -import com.xensource.xenapi.HostMetrics; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PBD; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Pool; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Session; -import com.xensource.xenapi.Task; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.BadServerResponse; -import com.xensource.xenapi.Types.VmPowerState; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VBDMetrics; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; -import com.xensource.xenapi.VMGuestMetrics; -import com.xensource.xenapi.XenAPIObject; /** @@ -289,7 +253,7 @@ import com.xensource.xenapi.XenAPIObject; * */ @Local(value = ServerResource.class) -public abstract class CitrixResourceBase implements ServerResource, HypervisorResource { +public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); protected String _name; @@ -336,6 +300,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected StorageSubsystemCommandHandler storageHandler; protected int _maxNics = 7; + protected VirtualRoutingResource _vrResource; + public enum SRType { NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE; @@ -426,23 +392,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected boolean pingXenServer() { - Session slaveSession = null; - Connection slaveConn = null; + Connection conn = getConnection(); try { - URL slaveUrl = null; - slaveUrl = ConnPool.getURL(_host.ip); - slaveConn = new Connection(slaveUrl, 10); - slaveSession = ConnPool.slaveLocalLoginWithPassword(slaveConn, _username, _password); + callHostPlugin(conn, "echo", "main"); return true; } catch (Exception e) { - } finally { - if (slaveSession != null) { - try { - Session.localLogout(slaveConn); - } catch (Exception e) { - } - slaveConn.dispose(); - } + s_logger.debug("cannot ping host " + _host.ip + " due to " + e.toString(), e); } return false; } @@ -456,30 +411,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Class clazz = cmd.getClass(); if (clazz == CreateCommand.class) { return execute((CreateCommand)cmd); - } else if (clazz == SetPortForwardingRulesCommand.class) { - return execute((SetPortForwardingRulesCommand)cmd); - } else if (clazz == SetStaticNatRulesCommand.class) { - return execute((SetStaticNatRulesCommand)cmd); - } else if (clazz == LoadBalancerConfigCommand.class) { - return execute((LoadBalancerConfigCommand)cmd); - } else if (clazz == IpAssocCommand.class) { - return execute((IpAssocCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clazz == CheckConsoleProxyLoadCommand.class) { return execute((CheckConsoleProxyLoadCommand)cmd); } else if (clazz == WatchConsoleProxyLoadCommand.class) { return execute((WatchConsoleProxyLoadCommand)cmd); - } else if (clazz == SavePasswordCommand.class) { - return execute((SavePasswordCommand)cmd); - } else if (clazz == DhcpEntryCommand.class) { - return execute((DhcpEntryCommand)cmd); - } else if (clazz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clazz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clazz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clazz == VmDataCommand.class) { - return execute((VmDataCommand)cmd); } else if (clazz == ReadyCommand.class) { return execute((ReadyCommand)cmd); } else if (clazz == GetHostStatsCommand.class) { @@ -538,10 +475,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((PoolEjectCommand)cmd); } else if (clazz == StartCommand.class) { return execute((StartCommand)cmd); - } else if (clazz == RemoteAccessVpnCfgCommand.class) { - return execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clazz == VpnUsersCfgCommand.class) { - return execute((VpnUsersCfgCommand)cmd); } else if (clazz == CheckSshCommand.class) { return execute((CheckSshCommand)cmd); } else if (clazz == SecurityGroupRulesCmd.class) { @@ -568,54 +501,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((OvsDestroyTunnelCommand)cmd); } else if (clazz == UpdateHostPasswordCommand.class) { return execute((UpdateHostPasswordCommand)cmd); - } else if (cmd instanceof CheckRouterCommand) { - return execute((CheckRouterCommand)cmd); - } else if (cmd instanceof SetFirewallRulesCommand) { - return execute((SetFirewallRulesCommand)cmd); - } else if (cmd instanceof BumpUpPriorityCommand) { - return execute((BumpUpPriorityCommand)cmd); } else if (cmd instanceof ClusterSyncCommand) { return execute((ClusterSyncCommand)cmd); - } else if (cmd instanceof GetDomRVersionCmd) { - return execute((GetDomRVersionCmd)cmd); } else if (clazz == CheckNetworkCommand.class) { return execute((CheckNetworkCommand)cmd); - } else if (clazz == SetupGuestNetworkCommand.class) { - return execute((SetupGuestNetworkCommand)cmd); } else if (clazz == PlugNicCommand.class) { return execute((PlugNicCommand)cmd); } else if (clazz == UnPlugNicCommand.class) { return execute((UnPlugNicCommand)cmd); - } else if (clazz == IpAssocVpcCommand.class) { - return execute((IpAssocVpcCommand)cmd); - } else if (clazz == SetSourceNatCommand.class) { - return execute((SetSourceNatCommand)cmd); - } else if (clazz == SetNetworkACLCommand.class) { - return execute((SetNetworkACLCommand)cmd); - } else if (clazz == SetPortForwardingRulesVpcCommand.class) { - return execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clazz == SetStaticRouteCommand.class) { - return execute((SetStaticRouteCommand)cmd); - } else if (clazz == Site2SiteVpnCfgCommand.class) { - return execute((Site2SiteVpnCfgCommand)cmd); - } else if (clazz == CheckS2SVpnConnectionsCommand.class) { - return execute((CheckS2SVpnConnectionsCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clazz == CreateVMSnapshotCommand.class) { - return execute((CreateVMSnapshotCommand)cmd); + return execute((CreateVMSnapshotCommand) cmd); } else if (clazz == DeleteVMSnapshotCommand.class) { - return execute((DeleteVMSnapshotCommand)cmd); + return execute((DeleteVMSnapshotCommand) cmd); } else if (clazz == RevertToVMSnapshotCommand.class) { - return execute((RevertToVMSnapshotCommand)cmd); + return execute((RevertToVMSnapshotCommand) cmd); } else if (clazz == NetworkRulesVmSecondaryIpCommand.class) { - return execute((NetworkRulesVmSecondaryIpCommand)cmd); + return execute((NetworkRulesVmSecondaryIpCommand) cmd); } else if (clazz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clazz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clazz == SetMonitorServiceCommand.class) { - return execute((SetMonitorServiceCommand)cmd); } else if (clazz == PerformanceMonitorCommand.class) { return execute((PerformanceMonitorCommand)cmd); } else { @@ -623,6 +530,50 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { + Connection conn = getConnection(); + String rc = callHostPlugin(conn, "vmops", "routerProxy", "args", script + " " + routerIP + " " + args); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { + Connection conn = getConnection(); + String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path + filename, "filecontents", content); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { + cleanupNetworkElementCommand((IpAssocCommand)cmd); + } + return new ExecutionResult(true, null); + } + private Answer execute(PerformanceMonitorCommand cmd) { Connection conn = getConnection(); String perfMon = getPerfMon(conn, cmd.getParams(), cmd.getWait()); @@ -633,11 +584,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String getPerfMon(Connection conn, Map params, - int wait) { + int wait) { String result = null; try { result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, - params); + params); if (result != null) return result; } catch (Exception e) { @@ -647,7 +598,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected String callHostPluginAsync(Connection conn, String plugin, - String cmd, int wait, Map params) { + String cmd, int wait, Map params) { int timeout = wait * 1000; Map args = new HashMap(); Task task = null; @@ -657,7 +608,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin executing for command " + cmd - + " with " + getArgsString(args)); + + " with " + getArgsString(args)); } Host host = Host.getByUuid(conn, _host.uuid); task = host.callPluginAsync(conn, plugin, cmd, args); @@ -669,29 +620,29 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.trace("callHostPlugin Result: " + result); } return result.replace("", "").replace("", "") - .replace("\n", ""); + .replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd - + " with args " + getArgsString(args) - + " due to HandleInvalid clazz:" + e.clazz + ", handle:" - + e.handle); + + " with args " + getArgsString(args) + + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + + e.handle); } catch (XenAPIException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.toString(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.toString(), + e); } catch (XmlRpcException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.getMessage(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.getMessage(), + e); } finally { if (task != null) { try { task.destroy(conn); } catch (Exception e1) { s_logger.warn("unable to destroy task(" + task.toString() - + ") on host(" + _host.uuid + ") due to ", e1); + + ") on host(" + _host.uuid + ") due to ", e1); } } } @@ -706,7 +657,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Long newDynamicMemoryMax = vmSpec.getMaxRam(); if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) { throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin + - ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); + ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); } vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax); @@ -746,7 +697,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If DMC is not enable then don't execute this command. if (!isDmcEnabled(conn, host)) { throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + _host.uuid + - " ,check your license and hypervisor version."); + " ,check your license and hypervisor version."); } // stop vm which is running on this host or is in halted state @@ -756,7 +707,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe VM.Record vmr = vm.getRecord(conn); if ((vmr.powerState == VmPowerState.HALTED) || - (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { + (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { iter.remove(); } } @@ -863,11 +814,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String revertToSnapshot(Connection conn, VM vmSnapshot, String vmName, String oldVmUuid, Boolean snapshotMemory, String hostUUID) throws XenAPIException, - XmlRpcException { + XmlRpcException { String results = - callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", - oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); + callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", + oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "revert_memory_snapshot return null"; @@ -1047,9 +998,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!is_xcp()) enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key); String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, - "key", String.valueOf(key), - "xs_nw_uuid", nw.getUuid(conn), - "cs_host_id", ((Long)hostId).toString()); + "key", String.valueOf(key), + "xs_nw_uuid", nw.getUuid(conn), + "cs_host_id", ((Long)hostId).toString()); //Note down the fact that the ovs bridge has been setup String[] res = result.split(":"); if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { @@ -1262,10 +1213,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException { + protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException { Volume.Type type = volume.getType(); - VDI vdi = mount(conn, vmName, volume); + if (vdi == null) { + vdi = mount(conn, vmName, volume); + } if (vdi != null) { if ("detached".equals(vdi.getNameLabel(conn))) { @@ -1695,8 +1648,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String result = null; if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); return new Answer(cmd, false, result); @@ -1705,8 +1658,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "vm-mac", vmMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "vm-mac", vmMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for vm with mac " + vmMac); return new Answer(cmd, false, result); @@ -1754,7 +1707,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vm = createVmFromTemplate(conn, vmSpec, host); for (DiskTO disk : vmSpec.getDisks()) { - createVbd(conn, disk, vmName, vm, vmSpec.getBootloader()); + VDI newVdi = prepareManagedDisk(conn, disk, vmName); + + if (newVdi != null) { + String path = newVdi.getUuid(conn); + + iqnToPath.put(disk.getDetails().get(DiskTO.IQN), path); + } + + createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi); } if (vmSpec.getType() != VirtualMachine.Type.User) { @@ -1773,7 +1734,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) { HashMap args = parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri())); OvsSetTagAndFlowCommand flowCmd = - new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); + new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); OvsSetTagAndFlowAnswer r = execute(flowCmd); if (!r.getResult()) { s_logger.warn("Failed to set flow for VM " + r.getVmId()); @@ -1792,7 +1753,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe boolean secGrpEnabled = false; for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || - (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { + (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { secGrpEnabled = true; break; } @@ -1811,7 +1772,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe NicTO[] nics = vmSpec.getNics(); for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && - nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { List nicSecIps = nic.getNicSecIps(); String secIpsStr; StringBuilder sb = new StringBuilder(); @@ -1824,8 +1785,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe secIpsStr = "0:"; } result = - callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", - Long.toString(vmSpec.getId()), "secIps", secIpsStr); + callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", + Long.toString(vmSpec.getId()), "secIps", secIpsStr); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); @@ -1866,6 +1827,53 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + // the idea here is to see if the DiskTO in question is from managed storage and + // does not yet have an SR + // if no SR, create it and create a VDI in it + private VDI prepareManagedDisk(Connection conn, DiskTO disk, String vmName) throws Exception { + Map details = disk.getDetails(); + + if (details == null) { + return null; + } + + boolean isManaged = new Boolean(details.get(DiskTO.MANAGED)).booleanValue(); + + if (!isManaged) { + return null; + } + + String iqn = details.get(DiskTO.IQN); + + Set srNameLabels = SR.getByNameLabel(conn, iqn); + + if (srNameLabels.size() != 0) { + return null; + } + + String vdiNameLabel = vmName + "-DATA"; + + return prepareManagedStorage(conn, details, null, vdiNameLabel); + } + + protected VDI prepareManagedStorage(Connection conn, Map details, String path, String vdiNameLabel) throws Exception { + String iScsiName = details.get(DiskTO.IQN); + String storageHost = details.get(DiskTO.STORAGE_HOST); + String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME); + String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET); + Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE)); + + SR sr = getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); + + VDI vdi = getVDIbyUuid(conn, path, false); + + if (vdi == null) { + vdi = createVdi(sr, vdiNameLabel, volumeSize); + } + + return vdi; + } + protected Answer execute(ModifySshKeysCommand cmd) { return new Answer(cmd); } @@ -1909,53 +1917,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd); } - private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - Connection conn = getConnection(); - String args = "checkbatchs2svpn.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - for (String ip : cmd.getVpnIps()) { - args += " " + ip; - } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); - } - - private CheckRouterAnswer execute(CheckRouterCommand cmd) { - Connection conn = getConnection(); - String args = "checkrouter.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); - } - return new CheckRouterAnswer(cmd, result, true); - } - - private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { - Connection conn = getConnection(); - String args = "get_template_version.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); - } - String[] lines = result.split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); - } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); - } - - private Answer execute(BumpUpPriorityCommand cmd) { - Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "bumpUpPriority", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed"); - } - return new Answer(cmd, true, result); - } - protected MaintainAnswer execute(MaintainCommand cmd) { Connection conn = getConnection(); try { @@ -1981,598 +1942,87 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { - Connection conn = getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - StringBuilder args = new StringBuilder(); - args.append(routerIp); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -p ").append(rule.getStringSrcPortRange()); - args.append(" -r ").append(rule.getDstIp()); - args.append(" -d ").append(rule.getStringDstPortRange()); - - String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - //String args = routerIp; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - String args = "vpc_staticnat.sh " + routerIp; - args += rule.revoked() ? " -D" : " -A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - Connection conn = getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - //String args = routerIp; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - //1:1 NAT needs instanceip;publicip;domrip;op - StringBuilder args = new StringBuilder(); - args.append(routerIp); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -r ").append(rule.getDstIp()); - - if (rule.getProtocol() != null) { - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - } - - args.append(" -d ").append(rule.getStringSrcPortRange()); - args.append(" -G "); - - String result = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer VPCLoadBalancerConfig(final LoadBalancerConfigCommand cmd) { - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - - if (routerIp == null) { - return new Answer(cmd); - } - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } - String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; - String result = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", tmpCfgFilePath, "filecontents", tmpCfgFileContents); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file."); - } - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = "vpc_loadbalancer.sh " + routerIp; - String ip = cmd.getNic().getIp(); - args += " -i " + ip; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - return new Answer(cmd); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = routerIp + " "; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - String result = callHostPlugin(conn, "vmops", "createipAlias", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "CreateIPAliasCommand failed\n"); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - String args = routerIp + " "; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. - args = args + "- "; - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - String result = callHostPlugin(conn, "vmops", "deleteipAlias", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DeleteipAliasCommand failed\n"); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - - String result = callHostPlugin(conn, "vmops", "configdnsmasq", "routerip", routerIp, "args", args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DnsMasqconfigCommand failed"); - } - - return new Answer(cmd); - - } - - protected Answer execute(final LoadBalancerConfigCommand cmd) { - if (cmd.getVpcId() != null) { - return VPCLoadBalancerConfig(cmd); - } - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - - if (routerIp == null) { - return new Answer(cmd); - } - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - - String[][] rules = cfgtr.generateFwRules(cmd); - String tmpCfgFilePath = "/tmp/" + routerIp.replace('.', '_') + ".cfg"; - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } - - String result = callHostPlugin(conn, "vmops", "createFile", "filepath", tmpCfgFilePath, "filecontents", tmpCfgFileContents); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file."); - } - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - args += "-i " + routerIp; - args += " -f " + tmpCfgFilePath; - - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - result = callHostPlugin(conn, "vmops", "setLoadBalancerRule", "args", args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - - callHostPlugin(conn, "vmops", "deleteFile", "filepath", tmpCfgFilePath); - - return new Answer(cmd); - } - - protected synchronized Answer execute(final DhcpEntryCommand cmd) { - Connection conn = getConnection(); - String args = "-r " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (cmd.getVmIpAddress() != null) { - args += " -v " + cmd.getVmIpAddress(); - } - args += " -m " + cmd.getVmMac(); - args += " -n " + cmd.getVmName(); - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getDefaultDns() != null) { - args += " -N " + cmd.getDefaultDns(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -z"; - } - - String result = callHostPlugin(conn, "vmops", "saveDhcpEntry", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DhcpEntry failed"); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { - Connection conn = getConnection(); - String args = "vpn_l2tp.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (cmd.isCreate()) { - args += " -r " + cmd.getIpRange(); - args += " -p " + cmd.getPresharedKey(); - args += " -s " + cmd.getVpnServerIp(); - args += " -l " + cmd.getLocalIp(); - args += " -c "; - } else { - args += " -d "; - args += " -s " + cmd.getVpnServerIp(); - } - args += " -C " + cmd.getLocalCidr(); - args += " -i " + cmd.getPublicInterface(); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN failed"); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final VpnUsersCfgCommand cmd) { - Connection conn = getConnection(); - for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { - String args = "vpn_l2tp.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (!userpwd.isAdd()) { - args += " -U " + userpwd.getUsername(); - } else { - args += " -u " + userpwd.getUsernamePassword(); - } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); - } - } - - return new Answer(cmd); - } - - protected Answer execute(final VmDataCommand cmd) { - Connection conn = getConnection(); - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String json = new Gson().toJson(data); - json = Base64.encodeBase64String(json.getBytes()); - - String args = "vmdata.py " + routerPrivateIpAddress + " -d " + json; - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "vm_data failed"); - } else { - return new Answer(cmd); - } - - } - - protected Answer execute(final SavePasswordCommand cmd) { - Connection conn = getConnection(); - final String password = cmd.getPassword(); - final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String vmIpAddress = cmd.getVmIpAddress(); - - String args = "savepassword.sh " + routerPrivateIPAddress; - args += " -v " + vmIpAddress; - args += " -p " + password; - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "savePassword failed"); - } - return new Answer(cmd); - } - - protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP, - boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, TrafficType trafficType, String name) - throws InternalErrorException { - - try { - VM router = getVM(conn, vmName); - - NicTO nic = new NicTO(); - nic.setMac(vifMacAddress); - nic.setType(trafficType); - if (vlanId == null) { - nic.setBroadcastType(BroadcastDomainType.Native); - } else { - URI uri = BroadcastDomainType.fromString(vlanId); - nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); - nic.setBroadcastUri(uri); - } - nic.setDeviceId(0); - nic.setNetworkRateMbps(networkRate); - nic.setName(name); - - Network network = getNetwork(conn, nic); - - // Determine the correct VIF on DomR to associate/disassociate the - // IP address with - VIF correctVif = getCorrectVif(conn, router, network); - - // If we are associating an IP address and DomR doesn't have a VIF - // for the specified vlan ID, we need to add a VIF - // If we are disassociating the last IP address in the VLAN, we need - // to remove a VIF - boolean addVif = false; - boolean removeVif = false; - if (add && correctVif == null) { - addVif = true; - } - - if (addVif) { - // Add a new VIF to DomR - String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); - - if (vifDeviceNum == null) { - throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); - } - - nic.setDeviceId(Integer.parseInt(vifDeviceNum)); - - correctVif = createVif(conn, vmName, router, null, nic); - correctVif.plug(conn); - // Add iptables rule for network usage - networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn)); - } - - if (correctVif == null) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } - - String args = "ipassoc.sh " + privateIpAddress; - - if (add) { - args += " -A "; - } else { - args += " -D "; - } - - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - //To indicate this is new interface created - args += " -n"; - } - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); - } - - if (removeVif) { - network = correctVif.getNetwork(conn); - - // Mark this vif to be removed from network usage - networkUsage(conn, privateIpAddress, "deleteVif", "eth" + correctVif.getDevice(conn)); - - // Remove the VIF from DomR - correctVif.unplug(conn); - correctVif.destroy(conn); - - // Disable the VLAN network if necessary - disableVlanNetwork(conn, network); - } - - } catch (XenAPIException e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } catch (final XmlRpcException e) { - String msg = "Unable to assign public IP address due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } - } - - protected void assignVPCPublicIpAddress(Connection conn, String vmName, String routerIp, IpAddressTO ip) throws Exception { - - try { - VM router = getVM(conn, vmName); - - VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); - if (correctVif == null) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = "vpc_ipassoc.sh " + routerIp; - String snatArgs = "vpc_privateGateway.sh " + routerIp; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed."); - } - - if (ip.isSourceNat()) { - snatArgs += " -l " + ip.getPublicIp(); - snatArgs += " -c " + "eth" + correctVif.getDevice(conn); - - result = callHostPlugin(conn, "vmops", "routerProxy", "args", snatArgs); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_privateGateway\" failed."); - } - } - - } catch (Exception e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new Exception(msg); - } - } - protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - if (option.equals("get")) { return "0:0"; } return null; } - protected Answer execute(IpAssocCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { + Connection conn = getConnection(); + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are associating an IP address and DomR doesn't have a VIF + // for the specified vlan ID, we need to add a VIF + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean addVif = false; + if (ip.isAdd() && correctVif == null) { + addVif = true; + } + + if (addVif) { + // Add a new VIF to DomR + String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); + + if (vifDeviceNum == null) { + throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); + } + + nic.setDeviceId(Integer.valueOf(vifDeviceNum)); + + correctVif = createVif(conn, routerName, router, null, nic); + correctVif.plug(conn); + // Add iptables rule for network usage + networkUsage(conn, routerIp, "addVif", "eth" + correctVif.getDevice(conn)); + } + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); + ip.setNewNic(addVif); + } + } catch (InternalErrorException e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); + } + return new ExecutionResult(true, null); + } + + protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) { Connection conn = getConnection(); String[] results = new String[cmd.getIpAddresses().length]; int i = 0; @@ -2582,16 +2032,57 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName()); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean removeVif = false; + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + if (removeVif) { + network = correctVif.getNetwork(conn); + + // Mark this vif to be removed from network usage + networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn)); + + // Remove the VIF from DomR + correctVif.unplug(conn); + correctVif.destroy(conn); + + // Disable the VLAN network if necessary + disableVlanNetwork(conn, network); + } } } catch (InternalErrorException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } protected GetVncPortAnswer execute(GetVncPortCommand cmd) { @@ -2976,7 +2467,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("true"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected String getVmStatsRawXML(Connection conn) { @@ -2984,7 +2475,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("false"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected State convertToState(Types.VmPowerState ps) { @@ -3198,8 +2689,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String createTemplateFromSnapshot(Connection conn, String templatePath, String snapshotPath, int wait) { String tmpltLocalDir = UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, - "tmpltLocalDir", tmpltLocalDir); + callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, + "tmpltLocalDir", tmpltLocalDir); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "create_privatetemplate_from_snapshot return null"; @@ -3250,7 +2741,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { String nameLabel = "cloud-" + UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); + callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "copy_vhd_from_secondarystorage return null"; @@ -3435,7 +2926,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Set vbds = vm.getVBDs(conn); for (VBD vbd : vbds) { VBD.Record vbdRec = vbd.getRecord(conn); - if (vbdRec.type.equals(Types.VbdType.CD.toString()) && !vbdRec.empty) { + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { vbd.eject(conn); break; } @@ -3703,7 +3194,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe long beginTime = System.currentTimeMillis(); if (s_logger.isTraceEnabled()) { s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + - "ms timeout"); + "ms timeout"); } while (task.getStatus(c) == Types.TaskStatusType.PENDING) { try { @@ -3946,7 +3437,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("", "").replace("", "").replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -4229,7 +3720,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -4254,7 +3745,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Bond bond = mgmtPifRec.bondSlaveOf; if (!isRefNull(bond)) { String msg = - "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + + "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + "), please move management interface to bond!"; s_logger.warn(msg); throw new CloudRuntimeException(msg); @@ -5021,6 +4512,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (_securityGroupEnabled) { _canBridgeFirewall = can_bridge_firewall(conn); + if (!_canBridgeFirewall) { + String msg = "Failed to configure brige firewall"; + s_logger.warn(msg); + s_logger.warn("Check host " + _host.ip +" for CSP is installed or not and check network mode for bridge"); + return new SetupAnswer(cmd, msg); + } + } String result = callHostPluginPremium(conn, "heartbeat", "host", _host.uuid, "interval", Integer.toString(_heartbeatInterval)); @@ -5054,7 +4552,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -5088,7 +4586,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (pr.VLAN != null && pr.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) .append(" ; pif=") .append(pr.uuid) .toString(); @@ -5098,7 +4596,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { if (pr.bondMasterOf.size() > 1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) .append("; pif=") .append(pr.uuid) .toString(); @@ -5112,8 +4610,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (spr.management) { if (!transferManagementNetwork(conn, host, slave, spr, pif)) { String msg = - new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + - _host.uuid).toString(); + new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + + _host.uuid).toString(); s_logger.warn(msg); return new SetupAnswer(cmd, msg); } @@ -5271,22 +4769,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (PhysicalNetworkSetupInfo info : infoList) { if (!isNetworkSetupByName(info.getGuestNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + - info.getGuestNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + + info.getGuestNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPrivateNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + - info.getPrivateNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + + info.getPrivateNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPublicNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + - info.getPublicNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + + info.getPublicNetworkName(); errorout = true; break; } @@ -5455,8 +4953,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, true, "success"); } catch (Exception e) { String msg = - "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + - pool.getHost() + pool.getPath(); + "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + + pool.getHost() + pool.getPath(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } @@ -5486,7 +4984,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -5645,8 +5143,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey()); bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", - cmd.getFrom().toString(), "to", cmd.getTo().toString()); + callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", + cmd.getFrom().toString(), "to", cmd.getTo().toString()); String[] res = result.split(":"); if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) { return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge); @@ -5719,8 +5217,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * plugin side */ String result = - callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), - "seqno", cmd.getSeqNo()); + callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), + "seqno", cmd.getSeqNo()); s_logger.debug("set flow for " + cmd.getVmName() + " " + result); if (result.equalsIgnoreCase("SUCCESS")) { @@ -5777,8 +5275,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", - Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); + callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", + Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); String[] res = result.split(":"); if (res.length != 2 || (res.length == 2 && res[1].equalsIgnoreCase("[]"))) { return new OvsCreateGreTunnelAnswer(cmd, false, result, _host.ip, bridge); @@ -5805,20 +5303,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!_canBridgeFirewall) { s_logger.warn("Host " + _host.ip + " cannot do bridge firewalling"); return new SecurityGroupRuleAnswer(cmd, false, "Host " + _host.ip + " cannot do bridge firewalling", - SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } String result = - callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", - Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", - cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); + callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", + Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", + cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", ingress numrules=" + cmd.getIngressRuleSet().length + - ", egress numrules=" + cmd.getEgressRuleSet().length); + ", egress numrules=" + cmd.getEgressRuleSet().length); return new SecurityGroupRuleAnswer(cmd); } } @@ -6034,8 +5532,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe CheckXenHostInfo(); storageHandler = getStorageHandler(); - return true; + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } + return true; } protected StorageSubsystemCommandHandler getStorageHandler() { @@ -6044,9 +5546,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private void CheckXenHostInfo() throws ConfigurationException { - Connection conn = ConnPool.slaveConnect(_host.ip, _username, _password); - if (conn == null) { - throw new ConfigurationException("Can not create slave connection to " + _host.ip); + Connection conn = ConnPool.getConnect(_host.ip, _username, _password); + if( conn == null ) { + throw new ConfigurationException("Can not create connection to " + _host.ip); } try { Host.Record hostRec = null; @@ -6066,7 +5568,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } finally { try { - Session.localLogout(conn); + Session.logout(conn); } catch (Exception e) { } } @@ -6101,7 +5603,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); return new CreateAnswer(cmd, vol); } catch (Exception e) { s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); @@ -6171,8 +5673,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, + new HashMap()); if (!checkSR(conn, sr)) { throw new Exception("no attached PBD"); } @@ -6261,7 +5763,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected SR getIscsiSR(Connection conn, String srNameLabel, String target, String path, String chapInitiatorUsername, String chapInitiatorPassword, - boolean ignoreIntroduceException) { + boolean ignoreIntroduceException) { synchronized (srNameLabel.intern()) { Map deviceConfig = new HashMap(); try { @@ -6304,7 +5806,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + - ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); + ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); } } deviceConfig.put("target", target); @@ -6435,7 +5937,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + - " for pool " + pool.getUuid() + "on host:" + _host.uuid); + " for pool " + pool.getUuid() + "on host:" + _host.uuid); } } @@ -6443,8 +5945,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe deviceConfig.put("serverpath", serverpath); Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, + new HashMap()); sr.scan(conn); return sr; } catch (XenAPIException e) { @@ -6562,7 +6064,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (cmd.getAttach() && cmd.isManaged()) { SR sr = - getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); + getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); vdi = getVDIbyUuid(conn, cmd.getVolumePath(), false); @@ -6590,7 +6092,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (isHVM && !pvDrvInstalled) { s_logger.warn(errorMsg + ": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected"); return new AttachVolumeAnswer(cmd, - "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); + "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); } if (attach) { // Figure out the disk number to attach the VM to @@ -6837,11 +6339,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List listVolumeTo) throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, - Types.OperationNotAllowed, XenAPIException, XmlRpcException { + Types.OperationNotAllowed, XenAPIException, XmlRpcException { String guestOsTypeName = getGuestOsType(guestOSType, false); if (guestOsTypeName == null) { String msg = - " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; + " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; s_logger.warn(msg); throw new CloudRuntimeException(msg); } @@ -7232,7 +6734,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected boolean postCreatePrivateTemplate(Connection conn, String templatePath, String tmpltFilename, String templateName, String templateDescription, - String checksum, long size, long virtualSize, long templateId) { + String checksum, long size, long virtualSize, long templateId) { if (templateDescription == null) { templateDescription = ""; @@ -7243,9 +6745,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } String result = - callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", - templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), - "templateId", String.valueOf(templateId)); + callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", + templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), + "templateId", String.valueOf(templateId)); boolean success = false; if (result != null && !result.isEmpty()) { @@ -7264,8 +6766,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { String parentUuid = - callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", - isISCSI.toString()); + callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", + isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); @@ -7279,8 +6781,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If anybody modifies the formatting below again, I'll skin them String result = - callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), - "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); + callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), + "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); return result; } @@ -7335,35 +6837,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host.Record hostr = poolr.master.getRecord(conn); if (_host.uuid.equals(hostr.uuid)) { - boolean mastermigrated = false; Map hostMap = Host.getAllRecords(conn); - if (hostMap.size() != 1) { - Host newMaster = null; - Host.Record newMasterRecord = null; - for (Map.Entry entry : hostMap.entrySet()) { - if (_host.uuid.equals(entry.getValue().uuid)) { - continue; - } - newMaster = entry.getKey(); - newMasterRecord = entry.getValue(); - s_logger.debug("New master for the XenPool is " + newMasterRecord.uuid + " : " + newMasterRecord.address); - try { - ConnPool.switchMaster(_host.ip, _host.pool, conn, newMaster, _username, _password, _wait); - mastermigrated = true; - break; - } catch (Exception e) { - s_logger.warn("Unable to switch the new master to " + newMasterRecord.uuid + ": " + newMasterRecord.address + " due to " + e.toString()); - } - } - } else { - s_logger.debug("This is last host to eject, so don't need to eject: " + hostuuid); - return new Answer(cmd); - } - if (!mastermigrated) { - String msg = "this host is master, and cannot designate a new master"; + if (hostMap.size() > 1) { + String msg = "This host is XS master, please designate a new XS master throught XenCenter before you delete this host from CS"; s_logger.debug(msg); return new Answer(cmd, false, msg); - } } @@ -7520,8 +6998,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); String result = - callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", - cmd.getAction()); + callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", + cmd.getAction()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { success = false; } @@ -7529,76 +7007,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, success, ""); } - private Answer execute(SetMonitorServiceCommand cmd) { - boolean success = true; - - String config = cmd.getConfiguration(); - - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - - if (routerIp == null) { - return new Answer(cmd); - } - - String args = "monitor_service.sh " + routerIp; - args += " -c " + config; - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file."); - } - - return new Answer(cmd, success, ""); - - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String[] results = new String[cmd.getRules().length]; - String callResult; - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - if (routerIp == null) { - return new SetFirewallRulesAnswer(cmd, false, results); - } - - String[][] rules = cmd.generateFwRules(); - String args = ""; - args += routerIp + " -F"; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E"; - if (egressDefault.equals("true")) { - args += " -P 1"; - } else if (egressDefault.equals("System")) { - args += " -P 2"; - } else { - args += " -P 0"; - } - } - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - callResult = callHostPlugin(conn, "vmops", "setFirewallRule", "args", args); - - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetFirewallRulesAnswer(cmd, false, results); - } - return new SetFirewallRulesAnswer(cmd, true, results); - } - protected Answer execute(final ClusterSyncCommand cmd) { Connection conn = getConnection(); //check if this is master @@ -7842,28 +7250,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * @param cmd * @return */ - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connection conn = getConnection(); NicTO nic = cmd.getNic(); - String domrIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { Set vms = VM.getByNameLabel(conn, domrName); if (vms == null || vms.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find VM " + domrName); + return new ExecutionResult(false, "Can not find VM " + domrName); } VM vm = vms.iterator().next(); String mac = nic.getMac(); @@ -7876,255 +7270,81 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } if (domrVif == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); + return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName); } - String args = "vpc_guestnw.sh " + domrIP + (cmd.isAdd() ? " -C" : " -D"); - String dev = "eth" + domrVif.getDevice(conn); - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + ((result == null) ? "null" : result)); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + nic.setDeviceId(Integer.valueOf(domrVif.getDevice(conn))); } catch (Exception e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connection conn = getConnection(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(conn, routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); + if (correctVif == null) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + } + } + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); } } catch (Exception e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - Connection conn = getConnection(); - String args = "ipsectunnel.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure site to site VPN failed! "); - } - return new Answer(cmd); - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); IpAddressTO pubIp = cmd.getIpAddress(); try { VM router = getVM(conn, routerName); VIF correctVif = getCorrectVif(conn, router, pubIp); - String args = "vpc_snat.sh " + routerIp; + pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_snat\" failed."); - } - return new SetSourceNatAnswer(cmd, true, "success"); } catch (Exception e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - String callResult; + protected ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); try { VM router = getVM(conn, routerName); - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - } NicTO nic = cmd.getNic(); VIF vif = getVifByMac(conn, router, nic.getMac()); - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - String args = "vpc_privategw_acl.sh " + routerIp; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -a " + sb.toString(); - - callResult = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - String args = "vpc_acl.sh " + routerIp; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - callResult = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } - return new SetNetworkACLAnswer(cmd, true, results); + nic.setDeviceId(Integer.valueOf(vif.getDevice(conn))); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - Connection conn = getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = "vpc_portforwarding.sh " + routerIp; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args.toString()); - - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - String callResult; - Connection conn = getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - try { - String[] results = new String[cmd.getStaticRoutes().length]; - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int i = 0; i < srRules.length; i++) { - sb.append(srRules[i]).append(','); - } - String args = "vpc_staticroute.sh " + routerIp; - args += " -a " + sb.toString(); - callResult = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (callResult == null || callResult.isEmpty()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetStaticRouteAnswer(cmd, false, results); - } - return new SetStaticRouteAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetStaticRoute failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetStaticRouteAnswer(cmd, false, null); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } @Override diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index df43430d481..7e26a5cdb22 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -16,25 +16,6 @@ // under the License. package com.cloud.hypervisor.xen.resource; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; - -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Types.IpConfigurationMode; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; @@ -47,6 +28,22 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.IpConfigurationMode; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import javax.ejb.Local; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { @@ -127,7 +124,7 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - String args = "netusage.sh " + privateIpAddress + " "; + String args = ""; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -142,7 +139,7 @@ public class XenServer56Resource extends CitrixResourceBase { args += vif; } - return callHostPlugin(conn, "vmops", "routerProxy", "args", args); + return executeInVR(privateIpAddress, "netusage.sh", args).getDetails(); } protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { @@ -151,8 +148,7 @@ public class XenServer56Resource extends CitrixResourceBase { String option = cmd.getOption(); String publicIp = cmd.getGatewayIP(); - String args = "vpc_netusage.sh " + cmd.getPrivateIP(); - args += " -l " + publicIp + " "; + String args = " -l " + publicIp + " "; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -169,7 +165,7 @@ public class XenServer56Resource extends CitrixResourceBase { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + String result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args).getDetails(); if (option.equals("get") || option.equals("vpn")) { long[] stats = new long[2]; if (result != null) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java index e797449b0cb..b779085f93c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java @@ -26,7 +26,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Queue; -import java.util.Set; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -43,7 +42,6 @@ import com.xensource.xenapi.Pool; import com.xensource.xenapi.Session; import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.BadServerResponse; -import com.xensource.xenapi.Types.UuidInvalid; import com.xensource.xenapi.Types.XenAPIException; import com.cloud.utils.NumbersUtil; @@ -55,7 +53,6 @@ public class XenServerConnectionPool { protected HashMap _conns = new HashMap(); protected int _retries; protected int _interval; - protected static boolean s_managePool = true; protected static long s_sleepOnError = 10 * 1000; // in ms static { File file = PropertiesUtil.findConfigFile("environment.properties"); @@ -68,15 +65,11 @@ public class XenServerConnectionPool { final Properties props = new Properties(); props.load(finputstream); finputstream.close(); - String search = props.getProperty("manage.xenserver.pool.master"); - if (search != null) { - s_managePool = Boolean.parseBoolean(search); - } - search = props.getProperty("sleep.interval.on.error"); + String search = props.getProperty("sleep.interval.on.error"); if (search != null) { s_sleepOnError = NumbersUtil.parseInterval(search, 10) * 1000; } - s_logger.info("XenServer Connection Pool Configs: manage.xenserver.pool.master=" + s_managePool + "; sleep.interval.on.error=" + s_sleepOnError); + s_logger.info("XenServer Connection Pool Configs: sleep.interval.on.error=" + s_sleepOnError); } catch (FileNotFoundException e) { s_logger.debug("File is not found", e); } catch (IOException e) { @@ -214,288 +207,27 @@ public class XenServerConnectionPool { return false; } - public void switchMaster(String slaveIp, String poolUuid, Connection conn, Host host, String username, Queue password, int wait) throws XmlRpcException, - XenAPIException { - synchronized (poolUuid.intern()) { - String masterIp = host.getAddress(conn); - s_logger.debug("Designating the new master to " + masterIp); - Pool.designateNewMaster(conn, host); - Connection slaveConn = null; - Connection masterConn = null; - int retry = 30; - for (int i = 0; i < retry; i++) { - forceSleep(5); - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Logging on as the slave to " + slaveIp); - } - slaveConn = null; - masterConn = null; - Session slaveSession = null; - slaveConn = new Connection(getURL(slaveIp), 10); - slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Slave logon successful. session= " + slaveSession); - } - - Pool.Record pr = getPoolRecord(slaveConn); - Host master = pr.master; - String ma = master.getAddress(slaveConn); - if (!ma.trim().equals(masterIp.trim())) { - continue; - } - s_logger.debug("Logging on as the master to " + masterIp); - masterConn = new Connection(getURL(masterIp), 10); - loginWithPassword(masterConn, username, password, APIVersion.latest().toString()); - removeConnect(poolUuid); - ensurePoolIntegrity(masterConn, masterIp, username, password, wait); - return; - } catch (Types.HostIsSlave e) { - s_logger.debug("HostIsSlaveException: Still waiting for the conversion to the master"); - } catch (XmlRpcException e) { - s_logger.debug("XmlRpcException: Still waiting for the conversion to the master " + e.getMessage()); - } catch (Exception e) { - s_logger.debug("Exception: Still waiting for the conversion to the master" + e.getMessage()); - } finally { - if (masterConn != null) { - try { - Session.logout(masterConn); - } catch (Exception e) { - s_logger.debug("Unable to log out of session: " + e.getMessage()); - } - masterConn.dispose(); - masterConn = null; - } - localLogout(slaveConn); - slaveConn = null; - } - } - throw new CloudRuntimeException("Unable to logon to the new master after " + retry + " retries"); - } - } - - private void localLogout(Connection conn) { - if (conn == null) - return; + public Connection getConnect(String ip, String username, Queue password) { + Connection conn = new Connection(getURL(ip), 10); try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Logging out of the session " + conn.getSessionReference()); - } - Session.localLogout(conn); - } catch (Exception e) { - s_logger.debug("localLogout has problem " + e.getMessage()); - } finally { - conn.dispose(); - conn = null; - } - } - - public Connection slaveConnect(String ip, String username, Queue password) { - Connection conn = null; - try { - conn = new Connection(getURL(ip), 10); - slaveLocalLoginWithPassword(conn, username, password); - return conn; - } catch (Exception e) { - s_logger.debug("Failed to slave local login to " + ip); - } - return null; - } - - public Connection masterConnect(String ip, String username, Queue password) { - Connection conn = null; - try { - conn = new Connection(getURL(ip), 10); - s_logger.debug("Logging on as the master to " + ip); loginWithPassword(conn, username, password, APIVersion.latest().toString()); - return conn; - } catch (Exception e) { - s_logger.debug("Failed to slave local login to " + ip); - } - throw new RuntimeException("can not log in to master " + ip); - } - - public String getMasterIp(String ip, String username, Queue password) throws XenAPIException { - Connection slaveConn = null; - try { - slaveConn = new Connection(getURL(ip), 10); - slaveLocalLoginWithPassword(slaveConn, username, password); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Slave logon to " + ip); - } - String masterIp = null; - Pool.Record pr = getPoolRecord(slaveConn); - Host master = pr.master; - masterIp = master.getAddress(slaveConn); - return masterIp; - } catch (Types.SessionAuthenticationFailed e) { - s_logger.debug("Failed to slave local login to " + ip + " due to " + e.toString()); - throw e; - } catch (Exception e) { - s_logger.debug("Failed to slave local login to " + ip + " due to " + e.toString()); - } finally { - localLogout(slaveConn); - slaveConn = null; - } - throw new RuntimeException("can not get master ip"); - } - - void PoolEmergencyTransitionToMaster(String slaveIp, String username, Queue password) { - if (!s_managePool) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Don't manage pool on error so sleeping for " + s_sleepOnError); - try { - Thread.sleep(s_sleepOnError); - } catch (InterruptedException ie) { - } - } - return; - } - - Connection slaveConn = null; - Connection c = null; - try { - s_logger.debug("Trying to transition master to " + slaveIp); - slaveConn = new Connection(getURL(slaveIp), 10); - slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.emergencyTransitionToMaster(slaveConn); - // restart xapi in 10 sec - forceSleep(10); - // check if the master of this host is set correctly. - c = new Connection(getURL(slaveIp), 10); - for (int i = 0; i < 30; i++) { - try { - loginWithPassword(c, username, password, APIVersion.latest().toString()); - s_logger.debug("Succeeded to transition master to " + slaveIp); - return; - } catch (Types.HostIsSlave e) { - s_logger.debug("HostIsSlave: Still waiting for the conversion to the master " + slaveIp); - } catch (Exception e) { - s_logger.debug("Exception: Still waiting for the conversion to the master"); - } - forceSleep(2); - } - throw new RuntimeException("EmergencyTransitionToMaster failed after retry 30 times"); - } catch (Exception e) { - throw new RuntimeException("EmergencyTransitionToMaster failed due to " + e.getMessage()); - } finally { - localLogout(slaveConn); - slaveConn = null; - if (c != null) { - try { - Session.logout(c); - c.dispose(); - } catch (Exception e) { - } - } - } - - } - - private void PoolEmergencyResetMaster(String slaveIp, String masterIp, String username, Queue password) { - if (!s_managePool) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Don't manage pool on error so sleeping for " + s_sleepOnError); - try { - Thread.sleep(s_sleepOnError); - } catch (InterruptedException ie) { - } - } - return; - } - - Connection slaveConn = null; - try { - s_logger.debug("Trying to reset master of slave " + slaveIp + " to " + masterIp); - slaveConn = new Connection(getURL(slaveIp), 10); - slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.emergencyResetMaster(slaveConn, masterIp); - forceSleep(10); - for (int i = 0; i < 30; i++) { - try { - slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.Record pr = getPoolRecord(slaveConn); - String mIp = pr.master.getAddress(slaveConn); - if (mIp.trim().equals(masterIp.trim())) { - s_logger.debug("Succeeded to reset master of slave " + slaveIp + " to " + masterIp); - return; - } - } catch (Exception e) { - } finally { - localLogout(slaveConn); - slaveConn = null; - } - // wait 2 second - forceSleep(2); - } - throw new CloudRuntimeException("Unable to reset master of slave " + slaveIp + " to " + masterIp + "after 30 retry"); - } catch (Exception e) { - throw new CloudRuntimeException("Unable to reset master of slave " + slaveIp + " to " + masterIp + " due to " + e.toString()); - } finally { - localLogout(slaveConn); - slaveConn = null; - } - } - - protected void ensurePoolIntegrity(Connection conn, String masterIp, String username, Queue password, int wait) { - try { - // try recoverSlave first - Set rcSlaves = Pool.recoverSlaves(conn); - // wait 10 second - forceSleep(10); - for (Host slave : rcSlaves) { - for (int i = 0; i < 30; i++) { - Connection slaveConn = null; - try { - - String slaveIp = slave.getAddress(conn); - s_logger.debug("Logging on as the slave to " + slaveIp); - slaveConn = new Connection(getURL(slaveIp), 10); - slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.Record pr = getPoolRecord(slaveConn); - String mIp = pr.master.getAddress(slaveConn); - if (mIp.trim().equals(masterIp.trim())) { - break; - } - } catch (Exception e) { - } finally { - localLogout(slaveConn); - slaveConn = null; - } - // wait 2 second - forceSleep(2); - } - } - // then try emergency reset master - Set slaves = Host.getAll(conn); - for (Host slave : slaves) { - String slaveIp = slave.getAddress(conn); - Connection slaveConn = null; - try { - s_logger.debug("Logging on as the slave to " + slaveIp); - - slaveConn = new Connection(getURL(slaveIp), 10); - slaveLocalLoginWithPassword(slaveConn, username, password); - Pool.Record slavePoolr = getPoolRecord(slaveConn); - String ip = slavePoolr.master.getAddress(slaveConn); - if (!masterIp.trim().equals(ip.trim())) { - PoolEmergencyResetMaster(slaveIp, masterIp, username, password); - } - } catch (Exception e) { - s_logger.debug("Unable to login to slave " + slaveIp + " error " + e.getMessage()); - } finally { - localLogout(slaveConn); - slaveConn = null; - } + } catch (Types.HostIsSlave e) { + String maddress = e.masterIPAddress; + conn = new Connection(getURL(maddress), 10); + try { + loginWithPassword(conn, username, password, APIVersion.latest().toString()); + } catch (Exception e1) { + String msg = "Unable to create master connection to host(" + maddress +") , due to " + e1.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e1); } } catch (Exception e) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Catch " + e.getClass().getName() + " due to " + e.toString()); - } + String msg = "Unable to create master connection to host(" + ip +") , due to " + e.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e); } + return conn; } public URL getURL(String ip) { @@ -512,39 +244,17 @@ public class XenServerConnectionPool { public Connection connect(String hostUuid, String poolUuid, String ipAddress, String username, Queue password, int wait) { XenServerConnection mConn = null; - Connection sConn = null; - String masterIp = null; if (hostUuid == null || poolUuid == null || ipAddress == null || username == null || password == null) { String msg = "Connect some parameter are null hostUuid:" + hostUuid + " ,poolUuid:" + poolUuid + " ,ipAddress:" + ipAddress; s_logger.debug(msg); throw new CloudRuntimeException(msg); } - Host host = null; synchronized (poolUuid.intern()) { // Let's see if it is an existing connection. mConn = getConnect(poolUuid); - if (mConn != null) { - try { - host = Host.getByUuid(mConn, hostUuid); - } catch (Types.SessionInvalid e) { - s_logger.debug("Session thgrough ip " + mConn.getIp() + " is invalid for pool(" + poolUuid + ") due to " + e.toString()); - try { - loginWithPassword(mConn, mConn.getUsername(), mConn.getPassword(), APIVersion.latest().toString()); - } catch (Exception e1) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("connect through IP(" + mConn.getIp() + " for pool(" + poolUuid + ") is broken due to " + e.toString()); - } - removeConnect(poolUuid); - mConn = null; - } - } catch (UuidInvalid e) { - String msg = - "Host(" + hostUuid + ") doesn't belong to pool(" + poolUuid + "), please execute 'xe pool-join master-address=" + mConn.getIp() + - " master-username=" + mConn.getUsername(); - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg, e); + if (mConn != null){ + try{ + Host.getByUuid(mConn, hostUuid); } catch (Exception e) { if (s_logger.isDebugEnabled()) { s_logger.debug("connect through IP(" + mConn.getIp() + " for pool(" + poolUuid + ") is broken due to " + e.toString()); @@ -554,114 +264,30 @@ public class XenServerConnectionPool { } } - if (mConn == null) { + if ( mConn == null ) { + mConn = new XenServerConnection(getURL(ipAddress), ipAddress, username, password, _retries, _interval, wait); try { + loginWithPassword(mConn, username, password, APIVersion.latest().toString()); + } catch (Types.HostIsSlave e) { + String maddress = e.masterIPAddress; + mConn = new XenServerConnection(getURL(maddress), maddress, username, password, _retries, _interval, wait); try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Logging on as the slave to " + ipAddress); - } - sConn = new Connection(getURL(ipAddress), 5); - slaveLocalLoginWithPassword(sConn, username, password); - } catch (Exception e) { - String msg = "Unable to create slave connection to host(" + hostUuid + ") due to " + e.toString(); - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg, e); - } - Pool.Record pr = null; - try { - pr = getPoolRecord(sConn); - } catch (Exception e) { - PoolEmergencyTransitionToMaster(ipAddress, username, password); - mConn = new XenServerConnection(getURL(ipAddress), ipAddress, username, password, _retries, _interval, wait); - try { - loginWithPassword(mConn, username, password, APIVersion.latest().toString()); - pr = getPoolRecord(mConn); - } catch (Exception e1) { - String msg = "Unable to create master connection to host(" + hostUuid + ") after transition it to master, due to " + e1.toString(); - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg, e1); - } - if (!pr.uuid.equals(poolUuid)) { - String msg = "host(" + hostUuid + ") should be in pool(" + poolUuid + "), but it is actually in pool(" + pr.uuid + ")"; - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg); - } else { - if (s_managePool) { - ensurePoolIntegrity(mConn, ipAddress, username, password, wait); - } - addConnect(poolUuid, mConn); - return mConn; - } - } - if (!pr.uuid.equals(poolUuid)) { - String msg = "host(" + hostUuid + ") should be in pool(" + poolUuid + "), but it is actually in pool(" + pr.uuid + ")"; - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg); - } - try { - masterIp = pr.master.getAddress(sConn); - mConn = new XenServerConnection(getURL(masterIp), masterIp, username, password, _retries, _interval, wait); loginWithPassword(mConn, username, password, APIVersion.latest().toString()); - addConnect(poolUuid, mConn); - return mConn; - } catch (Exception e) { - String msg = "Unable to logon in " + masterIp + " as master in pool(" + poolUuid + ")"; - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - throw new CloudRuntimeException(msg); + } catch (Exception e1) { + String msg = "Unable to create master connection to host(" + maddress +") , due to " + e1.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e1); + } - } finally { - localLogout(sConn); - sConn = null; + } catch (Exception e) { + String msg = "Unable to create master connection to host(" + ipAddress +") , due to " + e.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e); } + addConnect(poolUuid, mConn); } } - if (mConn != null) { - if (s_managePool) { - try { - Map args = new HashMap(); - host.callPlugin(mConn, "echo", "main", args); - } catch (Types.SessionInvalid e) { - if (s_logger.isDebugEnabled()) { - String msg = "Catch Exception: " + e.getClass().getName() + " Can't connect host " + ipAddress + " due to " + e.toString(); - s_logger.debug(msg); - } - PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword()); - } catch (Types.CannotContactHost e) { - if (s_logger.isDebugEnabled()) { - String msg = "Catch Exception: " + e.getClass().getName() + " Can't connect host " + ipAddress + " due to " + e.toString(); - s_logger.debug(msg); - } - PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword()); - } catch (Types.HostOffline e) { - if (s_logger.isDebugEnabled()) { - String msg = "Catch Exception: " + e.getClass().getName() + " Host is offline " + ipAddress + " due to " + e.toString(); - s_logger.debug(msg); - } - PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword()); - } catch (Types.HostNotLive e) { - String msg = "Catch Exception: " + e.getClass().getName() + " Host Not Live " + ipAddress + " due to " + e.toString(); - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword()); - } catch (Exception e) { - String msg = "Echo test failed on host " + hostUuid + " IP " + ipAddress; - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } - } - } return mConn; } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 5d2363f3b90..f2abff74f80 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -185,7 +185,7 @@ public class XenServerStorageProcessor implements StorageProcessor { catch (CloudRuntimeException ex) { } - Map details = cmd.getDisk().getDetails(); + Map details = disk.getDetails(); boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here) @@ -197,19 +197,7 @@ public class XenServerStorageProcessor implements StorageProcessor { VDI vdi = null; if (isManaged) { - String iScsiName = details.get(DiskTO.IQN); - String storageHost = details.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = disk.getDetails().get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = disk.getDetails().get(DiskTO.CHAP_INITIATOR_SECRET); - Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE)); - - SR sr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); - - vdi = hypervisorResource.getVDIbyUuid(conn, data.getPath(), false); - - if (vdi == null) { - vdi = hypervisorResource.createVdi(sr, vdiNameLabel, volumeSize); - } + vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel); if (vmNotRunning) { DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType()); diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index f2bf47262ca..e8217f7216f 100644 --- a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -106,7 +106,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -126,7 +126,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -153,7 +153,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } MigrateWithStorageSendCommand sendCmd = - new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); + new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); MigrateWithStorageSendAnswer sendAnswer = (MigrateWithStorageSendAnswer)agentMgr.send(srcHost.getId(), sendCmd); if (sendAnswer == null) { s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed."); @@ -184,7 +184,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { diff --git a/plugins/network-elements/dns-notifier/resources/components-example.xml b/plugins/network-elements/dns-notifier/resources/components-example.xml index 418835a299f..5977387a28b 100755 --- a/plugins/network-elements/dns-notifier/resources/components-example.xml +++ b/plugins/network-elements/dns-notifier/resources/components-example.xml @@ -185,7 +185,6 @@ under the License. - diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 56900feeaeb..6dd0f8a3f93 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -34,14 +34,14 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerRuleCmd; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -52,7 +52,6 @@ import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.agent.manager.Commands; -import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -802,7 +801,7 @@ public class ElasticLoadBalancerManagerImpl extends ManagerBase implements Elast if (s_logger.isInfoEnabled()) { s_logger.info("Check if we need to add management server explicit route to ELB vm. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + - ClusterManager.ManagementHostIPAdr.value()); + ApiServiceConfiguration.ManagementHostIPAdr.value()); } if (s_logger.isDebugEnabled()) { diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 7b377a0cb59..8c6877dfb90 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -82,10 +82,15 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-framework-spring-lifecycle + ${project.version} + test + com.google.guava guava - ${cs.guava.version} net.juniper.contrail @@ -95,7 +100,6 @@ mysql mysql-connector-java - ${cs.mysql.version} provided diff --git a/scripts/network/domr/call_dnsmasq.sh b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties old mode 100755 new mode 100644 similarity index 75% rename from scripts/network/domr/call_dnsmasq.sh rename to plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties index 81c218d0e7b..ced0f3addc7 --- a/scripts/network/domr/call_dnsmasq.sh +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties @@ -1,4 +1,3 @@ -#!/usr/bin/env bash # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,13 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - -usage() { - printf "Usage: %s: \n" $(basename $0) >&2 -} - -cert="/root/.ssh/id_rsa.cloud" - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$1 "/root/dnsmasq.sh $2" -exit $? - +name=contrail +parent=network \ No newline at end of file diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml new file mode 100644 index 00000000000..4614af79a4b --- /dev/null +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java index 5adbacdbbe4..05723b04447 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -42,6 +41,10 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.resource.ResourceManager; + import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; @@ -51,6 +54,8 @@ import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; import com.cloud.network.element.IpDeployer; import com.cloud.network.element.StaticNatServiceProvider; +import com.cloud.network.element.SourceNatServiceProvider; +import com.cloud.network.element.DhcpServiceProvider; import com.cloud.network.rules.StaticNat; import com.cloud.offering.NetworkOffering; import com.cloud.utils.component.AdapterBase; @@ -60,13 +65,22 @@ import com.cloud.vm.ReservationContext; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; +import com.cloud.server.ConfigurationServer; +import com.cloud.server.ConfigurationServerImpl; @Component -@Local(value = {ContrailElement.class, StaticNatServiceProvider.class}) -public class ContrailElementImpl extends AdapterBase implements ContrailElement, IpDeployer, StaticNatServiceProvider { +@Local(value = {ContrailElement.class, StaticNatServiceProvider.class, IpDeployer.class, SourceNatServiceProvider.class}) +public class ContrailElementImpl extends AdapterBase + implements ContrailElement, StaticNatServiceProvider, IpDeployer, SourceNatServiceProvider, DhcpServiceProvider { private final Map> _capabilities = InitCapabilities(); + @Inject + ResourceManager _resourceMgr; + @Inject + ConfigurationServer _configServer; + @Inject + NetworkDao _networksDao; @Inject ContrailManager _manager; @Inject @@ -75,12 +89,6 @@ public class ContrailElementImpl extends AdapterBase implements ContrailElement, ServerDBSync _dbSync; private static final Logger s_logger = Logger.getLogger(ContrailElement.class); - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - s_logger.debug("configure"); - return true; - } - // PluggableService @Override public List> getCommands() { @@ -92,7 +100,7 @@ public class ContrailElementImpl extends AdapterBase implements ContrailElement, // NetworkElement API @Override public Provider getProvider() { - return Provider.JuniperContrail; + return Provider.JuniperContrailRouter; } private static Map> InitCapabilities() { @@ -261,8 +269,34 @@ public class ContrailElementImpl extends AdapterBase implements ContrailElement, @Override public boolean isReady(PhysicalNetworkServiceProvider provider) { - return true; - } + Map serviceMap = ((ConfigurationServerImpl)_configServer).getServicesAndProvidersForNetwork( _manager.getRouterOffering().getId()); + List types = new ArrayList(); + types.add(TrafficType.Control); + types.add(TrafficType.Management); + types.add(TrafficType.Storage); + List systemNets = _manager.findSystemNetworks(types); + if (systemNets != null && !systemNets.isEmpty()) { + for (NetworkVO net: systemNets) { + s_logger.debug("update system network service: " + net.getName() + "; service provider: " + serviceMap); + _networksDao.update(net.getId(), net, serviceMap); + } + } else { + s_logger.debug("no system networks created yet"); + } + serviceMap = ((ConfigurationServerImpl)_configServer).getServicesAndProvidersForNetwork( _manager.getPublicRouterOffering().getId()); + types = new ArrayList(); + types.add(TrafficType.Public); + systemNets = _manager.findSystemNetworks(types); + if (systemNets != null && !systemNets.isEmpty()) { + for (NetworkVO net: systemNets) { + s_logger.debug("update system network service: " + net.getName() + "; service provider: " + serviceMap); + _networksDao.update(net.getId(), net, serviceMap); + } + } else { + s_logger.debug("no system networks created yet"); + } + return true; + } @Override public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, @@ -320,4 +354,28 @@ public class ContrailElementImpl extends AdapterBase implements ContrailElement, } return false; } + + @Override + public boolean addDhcpEntry(Network network, NicProfile nic, + VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, + ResourceUnavailableException { + return false; + } + + @Override + public boolean configDhcpSupportForSubnet(Network network, NicProfile nic, + VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, + ResourceUnavailableException { + return false; + } + + @Override + public boolean removeDhcpSupportForSubnet(Network network) + throws ResourceUnavailableException { + return false; + } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index 079035b9864..704dedd4a3c 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -18,14 +18,15 @@ package org.apache.cloudstack.network.contrail.management; import java.io.IOException; +import java.net.URI; import javax.inject.Inject; +import javax.ejb.Local; import net.juniper.contrail.api.types.MacAddressesType; import net.juniper.contrail.api.types.VirtualMachineInterface; import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import org.apache.cloudstack.network.contrail.model.InstanceIpModel; import org.apache.cloudstack.network.contrail.model.VMInterfaceModel; @@ -37,6 +38,9 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.network.Network; import com.cloud.network.Network.State; import com.cloud.network.NetworkProfile; @@ -47,6 +51,9 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.guru.NetworkGuru; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -55,12 +62,15 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic.ReservationStrategy; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.user.AccountManager; +import com.cloud.network.IpAddressManager; import com.cloud.vm.ReservationContext; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.NicDao; -@Component +@Local(value = {NetworkGuru.class}) public class ContrailGuru extends AdapterBase implements NetworkGuru { @Inject NetworkDao _networkDao; @@ -68,12 +78,29 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { ContrailManager _manager; @Inject NicDao _nicDao; + @Inject + IPAddressDao _ipAddressDao; + @Inject + AccountManager _accountMgr; + @Inject + IpAddressManager _ipAddrMgr; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + DataCenterDao _dcDao; private static final Logger s_logger = Logger.getLogger(ContrailGuru.class); private static final TrafficType[] TrafficTypes = {TrafficType.Guest}; - private boolean canHandle(NetworkOffering offering) { - return (offering.getName().equals(ContrailManager.offeringName)); + private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) { + if (networkType == NetworkType.Advanced + && offering.getId() == _manager.getRouterOffering().getId() + && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated + && physicalNetwork.getIsolationMethods().contains("L3VPN")) + return true; + + return false; } @Override @@ -83,7 +110,11 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { - if (!canHandle(offering)) { + // Check of the isolation type of the related physical network is L3VPN + PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId()); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + if (!canHandle(offering, dc.getNetworkType(),physnet)) { + s_logger.debug("Refusing to design this network"); return null; } NetworkVO network = @@ -138,6 +169,13 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { } profile.setStrategy(ReservationStrategy.Start); + URI broadcastUri = null; + try { + broadcastUri = new URI("vlan://untagged"); + } catch (Exception e) { + s_logger.warn("unable to instantiate broadcast URI: " + e); + } + profile.setBroadcastUri(broadcastUri); return profile; } @@ -215,7 +253,9 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { if (nic.getIp4Address() == null) { s_logger.debug("Allocated IP address " + ipModel.getAddress()); nic.setIp4Address(ipModel.getAddress()); - nic.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); + if (network.getCidr() != null) { + nic.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); + } nic.setGateway(network.getGateway()); nic.setFormat(AddressFormat.Ip4); } @@ -282,6 +322,7 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { return; } try { + _manager.getDatabase().getVirtualNetworks().remove(vnModel); vnModel.delete(_manager.getModelController()); } catch (IOException e) { s_logger.warn("virtual-network delete", e); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java index 335299e1776..6853d1efd55 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java @@ -22,6 +22,7 @@ import java.util.List; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.types.FloatingIp; +import net.juniper.contrail.api.types.NetworkPolicy; import net.juniper.contrail.api.types.VirtualNetwork; import org.apache.cloudstack.network.contrail.model.ModelController; @@ -36,16 +37,20 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; import com.cloud.projects.ProjectVO; +import com.cloud.network.vpc.NetworkACLVO; public interface ContrailManager { - public static final String offeringName = "Juniper Contrail offering"; - public static final String offeringDisplayText = "Juniper Contrail network offering"; + public static final String routerOfferingName = "Juniper Contrail Network Offering"; + public static final String routerOfferingDisplayText = "Juniper Contrail Network Offering"; + public static final String routerPublicOfferingName = "Juniper Contrail Public Network Offering"; + public static final String routerPublicOfferingDisplayText = "Juniper Contrail Public Network Offering"; public static final int DB_SYNC_INTERVAL_DEFAULT = 600000; public static final String VNC_ROOT_DOMAIN = "default-domain"; public static final String VNC_DEFAULT_PROJECT = "default-project"; public static final String managementNetworkName = "ip-fabric"; - public NetworkOffering getOffering(); + public NetworkOffering getRouterOffering(); + public NetworkOffering getPublicRouterOffering(); public void syncNetworkDB(short syncMode) throws IOException; @@ -81,6 +86,8 @@ public interface ContrailManager { public net.juniper.contrail.api.types.Project getVncProject(long domainId, long accountId) throws IOException; + public net.juniper.contrail.api.types.Project getDefaultVncProject() throws IOException; + public boolean isSystemRootDomain(net.juniper.contrail.api.types.Domain vnc); public boolean isSystemRootDomain(DomainVO domain); @@ -103,9 +110,13 @@ public interface ContrailManager { public ModelController getModelController(); - public List findJuniperManagedNetworks(List types); + public List findManagedNetworks(List types); - public List findJuniperManagedPublicIps(); + public List findSystemNetworks(List types); + + public List findManagedPublicIps(); + + public List findManagedACLs(); public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType) throws IOException; @@ -113,9 +124,9 @@ public interface ContrailManager { public VirtualNetworkModel lookupPublicNetworkModel(); - public void createPublicNetworks(); - public boolean createFloatingIp(PublicIpAddress ip); public boolean deleteFloatingIp(PublicIpAddress ip); + + public boolean isSystemDefaultNetworkPolicy(NetworkPolicy policy); } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java index ed5859494f6..ef76e4cee49 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java @@ -21,7 +21,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -34,6 +33,7 @@ import java.util.TimerTask; import javax.inject.Inject; import javax.naming.ConfigurationException; +import javax.ejb.Local; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.ApiConnectorFactory; @@ -41,11 +41,11 @@ import net.juniper.contrail.api.ApiPropertyBase; import net.juniper.contrail.api.ObjectReference; import net.juniper.contrail.api.types.FloatingIp; import net.juniper.contrail.api.types.FloatingIpPool; +import net.juniper.contrail.api.types.NetworkPolicy; import net.juniper.contrail.api.types.VirtualNetwork; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.google.common.collect.ImmutableList; @@ -56,13 +56,13 @@ import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ConfigurationService; +import com.cloud.server.ConfigurationServer; import com.cloud.dc.DataCenter; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; -import com.cloud.exception.InternalErrorException; import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -75,17 +75,17 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkVO; -import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; -import com.cloud.offering.NetworkOffering.State; +import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.projects.ProjectVO; +import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.NetworkACLVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.user.Account; import com.cloud.user.dao.AccountDao; import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.component.ComponentLifecycle; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -95,13 +95,14 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -@Component +@Local(value = { ContrailManager.class}) public class ContrailManagerImpl extends ManagerBase implements ContrailManager { @Inject public ConfigurationService _configService; @Inject + ConfigurationServer _configServer; + @Inject NetworkOfferingDao _networkOfferingDao; - @Inject DomainDao _domainDao; @Inject @@ -130,12 +131,16 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager VlanDao _vlanDao; @Inject UserVmDao _vmDao; + @Inject + NetworkACLDao _networkAclDao; private static final Logger s_logger = Logger.getLogger(ContrailManager.class); private ApiConnector _api; private NetworkOffering _offering; + private NetworkOffering _routerOffering; + private NetworkOffering _routerPublicOffering; private Timer _dbSyncTimer; private int _dbSyncInterval = DB_SYNC_INTERVAL_DEFAULT; private final String configuration = "contrail.properties"; @@ -143,7 +148,6 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager private ModelController _controller; ContrailManagerImpl() { - setRunLevel(ComponentLifecycle.RUN_LEVEL_COMPONENT); _database = new ModelDatabase(); } @@ -171,20 +175,55 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _database; } - private NetworkOffering LocateOffering() { - List offerList = _configService.listNetworkOfferings(TrafficType.Guest, false); - for (NetworkOffering offer : offerList) { + private NetworkOffering LocatePublicNetworkOffering(String offeringName, + String offeringDisplayText, Provider provider) { + List offerList = _configService.listNetworkOfferings(TrafficType.Public, false); + for (NetworkOffering offer: offerList) { if (offer.getName().equals(offeringName)) { - if (offer.getState() != State.Enabled) { + if (offer.getState() != NetworkOffering.State.Enabled) { return EnableNetworkOffering(offer.getId()); } return offer; } } Map> serviceProviderMap = new HashMap>(); - // Map> serviceCapabilityMap = new HashMap>(); Set providerSet = new HashSet(); - providerSet.add(Provider.JuniperContrail); + providerSet.add(provider); + final Service[] services = { + Service.Connectivity, + Service.Dhcp, + Service.NetworkACL, + Service.StaticNat, + Service.SourceNat + }; + for (Service svc: services) { + serviceProviderMap.put(svc, providerSet); + } + ConfigurationManager configMgr = (ConfigurationManager) _configService; + NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText, + TrafficType.Public, null, true, Availability.Optional, null, serviceProviderMap, true, + Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false); + + voffer.setState(NetworkOffering.State.Enabled); + long id = voffer.getId(); + _networkOfferingDao.update(id, voffer); + return _networkOfferingDao.findById(id); + } + + private NetworkOffering LocateNetworkOffering(String offeringName, + String offeringDisplayText, Provider provider) { + List offerList = _configService.listNetworkOfferings(TrafficType.Guest, false); + for (NetworkOffering offer : offerList) { + if (offer.getName().equals(offeringName)) { + if (offer.getState() != NetworkOffering.State.Enabled) { + return EnableNetworkOffering(offer.getId()); + } + return offer; + } + } + Map> serviceProviderMap = new HashMap>(); + Set providerSet = new HashSet(); + providerSet.add(provider); final Service[] services = {Service.Connectivity, Service.Dhcp, Service.NetworkACL, Service.StaticNat, Service.SourceNat}; for (Service svc : services) { serviceProviderMap.put(svc, providerSet); @@ -194,7 +233,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true, Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false); - voffer.setState(State.Enabled); + voffer.setState(NetworkOffering.State.Enabled); long id = voffer.getId(); _networkOfferingDao.update(id, voffer); return _networkOfferingDao.findById(id); @@ -202,7 +241,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager private NetworkOffering EnableNetworkOffering(long id) { NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id); - offering.setState(State.Enabled); + offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(id, offering); return _networkOfferingDao.findById(id); } @@ -211,29 +250,41 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public boolean configure(String name, Map params) throws ConfigurationException { File configFile = PropertiesUtil.findConfigFile(configuration); - final Properties configProps = new Properties(); try { - configProps.load(new FileInputStream(configFile)); - String value = configProps.getProperty("management.db_sync_interval"); - if (value != null) { - _dbSyncInterval = Integer.valueOf(value); - } - - String hostname = configProps.getProperty("api.hostname"); - String portStr = configProps.getProperty("api.port"); + String hostname = null; int port = 0; - if (portStr != null && portStr.length() > 0) { - port = Integer.parseInt(portStr); + if (configFile == null) { + hostname = "localhost"; + port = 8082; + } else { + final Properties configProps = new Properties(); + configProps.load(new FileInputStream(configFile)); + String value = configProps.getProperty("management.db_sync_interval"); + if (value != null) { + _dbSyncInterval = Integer.valueOf(value); + } + hostname = configProps.getProperty("api.hostname"); + String portStr = configProps.getProperty("api.port"); + if (portStr != null && portStr.length() > 0) { + port = Integer.parseInt(portStr); + } } _api = ApiConnectorFactory.build(hostname, port); } catch (IOException ex) { s_logger.warn("Unable to read " + configuration, ex); throw new ConfigurationException(); + } catch (Exception ex) { + s_logger.debug("Exception in configure: " + ex); + ex.printStackTrace(); + throw new ConfigurationException(); } _controller = new ModelController(this, _api, _vmDao, _networksDao, _nicDao, _vlanDao, _ipAddressDao); - _offering = LocateOffering(); + _routerOffering = LocateNetworkOffering(routerOfferingName, routerOfferingDisplayText, + Provider.JuniperContrailRouter); + _routerPublicOffering = LocatePublicNetworkOffering(routerPublicOfferingName, routerPublicOfferingDisplayText, + Provider.JuniperContrailRouter); _eventHandler.subscribe(); @@ -243,8 +294,13 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager } @Override - public NetworkOffering getOffering() { - return _offering; + public NetworkOffering getPublicRouterOffering() { + return _routerPublicOffering; + } + + @Override + public NetworkOffering getRouterOffering() { + return _routerOffering; } @Override @@ -340,11 +396,18 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public net.juniper.contrail.api.types.Project getVncProject(long domainId, long accountId) throws IOException { String projectId = getProjectId(domainId, accountId); if (projectId == null) { - return null; + return getDefaultVncProject(); } return (net.juniper.contrail.api.types.Project)_api.findById(net.juniper.contrail.api.types.Project.class, projectId); } + @Override + public net.juniper.contrail.api.types.Project getDefaultVncProject() throws IOException { + net.juniper.contrail.api.types.Project project = null; + project = (net.juniper.contrail.api.types.Project)_api.findByFQN(net.juniper.contrail.api.types.Project.class, VNC_ROOT_DOMAIN + ":" + VNC_DEFAULT_PROJECT); + return project; + } + @Override public String getFQN(Network net) { // domain, project, name @@ -402,7 +465,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public boolean isManagedPhysicalNetwork(Network network) { List net_list = _physicalNetworkDao.listByZone(network.getDataCenterId()); for (PhysicalNetworkVO phys : net_list) { - if (_physProviderDao.findByServiceProvider(phys.getId(), Network.Provider.JuniperContrail.getName()) != null) { + if (_physProviderDao.findByServiceProvider(phys.getId(), Network.Provider.JuniperContrailRouter.getName()) != null) { return true; } } @@ -427,6 +490,53 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _api.findByName(VirtualNetwork.class, fqn); } + @Override + public List findSystemNetworks(List types) { + SearchBuilder searchBuilder = _networksDao.createSearchBuilder(); + searchBuilder.and("trafficType", searchBuilder.entity().getTrafficType(), Op.IN); + SearchCriteria sc = searchBuilder.create(); + if (types == null || types.isEmpty()) { + types = new ArrayList(); + types.add(TrafficType.Control); + types.add(TrafficType.Management); + types.add(TrafficType.Public); + types.add(TrafficType.Storage); + } + sc.setParameters("trafficType", types.toArray()); + List dbNets = _networksDao.search(sc, null); + if (dbNets == null) { + s_logger.debug("no system networks for the given traffic types: " + types.toString()); + dbNets = new ArrayList(); + } + + List phys_list = _physicalNetworkDao.listAll(); + final String provider = Provider.JuniperContrailRouter.getName(); + for (Iterator iter = phys_list.iterator(); iter.hasNext(); ) { + PhysicalNetworkVO phys = iter.next(); + if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null) { + List infraNets = new ArrayList(); + findInfrastructureNetworks(phys, infraNets); + for (NetworkVO net:infraNets) { + if (types == null || types.isEmpty()) { + if (!dbNets.contains(net)) { + dbNets.add(net); + } + continue; + } + for(TrafficType type:types) { + if (net.getTrafficType() == type) { + if (!dbNets.contains(net)) { + dbNets.add(net); + } + break; + } + } + } + } + } + return dbNets; + } + @Override public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType) throws IOException { if (trafficType == TrafficType.Guest || trafficType == TrafficType.Public) { @@ -445,14 +555,17 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager * Returns list of networks managed by Juniper VRouter filtered by traffic types */ @Override - public List findJuniperManagedNetworks(List types) { + public List findManagedNetworks(List types) { SearchBuilder searchBuilder = _networksDao.createSearchBuilder(); searchBuilder.and("trafficType", searchBuilder.entity().getTrafficType(), Op.IN); - searchBuilder.and("networkOfferingId", searchBuilder.entity().getNetworkOfferingId(), Op.EQ); + searchBuilder.and("networkOfferingId", searchBuilder.entity().getNetworkOfferingId(), Op.IN); SearchCriteria sc = searchBuilder.create(); - sc.setParameters("networkOfferingId", getOffering().getId()); + List offerings = new ArrayList(); + offerings.add(getRouterOffering().getId()); + offerings.add(getPublicRouterOffering().getId()); + sc.setParameters("networkOfferingId", offerings.toArray()); if (types == null || types.isEmpty()) { types = new ArrayList(); @@ -471,7 +584,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager } List phys_list = _physicalNetworkDao.listAll(); - final String provider = Network.Provider.JuniperContrail.getName(); + final String provider = Network.Provider.JuniperContrailRouter.getName(); for (Iterator iter = phys_list.iterator(); iter.hasNext();) { PhysicalNetworkVO phys = iter.next(); if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null) { @@ -479,12 +592,16 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager findInfrastructureNetworks(phys, infraNets); for (NetworkVO net : infraNets) { if (types == null || types.isEmpty()) { - dbNets.add(net); + if (!dbNets.contains(net)) { + dbNets.add(net); + } continue; } for (TrafficType type : types) { if (net.getTrafficType() == type) { - dbNets.add(net); + if (!dbNets.contains(net)) { + dbNets.add(net); + } break; } } @@ -494,13 +611,19 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return dbNets; } + @Override + public List findManagedACLs() { + /* contrail vpc is not yet implemented */ + return null; + } + /* * Returns list of public ip addresses managed by Juniper VRouter */ @Override - public List findJuniperManagedPublicIps() { + public List findManagedPublicIps() { - List dbNets = findJuniperManagedNetworks(null); + List dbNets = findManagedNetworks(null); if (dbNets == null || dbNets.isEmpty()) { s_logger.debug("Juniper managed networks is empty"); @@ -538,7 +661,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager types.add(TrafficType.Storage); types.add(TrafficType.Control); - List dbNets = findJuniperManagedNetworks(types); + List dbNets = findManagedNetworks(types); for (NetworkVO net : dbNets) { VirtualNetworkModel vnModel = getDatabase().lookupVirtualNetwork(null, getCanonicalName(net), net.getTrafficType()); @@ -647,48 +770,29 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public VirtualNetworkModel lookupPublicNetworkModel() { List types = new ArrayList(); types.add(TrafficType.Public); - List dbNets = findJuniperManagedNetworks(types); + List dbNets = findManagedNetworks(types); if (dbNets == null) { return null; } NetworkVO net = dbNets.get(0); VirtualNetworkModel vnModel = getDatabase().lookupVirtualNetwork(net.getUuid(), getCanonicalName(net), TrafficType.Public); + if (vnModel == null) { + vnModel = new VirtualNetworkModel(net, net.getUuid(), + getCanonicalName(net), net.getTrafficType()); + vnModel.setProperties(getModelController(), net); + } + try { + if (!vnModel.verify(getModelController())) { + vnModel.update(getModelController()); + } + getDatabase().getVirtualNetworks().add(vnModel); + } catch (Exception ex) { + s_logger.warn("virtual-network update: ", ex); + } return vnModel; } - @Override - public void createPublicNetworks() { - List types = new ArrayList(Arrays.asList(TrafficType.Public)); - List dbNets = findJuniperManagedNetworks(types); - if (dbNets == null) { - return; - } - for (NetworkVO net : dbNets) { - VirtualNetworkModel vnModel = _database.lookupVirtualNetwork(net.getUuid(), getCanonicalName(net), TrafficType.Public); - if (vnModel != null) { - continue; - } - vnModel = new VirtualNetworkModel(net, net.getUuid(), getCanonicalName(net), net.getTrafficType()); - vnModel.build(_controller, net); - try { - vnModel.update(_controller); - } catch (InternalErrorException ex) { - s_logger.warn("virtual-network update", ex); - continue; - } catch (IOException ex) { - s_logger.warn("virtual-network update", ex); - continue; - } - _database.getVirtualNetworks().add(vnModel); - - // Add the Contrail NetworkElement to the Public network. - Map providerMap = new HashMap(); - providerMap.put(Service.Connectivity.getName(), Provider.JuniperContrail.getName()); - _networksDao.update(net.getId(), net, providerMap); - } - } - @Override public boolean createFloatingIp(PublicIpAddress ip) { VirtualNetworkModel vnModel = lookupPublicNetworkModel(); @@ -775,4 +879,12 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager } return null; } + + @Override + public boolean isSystemDefaultNetworkPolicy(NetworkPolicy policy) { + if (policy.getName().equals("default-network-policy")) { + return true; + } + return false; + } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java index e2845b7644c..66fad7097b8 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.network.contrail.management; import java.util.TreeSet; import org.apache.cloudstack.network.contrail.model.ModelObjectBase; +import org.apache.cloudstack.network.contrail.model.NetworkPolicyModel; import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel; import org.apache.cloudstack.network.contrail.model.VirtualMachineModel; import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel; @@ -30,6 +31,7 @@ public class ModelDatabase { TreeSet _serviceInstanceTable; TreeSet _vmTable; TreeSet _vnTable; + TreeSet _policyTable; public ModelDatabase() { initDb(); @@ -39,16 +41,17 @@ public class ModelDatabase { _serviceInstanceTable = new TreeSet(new ModelObjectBase.UuidComparator()); _vmTable = new TreeSet(new ModelObjectBase.UuidComparator()); _vnTable = new TreeSet(new ModelObjectBase.UuidComparator()); + _policyTable = new TreeSet(new ModelObjectBase.UuidComparator()); } public TreeSet getServiceInstances() { return _serviceInstanceTable; } - public ServiceInstanceModel lookupServiceInstance(String uuid) { - ServiceInstanceModel siKey = new ServiceInstanceModel(uuid); + public ServiceInstanceModel lookupServiceInstance(String fqn) { + ServiceInstanceModel siKey = new ServiceInstanceModel(fqn); ServiceInstanceModel current = _serviceInstanceTable.ceiling(siKey); - if (current != null && current.getUuid().equals(uuid)) { + if (current != null && current.getQualifiedName().equals(fqn)) { return current; } return null; @@ -85,4 +88,17 @@ public class ModelDatabase { } return null; } + + public TreeSet getNetworkPolicys() { + return _policyTable; + } + + public NetworkPolicyModel lookupNetworkPolicy(String uuid) { + NetworkPolicyModel vmKey = new NetworkPolicyModel(uuid, null); + NetworkPolicyModel current = _policyTable.ceiling(vmKey); + if (current != null && current.getUuid().equals(uuid)) { + return current; + } + return null; + } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java index 52fe31e5693..b1f47187ed8 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java @@ -33,6 +33,7 @@ import net.juniper.contrail.api.ApiPropertyBase; import net.juniper.contrail.api.ObjectReference; import net.juniper.contrail.api.types.FloatingIp; import net.juniper.contrail.api.types.FloatingIpPool; +import net.juniper.contrail.api.types.NetworkPolicy; import net.juniper.contrail.api.types.InstanceIp; import net.juniper.contrail.api.types.ServiceInstance; import net.juniper.contrail.api.types.VirtualMachine; @@ -45,6 +46,7 @@ import org.springframework.stereotype.Component; import org.apache.cloudstack.network.contrail.model.FloatingIpModel; import org.apache.cloudstack.network.contrail.model.FloatingIpPoolModel; +import org.apache.cloudstack.network.contrail.model.NetworkPolicyModel; import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel; import org.apache.cloudstack.network.contrail.model.VMInterfaceModel; import org.apache.cloudstack.network.contrail.model.VirtualMachineModel; @@ -62,6 +64,10 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.vpc.NetworkACLItemDao; +import com.cloud.network.vpc.NetworkACLItemVO; +import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.dao.NetworkACLDao; import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.vm.NicVO; @@ -90,6 +96,11 @@ public class ServerDBSyncImpl implements ServerDBSync { PhysicalNetworkServiceProviderDao _physProviderDao; @Inject ContrailManager _manager; + @Inject + NetworkACLItemDao _networkACLItemDao; + @Inject + NetworkACLDao _networkACLDao; + DBSyncGeneric _dbSync; Class[] _vncClasses; // Read-Write (true) or Read-Only mode. @@ -98,8 +109,8 @@ public class ServerDBSyncImpl implements ServerDBSync { ServerDBSyncImpl() { _vncClasses = - new Class[] {net.juniper.contrail.api.types.Domain.class, net.juniper.contrail.api.types.Project.class, VirtualNetwork.class, VirtualMachine.class, - ServiceInstance.class, FloatingIp.class}; + new Class[] {net.juniper.contrail.api.types.Domain.class, net.juniper.contrail.api.types.Project.class, NetworkPolicy.class, VirtualNetwork.class, + VirtualMachine.class, ServiceInstance.class, FloatingIp.class}; _dbSync = new DBSyncGeneric(this); } @@ -440,7 +451,7 @@ public class ServerDBSyncImpl implements ServerDBSync { List types = new ArrayList(); types.add(TrafficType.Public); types.add(TrafficType.Guest); - List dbNets = _manager.findJuniperManagedNetworks(types); + List dbNets = _manager.findManagedNetworks(types); List vList = (List)api.list(VirtualNetwork.class, null); List vncList = new ArrayList(); @@ -499,6 +510,16 @@ public class ServerDBSyncImpl implements ServerDBSync { } VirtualNetworkModel vnModel = new VirtualNetworkModel(dbNet, dbNet.getUuid(), _manager.getCanonicalName(dbNet), dbNet.getTrafficType()); + if (dbNet.getTrafficType() == TrafficType.Guest && dbNet.getNetworkACLId() != null) { + NetworkACLVO acl = _networkACLDao.findById(dbNet.getNetworkACLId()); + NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid()); + if (policyModel == null) { + s_logger.error("Network(" + dbNet.getName() + ") has ACL but policy model not created: " + + acl.getUuid() + ", name: " + acl.getName()); + } else { + vnModel.addToNetworkPolicy(policyModel); + } + } vnModel.build(_manager.getModelController(), dbNet); if (_rwMode) { @@ -569,6 +590,16 @@ public class ServerDBSyncImpl implements ServerDBSync { VirtualNetworkModel current = _manager.getDatabase().lookupVirtualNetwork(vnet.getUuid(), _manager.getCanonicalName(dbn), dbn.getTrafficType()); VirtualNetworkModel vnModel = new VirtualNetworkModel(dbn, vnet.getUuid(), _manager.getCanonicalName(dbn), dbn.getTrafficType()); + if (dbn.getTrafficType() == TrafficType.Guest && dbn.getNetworkACLId() != null) { + NetworkACLVO acl = _networkACLDao.findById(dbn.getNetworkACLId()); + NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid()); + if (policyModel == null) { + s_logger.error("Network(" + dbn.getName() + ") has ACL but policy model not created: " + + acl.getUuid() + ", name: " + acl.getName()); + } else { + vnModel.addToNetworkPolicy(policyModel); + } + } vnModel.build(_manager.getModelController(), dbn); if (_rwMode) { @@ -589,6 +620,23 @@ public class ServerDBSyncImpl implements ServerDBSync { } catch (Exception ex) { s_logger.warn("update virtual-network", ex); } + if (current != null) { + NetworkPolicyModel oldPolicyModel = current.getNetworkPolicyModel(); + if (oldPolicyModel != vnModel.getNetworkPolicyModel()) { + /* + * if no other VNs are associated with the old policy, + * we could delete it from the Contrail VNC + */ + if (oldPolicyModel != null && !oldPolicyModel.hasDescendents()) { + try { + oldPolicyModel.delete(_manager.getModelController()); + _manager.getDatabase().getNetworkPolicys().remove(oldPolicyModel); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } } else { //compare if (current != null && current.compare(_manager.getModelController(), vnModel) == false) { @@ -780,7 +828,7 @@ public class ServerDBSyncImpl implements ServerDBSync { public boolean syncFloatingIp() throws Exception { - List ipList = _manager.findJuniperManagedPublicIps(); + List ipList = _manager.findManagedPublicIps(); List vncList = _manager.getFloatingIps(); if (ipList == null) { ipList = new ArrayList(); @@ -884,6 +932,164 @@ public class ServerDBSyncImpl implements ServerDBSync { return true; } + /* + * Network Policy Synchronization methods + */ + @SuppressWarnings({ "unchecked" }) + public boolean syncNetworkPolicy() throws Exception { + final ApiConnector api = _manager.getApiConnector(); + try { + + List dbAcls = _manager.findManagedACLs(); + if (dbAcls == null) { + dbAcls = new ArrayList(); + } + + List pList = (List) api.list(NetworkPolicy.class, null); + List vncList = new ArrayList(); + + for (NetworkPolicy policy:pList) { + if (!_manager.isSystemDefaultNetworkPolicy(policy)) { + vncList.add(policy); + } + } + s_logger.debug("sync Network Policy - DB size: " + dbAcls.size() + " VNC Size: " + vncList.size()); + return _dbSync.syncGeneric(NetworkPolicy.class, dbAcls, vncList); + } catch (Exception ex) { + s_logger.warn("sync network-policys", ex); + throw ex; + } + } + + public Comparator dbComparatorNetworkPolicy() { + Comparator comparator = new Comparator() { + public int compare(NetworkACLVO u1, NetworkACLVO u2) { + return u1.getUuid().compareTo(u2.getUuid()); + } + }; + return comparator; + } + + public Comparator vncComparatorNetworkPolicy() { + Comparator comparator = new Comparator() { + public int compare(NetworkPolicy u1, NetworkPolicy u2) { + return u1.getUuid().compareTo(u2.getUuid()); + } + }; + return comparator; + } + + public void createNetworkPolicy(NetworkACLVO db, StringBuffer syncLogMesg) throws IOException { + syncLogMesg.append("Policy# DB: " + db.getName() + + "(" + db.getUuid() + "); VNC: none; action: create\n"); + + if (_manager.getDatabase().lookupNetworkPolicy(db.getUuid()) != null) { + s_logger.warn("Policy model object is already present in DB: " + + db.getUuid() + ", name: " + db.getName()); + } + NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); + net.juniper.contrail.api.types.Project project = null; + try { + project = _manager.getDefaultVncProject(); + } catch (IOException ex) { + s_logger.warn("read project", ex); + throw ex; + } + policyModel.setProject(project); + List rules = _networkACLItemDao.listByACL(db.getId()); + try { + policyModel.build(_manager.getModelController(), rules); + } catch (Exception e) { + e.printStackTrace(); + } + + if (_rwMode) { + try { + if (!policyModel.verify(_manager.getModelController())) { + policyModel.update(_manager.getModelController()); + } + } catch (Exception ex) { + s_logger.warn("create network-policy", ex); + syncLogMesg.append("Error: Policy# VNC : Unable to create network policy " + + db.getName() + "\n"); + return; + } + s_logger.debug("add model " + policyModel.getName()); + _manager.getDatabase().getNetworkPolicys().add(policyModel); + syncLogMesg.append("Policy# VNC: " + db.getUuid() + ", " + policyModel.getName() + " created\n"); + } else { + syncLogMesg.append("Policy# VNC: " + policyModel.getName() + " created \n"); + } + } + + public void deleteNetworkPolicy(NetworkPolicy policy, StringBuffer syncLogMesg) throws IOException { + final ApiConnector api = _manager.getApiConnector(); + if (_manager.isSystemDefaultNetworkPolicy(policy)) { + syncLogMesg.append("Policy# System default Network Policy# VNC: " + policy.getName() + " can not be deleted\n"); + return; + } + syncLogMesg.append("Policy# DB: none; VNC: " + policy.getName() + "(" + policy.getUuid() + "); action: delete\n"); + api.delete(policy); + syncLogMesg.append("Policy# VNC: " + policy.getName() + " deleted\n"); + } + + public Integer compareNetworkPolicy(NetworkACLVO dbn, NetworkPolicy policy, StringBuffer syncLogMesg) { + if (_manager.isSystemDefaultNetworkPolicy(policy)) { + return 1; + } + return dbn.getUuid().compareTo(policy.getUuid()); + } + + public Boolean filterNetworkPolicy(NetworkPolicy policy, StringBuffer syncLogMesg) { + if (_manager.isSystemDefaultNetworkPolicy(policy)) { + syncLogMesg.append("Policy# VNC: " + policy.getName() + " filtered; action: don't delete\n"); + return true; + } + return false; + } + + public Boolean equalNetworkPolicy(NetworkACLVO db, NetworkPolicy policy, StringBuffer syncLogMesg) { + syncLogMesg.append("Policy# DB: " + db.getName() + + "; VNC: " + policy.getName() + "; action: equal\n"); + NetworkPolicyModel current = _manager.getDatabase().lookupNetworkPolicy(policy.getUuid()); + NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); + net.juniper.contrail.api.types.Project project = null; + try { + project = _manager.getDefaultVncProject(); + } catch (IOException ex) { + s_logger.warn("read project", ex); + } + policyModel.setProject(project); + List rules = _networkACLItemDao.listByACL(db.getId()); + try { + policyModel.build(_manager.getModelController(), rules); + } catch (Exception e) { + e.printStackTrace(); + } + if (_rwMode) { + if (current != null) { + _manager.getDatabase().getNetworkPolicys().remove(current); + } + s_logger.debug("add policy model " + policyModel.getName()); + _manager.getDatabase().getNetworkPolicys().add(policyModel); + try { + if (!policyModel.verify(_manager.getModelController())) { + policyModel.update(_manager.getModelController()); + } + } catch (Exception ex) { + s_logger.warn("update network-policy", ex); + } + } else { + //compare + if (current != null && current.compare(_manager.getModelController(), policyModel) == false) { + syncLogMesg.append("Policy# DB: " + db.getName() + + "; VNC: " + policy.getName() + "; attributes differ\n"); + return false; + } + } + return true; + } + public Integer compareServiceInstance(ServiceInstanceModel siModel, ServiceInstance siObj, StringBuffer logMsg) { String fqn = StringUtils.join(siObj.getQualifiedName(), ':'); return siModel.getQualifiedName().compareTo(fqn); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java index 5030bb71d09..05dcdce1a92 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java @@ -87,14 +87,6 @@ public class ServerEventHandlerImpl implements ServerEventHandler { public void defaultMessageHandler(String subject, String topic, Object args) { s_logger.info("DB Event Received - topic: " + topic + "; subject: " + subject); - if (subject.equals("VLAN.IP.RANGE.CREATE")) { - _manager.createPublicNetworks(); - return; - } else if (subject.equals("VLAN.IP.RANGE.DELETE")) { - // TODO - return; - } - org.apache.cloudstack.framework.events.Event event = (org.apache.cloudstack.framework.events.Event)args; /* Method name should be on for example: onDomainCreate */ @@ -244,7 +236,5 @@ public class ServerEventHandlerImpl implements ServerEventHandler { _messageBus.subscribe(EventTypes.EVENT_PROJECT_DELETE, MessageDispatcher.getDispatcher(this)); _messageBus.subscribe(EventTypes.EVENT_DOMAIN_CREATE, MessageDispatcher.getDispatcher(this)); _messageBus.subscribe(EventTypes.EVENT_DOMAIN_DELETE, MessageDispatcher.getDispatcher(this)); - _messageBus.subscribe(EventTypes.EVENT_VLAN_IP_RANGE_CREATE, MessageDispatcher.getDispatcher(this)); - _messageBus.subscribe(EventTypes.EVENT_VLAN_IP_RANGE_DELETE, MessageDispatcher.getDispatcher(this)); } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java index 98be2889aeb..9860faf7f09 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java @@ -27,12 +27,13 @@ import javax.inject.Inject; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.types.ServiceInstance; -import net.juniper.contrail.api.types.VirtualNetwork; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse; import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel; import org.apache.cloudstack.network.contrail.model.VirtualMachineModel; +import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel; + import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; @@ -142,17 +143,15 @@ public class ServiceManagerImpl implements ServiceManager { } final ApiConnector api = _manager.getApiConnector(); - final VirtualNetwork netLeft; - try { - netLeft = (VirtualNetwork)api.findById(VirtualNetwork.class, left.getUuid()); - } catch (IOException ex) { - throw new CloudRuntimeException("Unable to read virtual-network object", ex); + VirtualNetworkModel leftModel = _manager.getDatabase().lookupVirtualNetwork(left.getUuid(), + _manager.getCanonicalName(left), left.getTrafficType()); + if (leftModel == null) { + throw new CloudRuntimeException("Unable to read virtual-network object"); } - final VirtualNetwork netRight; - try { - netRight = (VirtualNetwork)api.findById(VirtualNetwork.class, right.getUuid()); - } catch (IOException ex) { - throw new CloudRuntimeException("Unable to read virtual-network object", ex); + VirtualNetworkModel rightModel = _manager.getDatabase().lookupVirtualNetwork(right.getUuid(), + _manager.getCanonicalName(right), right.getTrafficType()); + if (rightModel == null) { + throw new CloudRuntimeException("Unable to read virtual-network object"); } net.juniper.contrail.api.types.Project project; @@ -174,7 +173,8 @@ public class ServiceManagerImpl implements ServiceManager { } // 1. Create service-instance. - ServiceInstanceModel serviceModel = new ServiceInstanceModel(project, name, template, serviceOffering, netLeft, netRight); + ServiceInstanceModel serviceModel = new ServiceInstanceModel(project, name, template, serviceOffering, + leftModel, rightModel); try { serviceModel.update(_manager.getModelController()); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java new file mode 100644 index 00000000000..8ec2ff7187a --- /dev/null +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java @@ -0,0 +1,305 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.network.contrail.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.network.Networks; + +import net.juniper.contrail.api.types.NetworkPolicy; +import net.juniper.contrail.api.types.PolicyEntriesType; +import net.juniper.contrail.api.types.PolicyEntriesType.PolicyRuleType; +import net.juniper.contrail.api.types.Project; +import net.juniper.contrail.api.ApiConnector; +import org.apache.cloudstack.network.contrail.management.ContrailManager; + +import com.cloud.exception.InternalErrorException; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.NetworkACLItem.Action; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.exception.CloudRuntimeException; + +public class NetworkPolicyModel extends ModelObjectBase { + private static final Logger s_logger = Logger.getLogger(NetworkPolicyModel.class); + + private String _uuid; + private String _fqName; + private String _name; + private Project _project; + private NetworkPolicy _policy; + PolicyEntriesType _policyMap; + + public NetworkPolicyModel(String uuid, String name) { + _uuid = uuid; + _name = name; + } + + public String getQualifiedName() { + return _fqName; + } + + public String getName() { + return _name; + } + + public NetworkVO cidrToNetwork(ModelController controller, String cidr) { + SearchBuilder searchBuilder = controller.getNetworkDao().createSearchBuilder(); + searchBuilder.and("trafficType", searchBuilder.entity().getTrafficType(), Op.EQ); + searchBuilder.and("cidr", searchBuilder.entity().getCidr(), Op.EQ); + searchBuilder.and("networkOfferingId", searchBuilder.entity().getNetworkOfferingId(), Op.EQ); + + SearchCriteria sc = searchBuilder.create(); + + sc.setParameters("networkOfferingId", controller.getManager().getRouterOffering().getId()); + sc.setParameters("cidr", cidr); + sc.setParameters("trafficType", Networks.TrafficType.Guest); + + List dbNets = controller.getNetworkDao().search(sc, null); + if (dbNets == null || dbNets.size() == 0) { + return null; + } + if (dbNets.size() > 1) { + s_logger.warn("more than one network found with cidr: " + cidr); + } + return dbNets.get(0); + } + + public void build(ModelController controller, List rules) throws Exception { + String projectName = null; + if (_project != null) { + _fqName = StringUtils.join(_project.getQualifiedName(), ':') + ":" + _name; + projectName = StringUtils.join(_project.getQualifiedName(), ':'); + } else { + _fqName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT + ":" + _name; + projectName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT; + } + + PolicyEntriesType policyMap = new PolicyEntriesType(); + + for (NetworkACLItem rule:rules) { + if (rule.getState() != NetworkACLItem.State.Active && + rule.getState() != NetworkACLItem.State.Add) { + continue; + } + + String action = null; + if (rule.getAction() == Action.Allow) { + action = "pass"; + } else if (rule.getAction() == Action.Deny) { + action = "deny"; + } + List cidrList = rule.getSourceCidrList(); + String protocol = rule.getProtocol(); + if (protocol == null || protocol.equalsIgnoreCase("ALL") || protocol.isEmpty()) { + protocol = "any"; + } else { + protocol = protocol.toLowerCase(); + } + + Integer portStart = rule.getSourcePortStart(); + Integer portEnd = rule.getSourcePortEnd(); + if (portStart == null) { + portStart = 0; + } + if (portEnd == null) { + portEnd = 65535; + } + + List srcList = new ArrayList(); + List dstList = new ArrayList(); + + List srcPorts = new ArrayList(); + List dstPorts = new ArrayList(); + + if (rule.getTrafficType() == NetworkACLItem.TrafficType.Egress){ + for (String cidr: cidrList) { + NetworkVO net = cidrToNetwork(controller, cidr); + /*String[] maskInfo = StringUtils.splitByWholeSeparator(cidr, "/"); + SubnetType subnet = new SubnetType(); + subnet.setIpPrefix(maskInfo[0]); + subnet.setIpPrefixLen(Integer.parseInt(maskInfo[1])); + */ + String netName = projectName + ":" + controller.getManager().getCanonicalName(net); + dstList.add(new PolicyRuleType.AddressType(null, netName, null)); + } + dstPorts.add(new PolicyRuleType.PortType(portStart, portEnd)); + srcList.add(new PolicyRuleType.AddressType(null, "local", null)); + srcPorts.add(new PolicyRuleType.PortType(0, 65535)); + } else { + for (String cidr: cidrList) { + NetworkVO net = cidrToNetwork(controller, cidr); + String netName = projectName + ":" + controller.getManager().getCanonicalName(net); + dstList.add(new PolicyRuleType.AddressType(null, netName, null)); + } + dstPorts.add(new PolicyRuleType.PortType(portStart, portEnd)); + + srcList.add(new PolicyRuleType.AddressType(null, "any", null)); + srcPorts.add(new PolicyRuleType.PortType(0, 65535)); + } + + PolicyRuleType vnRule = new PolicyRuleType( + new PolicyRuleType.SequenceType(1, 0), rule.getUuid(), "<>", protocol, + srcList, srcPorts, null, dstList, dstPorts, + new PolicyRuleType.ActionListType(action, null, null, null)); + policyMap.addPolicyRule(vnRule); + } + _policyMap = policyMap; + } + + /* for service instance policy */ + public void build(ModelController modelController, String leftVn, String rightVn, String gatewayName, + List siList, String action) { + if (_project != null) { + _fqName = StringUtils.join(_project.getQualifiedName(), ':') + ":" + _name; + } else { + _fqName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT + ":" + _name; + } + + PolicyEntriesType policyMap = new PolicyEntriesType(); + List srcList = new ArrayList(); + srcList.add(new PolicyRuleType.AddressType(null, leftVn, null)); + List dstList = new ArrayList(); + dstList.add(new PolicyRuleType.AddressType(null, rightVn, null)); + + List portAny = new ArrayList(); + portAny.add(new PolicyRuleType.PortType(0, 65535)); + + PolicyRuleType rule = new PolicyRuleType( + new PolicyRuleType.SequenceType(1, 0), null, "<>", "any", + srcList, portAny, null, dstList, portAny, + new PolicyRuleType.ActionListType(action, gatewayName, siList, null)); + policyMap.addPolicyRule(rule); + _policyMap = policyMap; + } + + public boolean hasPolicyRules() { + if (_policyMap != null && _policyMap.getPolicyRule() != null && _policyMap.getPolicyRule().size() > 0) { + return true; + } + return false; + } + + @Override + public int compareTo(ModelObject o) { + NetworkPolicyModel other; + try { + other = (NetworkPolicyModel) o; + } catch (ClassCastException ex) { + String clsname = o.getClass().getName(); + return NetworkPolicyModel.class.getName().compareTo(clsname); + } + return _uuid.compareTo(other._uuid); + } + + @Override + public void delete(ModelController controller) throws IOException { + ApiConnector api = controller.getApiAccessor(); + if (_policy != null) { + api.delete(_policy); + _policy = null; + } + } + + @Override + public void destroy(ModelController controller) throws IOException { + } + + public String getUuid() { + return _uuid; + } + + @Override + public void update(ModelController controller) throws InternalErrorException, IOException { + ApiConnector api = controller.getApiAccessor(); + if (_project == null) { + s_logger.debug("Project is null for the policy: " + _name); + throw new IOException("Project is null for the policy: " + _name); + } + + NetworkPolicy policy = _policy; + + if (policy == null) { + try { + String policyId = api.findByName(NetworkPolicy.class, _project, _name); + if (policyId != null) { + policy = _policy = (NetworkPolicy) api.findById(NetworkPolicy.class, policyId); + } + if (policy == null) { + policy = new NetworkPolicy(); + policy.setUuid(_uuid); + policy.setName(_name); + policy.setParent(_project); + } + } catch (IOException ex) { + s_logger.warn("network-policy read", ex); + return; + } + } + + policy.setEntries(_policyMap); + if (_policy == null) { + try { + api.create(policy); + } catch (Exception ex) { + s_logger.debug("network policy create", ex); + throw new CloudRuntimeException("Failed to create network policy", ex); + } + _policy = policy; + } else { + try { + api.update(policy); + } catch (IOException ex) { + s_logger.warn("network policy update", ex); + throw new CloudRuntimeException("Unable to update network policy", ex); + } + } + for (ModelObject successor: successors()) { + successor.update(controller); + } + } + + @Override + public boolean verify(ModelController controller) { + return false; + } + + @Override + public boolean compare(ModelController controller, ModelObject current) { + return true; + } + + public void setProperties(ModelController controller, List rules) { + + } + + public void setProject(Project project) { + _project = project; + } + + public NetworkPolicy getPolicy() { + return _policy; + } +} diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java index a9bc5c153c8..0ce22adc421 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java @@ -20,19 +20,15 @@ package org.apache.cloudstack.network.contrail.model; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import net.juniper.contrail.api.ApiConnector; import net.juniper.contrail.api.ObjectReference; -import net.juniper.contrail.api.types.NetworkPolicy; -import net.juniper.contrail.api.types.PolicyEntriesType; -import net.juniper.contrail.api.types.PolicyEntriesType.PolicyRuleType; import net.juniper.contrail.api.types.Project; import net.juniper.contrail.api.types.ServiceInstance; import net.juniper.contrail.api.types.ServiceInstanceType; import net.juniper.contrail.api.types.ServiceTemplate; import net.juniper.contrail.api.types.ServiceTemplateType; -import net.juniper.contrail.api.types.VirtualNetwork; -import net.juniper.contrail.api.types.VirtualNetworkPolicyType; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -56,11 +52,11 @@ public class ServiceInstanceModel extends ModelObjectBase { private String _templateName; private String _templateId; private String _templateUrl; - private VirtualNetwork _left; - private VirtualNetwork _right; + private VirtualNetworkModel _left; + private VirtualNetworkModel _right; private ServiceTemplate _tmpl; private ServiceInstance _serviceInstance; - private NetworkPolicy _policy; + private NetworkPolicyModel _policy; /** * Create a ServiceInstance as result of an API call. @@ -72,7 +68,7 @@ public class ServiceInstanceModel extends ModelObjectBase { * @param left * @param right */ - public ServiceInstanceModel(Project project, String name, VirtualMachineTemplate template, ServiceOffering serviceOffering, VirtualNetwork left, VirtualNetwork right) { + public ServiceInstanceModel(Project project, String name, VirtualMachineTemplate template, ServiceOffering serviceOffering, VirtualNetworkModel left, VirtualNetworkModel right) { String parent_name; if (project != null) { parent_name = StringUtils.join(project.getQualifiedName(), ':'); @@ -84,8 +80,8 @@ public class ServiceInstanceModel extends ModelObjectBase { _mgmtName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT + ":" + ContrailManager.managementNetworkName; _left = left; _right = right; - _leftName = StringUtils.join(left.getQualifiedName(), ":"); - _rightName = StringUtils.join(right.getQualifiedName(), ":"); + _leftName = StringUtils.join(left.getVirtualNetwork().getQualifiedName(), ":"); + _rightName = StringUtils.join(right.getVirtualNetwork().getQualifiedName(), ":"); _templateName = template.getName(); _templateId = template.getUuid(); @@ -110,28 +106,6 @@ public class ServiceInstanceModel extends ModelObjectBase { return _fqName.substring(_fqName.lastIndexOf(':') + 1); } - private void applyNetworkPolicy(ModelController controller, NetworkPolicy policy, VirtualNetwork left, VirtualNetwork right) { - left.setNetworkPolicy(policy, new VirtualNetworkPolicyType(new VirtualNetworkPolicyType.SequenceType(1, 0), null)); - // TODO: network_ipam_refs attr is missing - left.clearNetworkIpam(); - try { - ApiConnector api = controller.getApiAccessor(); - api.update(left); - } catch (IOException ex) { - throw new CloudRuntimeException("Unable to update virtual-network", ex); - } - - right.setNetworkPolicy(policy, new VirtualNetworkPolicyType(new VirtualNetworkPolicyType.SequenceType(1, 0), null)); - // TODO: network_ipam_refs attr is missing - right.clearNetworkIpam(); - try { - ApiConnector api = controller.getApiAccessor(); - api.update(right); - } catch (IOException ex) { - throw new CloudRuntimeException("Unable to update virtual-network", ex); - } - } - /** * Recreate the model object from the Contrail API which is the master for this type of object. * @param siObj @@ -151,18 +125,6 @@ public class ServiceInstanceModel extends ModelObjectBase { s_logger.warn("service-template read", ex); } } - try { - Project project = (Project)api.findById(Project.class, siObj.getParentUuid()); - if (project != null) { - _projectId = project.getUuid(); - } - String policyId = api.findByName(NetworkPolicy.class, project, siObj.getName()); - if (policyId != null) { - _policy = (NetworkPolicy)api.findById(NetworkPolicy.class, policyId); - } - } catch (IOException ex) { - s_logger.warn("network-policy read", ex); - } } @Override @@ -207,40 +169,52 @@ public class ServiceInstanceModel extends ModelObjectBase { return si_obj; } - private NetworkPolicy createServicePolicy(ModelController controller) { - NetworkPolicy policy = new NetworkPolicy(); - policy.setParent(_serviceInstance.getParent()); - policy.setName(_serviceInstance.getName()); - PolicyEntriesType policy_map = new PolicyEntriesType(); - List srcList = new ArrayList(); - srcList.add(new PolicyRuleType.AddressType(null, _leftName, null)); - List dstList = new ArrayList(); - dstList.add(new PolicyRuleType.AddressType(null, _rightName, null)); + private void clearServicePolicy(ModelController controller) { + _left.addToNetworkPolicy(null); + _right.addToNetworkPolicy(null); + try { + controller.getManager().getDatabase().getNetworkPolicys().remove(_policy); + _policy.delete(controller.getManager().getModelController()); + _policy = null; + } catch (Exception e) { + s_logger.error(e); + } + try { + _left.update(controller.getManager().getModelController()); + _right.update(controller.getManager().getModelController()); + } catch (Exception ex) { + s_logger.error("virtual-network update for policy delete: ", ex); + } + } + + private NetworkPolicyModel setServicePolicy(ModelController controller) { + NetworkPolicyModel policyModel = new NetworkPolicyModel(UUID.randomUUID().toString(), _serviceInstance.getName()); + policyModel.setProject((Project)_serviceInstance.getParent()); + _left.addToNetworkPolicy(policyModel); + _right.addToNetworkPolicy(policyModel); List siList = new ArrayList(); siList.add(StringUtils.join(_serviceInstance.getQualifiedName(), ':')); - List portAny = new ArrayList(); - portAny.add(new PolicyRuleType.PortType(0, 65535)); - - PolicyRuleType rule = - new PolicyRuleType(new PolicyRuleType.SequenceType(1, 0), /* uuid */null, "<>", "any", srcList, portAny, /* application */null, dstList, portAny, - new PolicyRuleType.ActionListType("pass", "in-network", siList, null)); - policy_map.addPolicyRule(rule); - policy.setEntries(policy_map); - - try { - ApiConnector api = controller.getApiAccessor(); - if (!api.create(policy)) { - throw new CloudRuntimeException("Unable to create network-policy"); - } - } catch (IOException ex) { - throw new CloudRuntimeException("Unable to create network-policy", ex); + try { + policyModel.build(controller.getManager().getModelController(), _leftName, _rightName, "in-network", siList, "pass"); + } catch (Exception e) { + s_logger.error(e); + return null; } - return policy; + try { + if (!policyModel.verify(controller.getManager().getModelController())) { + policyModel.update(controller.getManager().getModelController()); + } + controller.getManager().getDatabase().getNetworkPolicys().add(policyModel); + } catch (Exception ex) { + s_logger.error("network-policy update: ", ex); + } + return policyModel; } @Override public void delete(ModelController controller) throws IOException { ApiConnector api = controller.getApiAccessor(); + clearServicePolicy(controller); if (_serviceInstance != null) { api.delete(_serviceInstance); } @@ -291,9 +265,7 @@ public class ServiceInstanceModel extends ModelObjectBase { } _uuid = _serviceInstance.getUuid(); if (_policy == null) { - _policy = createServicePolicy(controller); - // TODO: update the network model objects and call update - applyNetworkPolicy(controller, _policy, _left, _right); + _policy = setServicePolicy(controller); } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java index df0af908320..4d0218c8b4a 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java @@ -29,6 +29,7 @@ import net.juniper.contrail.api.types.VirtualMachine; import org.apache.cloudstack.network.contrail.management.ContrailManager; import org.apache.log4j.Logger; +import org.apache.commons.lang.StringUtils; import com.cloud.exception.InternalErrorException; import com.cloud.network.dao.NetworkDao; @@ -101,22 +102,27 @@ public class VirtualMachineModel extends ModelObjectBase { ApiConnector api = controller.getApiAccessor(); _serviceUuid = serviceUuid; - ServiceInstanceModel siModel = manager.getDatabase().lookupServiceInstance(serviceUuid); - if (siModel == null) { - ServiceInstance siObj; - try { - siObj = (ServiceInstance)api.findById(ServiceInstance.class, serviceUuid); - } catch (IOException ex) { - s_logger.warn("service-instance read", ex); - throw new CloudRuntimeException("Unable to read service-instance object", ex); - } - if (siObj == null) { - //If the ServiceInstance object is null, do not call build. It will break in many places. Instead, call update passing the controller as parameter. - //It will then create a new ServiceInstance is that's null. - siModel = new ServiceInstanceModel(serviceUuid); - siModel.update(controller); - - siObj = siModel.getServiceInstance(); + ServiceInstance siObj; + try { + siObj = (ServiceInstance) api.findById(ServiceInstance.class, serviceUuid); + } catch (IOException ex) { + s_logger.warn("service-instance read", ex); + throw new CloudRuntimeException("Unable to read service-instance object", ex); + } + ServiceInstanceModel siModel; + if (siObj == null) { + siModel = new ServiceInstanceModel(serviceUuid); + siModel.build(controller, siObj); + manager.getDatabase().getServiceInstances().add(siModel); + } else { + String fqn = StringUtils.join(siObj.getQualifiedName(), ':'); + siModel = manager.getDatabase().lookupServiceInstance(fqn); + if (siModel == null) { + if (siObj == null) { + siModel = new ServiceInstanceModel(serviceUuid); + siModel.build(controller, siObj); + manager.getDatabase().getServiceInstances().add(siModel); + } } } _serviceModel = siModel; diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java index 547d4bd8b04..b0505b17db7 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java @@ -29,6 +29,7 @@ import net.juniper.contrail.api.types.NetworkIpam; import net.juniper.contrail.api.types.Project; import net.juniper.contrail.api.types.SubnetType; import net.juniper.contrail.api.types.VirtualNetwork; +import net.juniper.contrail.api.types.VirtualNetworkPolicyType; import net.juniper.contrail.api.types.VnSubnetsType; import org.apache.log4j.Logger; @@ -66,6 +67,7 @@ public class VirtualNetworkModel extends ModelObjectBase { private NetworkIpam _ipam; private FloatingIpPoolModel _fipPoolModel; + private NetworkPolicyModel _policyModel; public VirtualNetworkModel(Network network, String uuid, String name, TrafficType trafficType) { _uuid = uuid; @@ -133,6 +135,10 @@ public class VirtualNetworkModel extends ModelObjectBase { successor.delete(controller); } + if (_policyModel != null) { + _policyModel.removeSuccessor(this); + } + try { api.delete(VirtualNetwork.class, _uuid); } catch (IOException ex) { @@ -181,6 +187,8 @@ public class VirtualNetworkModel extends ModelObjectBase { } } + _id = network.getId(); + try { _projectId = manager.getProjectId(network.getDomainId(), network.getAccountId()); } catch (IOException ex) { @@ -226,6 +234,16 @@ public class VirtualNetworkModel extends ModelObjectBase { } } + if (_policyModel == null) { + vn.clearNetworkPolicy(); + } else if (!_policyModel.hasPolicyRules()) { + vn.clearNetworkPolicy(); + _policyModel.removeSuccessor(this); + } else { + vn.setNetworkPolicy(_policyModel.getPolicy(), new VirtualNetworkPolicyType( + new VirtualNetworkPolicyType.SequenceType(1, 0), null)); + } + if (_ipam == null) { NetworkIpam ipam = null; try { @@ -402,6 +420,22 @@ public class VirtualNetworkModel extends ModelObjectBase { return false; } + List> policyRefs = _vn.getNetworkPolicy(); + if ((policyRefs == null || policyRefs.isEmpty()) && _policyModel != null) { + return false; + } + + if ((policyRefs != null && !policyRefs.isEmpty()) && _policyModel == null) { + return false; + } + + if (policyRefs != null && !policyRefs.isEmpty() && _policyModel != null) { + ObjectReference ref = policyRefs.get(0); + if (!ref.getUuid().equals(_policyModel.getUuid())) { + return false; + } + } + for (ModelObject successor : successors()) { if (!successor.verify(controller)) { return false; @@ -413,8 +447,6 @@ public class VirtualNetworkModel extends ModelObjectBase { @Override public boolean compare(ModelController controller, ModelObject o) { VirtualNetworkModel latest; - ApiConnector api = controller.getApiAccessor(); - assert this._vn != null : "vnc virtual network current is not initialized"; try { @@ -475,6 +507,40 @@ public class VirtualNetworkModel extends ModelObjectBase { return false; } + List> currentPolicyRefs = this._vn.getNetworkPolicy(); + List> latestPolicyRefs = latest._vn.getNetworkPolicy(); + + if (currentPolicyRefs == null && latestPolicyRefs == null) { + return true; + } + + if ((currentPolicyRefs == null && latestPolicyRefs != null) || + (currentPolicyRefs != null && latestPolicyRefs == null) || + (currentPolicyRefs.size() != latestPolicyRefs.size())) { + return false; + } + + if (currentPolicyRefs.isEmpty() && latestPolicyRefs.isEmpty()) { + return true; + } + + //both must be non empty lists + ObjectReference ref1 = currentPolicyRefs.get(0); + ObjectReference ref2 = latestPolicyRefs.get(0); + + if ((ref1 != null && ref2 == null) || (ref1 == null && ref2 != null)) { + return false; + } + + if ((ref1.getUuid() != null && ref2.getUuid() == null) || (ref1.getUuid() == null && ref2.getUuid() != null)) { + return false; + } + if (ref1.getUuid() == null && ref2.getUuid() == null) { + return true; + } + if (!ref1.getUuid().equals(ref2.getUuid())) { + return false; + } return true; } @@ -485,4 +551,18 @@ public class VirtualNetworkModel extends ModelObjectBase { public void setFipPoolModel(FloatingIpPoolModel fipPoolModel) { _fipPoolModel = fipPoolModel; } + + public NetworkPolicyModel getNetworkPolicyModel() { + return _policyModel; + } + + public void addToNetworkPolicy(NetworkPolicyModel policyModel) { + if (_policyModel != null) { + _policyModel.removeSuccessor(this); + } + _policyModel = policyModel; + if (_policyModel != null) { + _policyModel.addSuccessor(this); + } + } } diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java index 2a2babc67aa..1a53c173d9f 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java @@ -21,6 +21,7 @@ import java.io.IOException; import javax.inject.Inject; +import org.eclipse.jetty.security.IdentityService; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -42,17 +43,19 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl; -import org.apache.cloudstack.api.IdentityService; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl; +import org.apache.cloudstack.engine.orchestration.NetworkOrchestrator; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; @@ -65,6 +68,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl; import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor; import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl; +import org.apache.cloudstack.network.element.InternalLoadBalancerElement; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; @@ -73,6 +77,9 @@ import org.apache.cloudstack.region.PortableIpDaoImpl; import org.apache.cloudstack.region.PortableIpRangeDaoImpl; import org.apache.cloudstack.region.RegionManager; import org.apache.cloudstack.region.dao.RegionDaoImpl; +import org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry; +import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl; import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl; @@ -120,6 +127,7 @@ import com.cloud.dc.dao.AccountVlanMapDaoImpl; import com.cloud.dc.dao.ClusterDaoImpl; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDaoImpl; +import com.cloud.dc.dao.DataCenterDetailsDaoImpl; import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterVnetDaoImpl; @@ -141,11 +149,11 @@ import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.hypervisor.HypervisorGuruManagerImpl; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl; +import com.cloud.hypervisor.XenServerGuru; import com.cloud.network.ExternalDeviceUsageManager; import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManagerImpl; import com.cloud.network.Ipv6AddressManagerImpl; -import com.cloud.network.NetworkModelImpl; import com.cloud.network.NetworkServiceImpl; import com.cloud.network.NetworkUsageService; import com.cloud.network.StorageNetworkManager; @@ -161,6 +169,7 @@ import com.cloud.network.as.dao.CounterDaoImpl; import com.cloud.network.dao.AccountGuestVlanMapDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; +import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LBHealthCheckPolicyDaoImpl; import com.cloud.network.dao.LBStickinessPolicyDaoImpl; @@ -183,7 +192,11 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; import com.cloud.network.dao.UserIpv6AddressDaoImpl; import com.cloud.network.dao.VirtualRouterProviderDaoImpl; import com.cloud.network.dao.VpnUserDaoImpl; +import com.cloud.network.element.FirewallServiceProvider; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.element.VpcProvider; import com.cloud.network.firewall.FirewallManagerImpl; import com.cloud.network.lb.LoadBalancingRulesManagerImpl; import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; @@ -234,7 +247,7 @@ import com.cloud.storage.VolumeApiService; import com.cloud.storage.dao.DiskOfferingDaoImpl; import com.cloud.storage.dao.GuestOSCategoryDaoImpl; import com.cloud.storage.dao.GuestOSDaoImpl; -import com.cloud.storage.dao.LaunchPermissionDao; +import com.cloud.storage.dao.LaunchPermissionDaoImpl; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.storage.dao.SnapshotPolicyDaoImpl; import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; @@ -270,12 +283,14 @@ import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; -import com.cloud.uuididentity.dao.IdentityDaoImpl; import com.cloud.vm.ItWorkDaoImpl; +import com.cloud.vm.UserVmManagerImpl; +import com.cloud.vm.VirtualMachineManagerImpl; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDaoImpl; import com.cloud.vm.dao.InstanceGroupDaoImpl; import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl; +import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.NicIpAliasDaoImpl; import com.cloud.vm.dao.NicSecondaryIpDaoImpl; import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; @@ -292,19 +307,19 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; AsyncJobJournalDaoImpl.class, AsyncJobManagerImpl.class, AutoScalePolicyConditionMapDaoImpl.class, AutoScalePolicyDaoImpl.class, AutoScaleVmGroupDaoImpl.class, AutoScaleVmGroupPolicyMapDaoImpl.class, AutoScaleVmProfileDaoImpl.class, CapacityDaoImpl.class, ClusterDaoImpl.class, ClusterDetailsDaoImpl.class, ConditionDaoImpl.class, ConfigurationDaoImpl.class, ConfigurationManagerImpl.class, ConfigurationServerImpl.class, ConsoleProxyDaoImpl.class, - ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterIpAddressDaoImpl.class, + ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterDetailsDaoImpl.class, DataCenterIpAddressDaoImpl.class, DataCenterJoinDaoImpl.class, DataCenterLinkLocalIpAddressDaoImpl.class, DataCenterVnetDaoImpl.class, DcDetailsDaoImpl.class, DedicatedResourceDaoImpl.class, DiskOfferingDaoImpl.class, DiskOfferingJoinDaoImpl.class, DomainDaoImpl.class, DomainManagerImpl.class, DomainRouterDaoImpl.class, DomainRouterJoinDaoImpl.class, - EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, EventUtils.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, + EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, ExtensionRegistry.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, FirewallRulesDaoImpl.class, GuestOSCategoryDaoImpl.class, GuestOSDaoImpl.class, HostDaoImpl.class, HostDetailsDaoImpl.class, HostJoinDaoImpl.class, HostPodDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, HypervisorCapabilitiesDaoImpl.class, HypervisorGuruManagerImpl.class, - IdentityDaoImpl.class, ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, - InstanceGroupVMMapDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, - LBStickinessPolicyDaoImpl.class, LaunchPermissionDao.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, + ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, + InstanceGroupVMMapDaoImpl.class, InternalLoadBalancerElement.class, IPAddressDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, + LBStickinessPolicyDaoImpl.class, LaunchPermissionDaoImpl.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, ManagementServerHostDaoImpl.class, MockAccountManager.class, NetworkACLDaoImpl.class, NetworkACLItemDaoImpl.class, NetworkACLManagerImpl.class, - NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkModelImpl.class, NetworkOfferingDaoImpl.class, - NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, - NetworkServiceMapDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, + NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkOfferingDaoImpl.class, + NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkOrchestrator.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, + NetworkServiceMapDaoImpl.class, NicDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, PlannerHostReservationDaoImpl.class, PodVlanDaoImpl.class, PodVlanMapDaoImpl.class, PortForwardingRulesDaoImpl.class, PortableIpDaoImpl.class, PortableIpRangeDaoImpl.class, PrimaryDataStoreDaoImpl.class, PrivateIpDaoImpl.class, ProjectAccountDaoImpl.class, ProjectAccountJoinDaoImpl.class, ProjectInvitationDaoImpl.class, ProjectDaoImpl.class, ProjectInvitationJoinDaoImpl.class, ProjectJoinDaoImpl.class, @@ -316,11 +331,11 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; SnapshotDaoImpl.class, SnapshotPolicyDaoImpl.class, StaticRouteDaoImpl.class, StatsCollector.class, StoragePoolDetailsDaoImpl.class, StoragePoolHostDaoImpl.class, StoragePoolJoinDaoImpl.class, SyncQueueItemDaoImpl.class, TemplateDataStoreDaoImpl.class, TemplateJoinDaoImpl.class, UploadDaoImpl.class, UsageEventDaoImpl.class, UserAccountJoinDaoImpl.class, UserDaoImpl.class, UserIpv6AddressDaoImpl.class, UserStatisticsDaoImpl.class, UserStatsLogDaoImpl.class, - UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, - VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualRouterProviderDaoImpl.class, + UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, UserVmManagerImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, + VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualMachineManagerImpl.class, VirtualRouterProviderDaoImpl.class, VlanDaoImpl.class, VmDiskStatisticsDaoImpl.class, VmRulesetLogDaoImpl.class, VolumeDaoImpl.class, VolumeHostDaoImpl.class, VolumeJoinDaoImpl.class, VpcDaoImpl.class, VpcGatewayDaoImpl.class, VpcManagerImpl.class, VpcOfferingDaoImpl.class, VpcOfferingServiceMapDaoImpl.class, VpcServiceMapDaoImpl.class, - VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, + VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class, XenServerGuru.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, type = FilterType.CUSTOM)}, useDefaultFilters = false) @Configuration public class IntegrationTestConfiguration { @@ -712,5 +727,36 @@ public class IntegrationTestConfiguration { public VolumeOrchestrationService volumeOrchestrationService() { return Mockito.mock(VolumeOrchestrationService.class); } - + @Bean + public FirewallServiceProvider firewallServiceProvider() { + return Mockito.mock(FirewallServiceProvider.class); + } + @Bean + public PortForwardingServiceProvider portForwardingServiceProvider() { + return Mockito.mock(PortForwardingServiceProvider.class); + } + @Bean + public NetworkACLServiceProvider networkACLServiceProvider() { + return Mockito.mock(NetworkACLServiceProvider.class); + } + @Bean + public VpcProvider vpcProvier() { + return Mockito.mock(VpcProvider.class); + } + @Bean + public VolumeService volumeService() { + return Mockito.mock(VolumeService.class); + } + @Bean + public PrimaryDataStoreProviderManager privateDataStoreProviderManager() { + return Mockito.mock(PrimaryDataStoreProviderManager.class); + } + @Bean + public ImageStoreProviderManager imageStoreProviderManager() { + return Mockito.mock(ImageStoreProviderManager.class); + } + @Bean + public DataStoreProvider dataStoreProvider() { + return Mockito.mock(DataStoreProvider.class); + } } diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java index 806dd21a07f..50419ea1b36 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java @@ -327,17 +327,17 @@ public class ManagementServerMock { _znet = _networkService.getPhysicalNetwork(id); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } catch (InvalidParameterValueException e) { List isolationMethods = new ArrayList(); - isolationMethods.add("GRE"); + isolationMethods.add("L3VPN"); _znet = _networkService.createPhysicalNetwork(_zone.getId(), null, null, isolationMethods, BroadcastDomainRange.ZONE.toString(), _zone.getDomainId(), null, "znet"); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } if (_znet.getState() != PhysicalNetwork.State.Enabled) { @@ -353,14 +353,14 @@ public class ManagementServerMock { } } if (!found) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null); } Pair, Integer> providers = - _networkService.listNetworkServiceProviders(_znet.getId(), Provider.JuniperContrail.getName(), null, null, null); + _networkService.listNetworkServiceProviders(_znet.getId(), Provider.JuniperContrailRouter.getName(), null, null, null); if (providers.second() == 0) { - s_logger.debug("Add " + Provider.JuniperContrail.getName() + " to network " + _znet.getName()); - PhysicalNetworkServiceProvider provider = _networkService.addProviderToPhysicalNetwork(_znet.getId(), Provider.JuniperContrail.getName(), null, null); + s_logger.debug("Add " + Provider.JuniperContrailRouter.getName() + " to network " + _znet.getName()); + PhysicalNetworkServiceProvider provider = _networkService.addProviderToPhysicalNetwork(_znet.getId(), Provider.JuniperContrailRouter.getName(), null, null); _networkService.updateNetworkServiceProvider(provider.getId(), PhysicalNetworkServiceProvider.State.Enabled.toString(), null); } else { PhysicalNetworkServiceProvider provider = providers.first().get(0); @@ -372,7 +372,7 @@ public class ManagementServerMock { providers = _networkService.listNetworkServiceProviders(_znet.getId(), null, PhysicalNetworkServiceProvider.State.Enabled.toString(), null, null); s_logger.debug(_znet.getName() + " has " + providers.second().toString() + " Enabled providers"); for (PhysicalNetworkServiceProvider provider : providers.first()) { - if (provider.getProviderName().equals(Provider.JuniperContrail.getName())) { + if (provider.getProviderName().equals(Provider.JuniperContrailRouter.getName())) { continue; } s_logger.debug("Disabling " + provider.getProviderName()); diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 2f81688c0f8..fa7be5827c5 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.context.CallContext; -import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.configuration.ResourceLimit; import com.cloud.configuration.dao.ResourceCountDao; @@ -68,8 +67,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager { @Inject ResourceCountDao _resourceCountDao; - @Inject - AccountJoinDao _accountJoinDao; @Inject UserDao _userDao; diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java index 6996a287302..95204900f72 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java @@ -204,7 +204,7 @@ public class NetworkProviderTest extends TestCase { ManagementServerMock.setParameter(cmd, "accountName", BaseCmd.CommandType.STRING, system.getAccountName()); ManagementServerMock.setParameter(cmd, ApiConstants.NAME, BaseCmd.CommandType.STRING, name); ManagementServerMock.setParameter(cmd, "displayText", BaseCmd.CommandType.STRING, "test network"); - ManagementServerMock.setParameter(cmd, "networkOfferingId", BaseCmd.CommandType.LONG, _contrailMgr.getOffering().getId()); + ManagementServerMock.setParameter(cmd, "networkOfferingId", BaseCmd.CommandType.LONG, _contrailMgr.getRouterOffering().getId()); ManagementServerMock.setParameter(cmd, "zoneId", BaseCmd.CommandType.LONG, zone.getId()); ManagementServerMock.setParameter(cmd, ApiConstants.GATEWAY, BaseCmd.CommandType.STRING, "10.0.1.254"); ManagementServerMock.setParameter(cmd, ApiConstants.NETMASK, BaseCmd.CommandType.STRING, "255.255.255.0"); diff --git a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml index eef908ff15b..6f46f6dde4e 100644 --- a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml +++ b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml @@ -23,6 +23,7 @@ + - - - + + + + + - + + - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + class="org.apache.cloudstack.network.contrail.management.IntegrationTestConfiguration"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java b/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java index eaade0107b7..ed6011b9a7a 100644 --- a/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java +++ b/plugins/network-elements/juniper-srx/src/com/cloud/network/resource/JuniperSrxResource.java @@ -2809,7 +2809,7 @@ public class JuniperSrxResource implements ServerResource { if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS) || type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS_DEFAULT)) { xml = replaceXmlValue(xml, "from-zone", _privateZone); xml = replaceXmlValue(xml, "to-zone", _publicZone); - if (cidrs == null) { + if (cidrs == null || cidrs.size() == 0) { srcAddrs = "any"; } else { for (String cidr : cidrs) { diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index a4b4c494da9..6fc43ec4cfe 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -1,20 +1,22 @@ 4.0.0 @@ -34,6 +36,21 @@ true + + + com.mycila + license-maven-plugin + + + cloudstack-checklicence + process-classes + + check + + + + + diff --git a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties index 92f92a4b4b0..5085fcec0c7 100644 --- a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties +++ b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/module.properties @@ -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 @@ -14,5 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# + name=nvp parent=network \ No newline at end of file diff --git a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml index 8d9813a020e..cd8a2c9846f 100644 --- a/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml +++ b/plugins/network-elements/nicira-nvp/resources/META-INF/cloudstack/nvp/spring-nvp-context.xml @@ -1,20 +1,22 @@ prefixMap; + protected final static Map prefixMap; - protected static Map listTypeMap; + protected final static Map listTypeMap; - protected static Map defaultListParams; + protected final static Map defaultListParams; static { prefixMap = new HashMap(); diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java index facc5ab59e3..0d2782007f5 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApiException.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; public class NiciraNvpApiException extends Exception { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java index ba6ff974790..34b5e19c8c1 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import java.util.List; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java index 7185bc71b62..625e49c21a5 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpTag.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import org.apache.log4j.Logger; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java index 3e2a8c3166a..26fa0486113 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; /** diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java index 7622c68c287..8dd884072be 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; /** diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java index c5eca5b9bc4..5eaef0a699d 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RoutingConfig.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; public class RoutingConfig { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java index fb3f0743cd0..d83ce49db12 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityProfile.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; @SuppressWarnings("serial") diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java index 06181f0725d..e23593cb3d6 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SecurityRule.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import org.apache.commons.lang.builder.EqualsBuilder; diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java index d386e7020b5..05335791b95 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SingleDefaultRouteImplictRoutingConfig.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; /** diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java index ee467a710a9..b95cb9aeb5d 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/SourceNatRule.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; public class SourceNatRule extends NatRule { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java index fd0fbb1c370..c643876d93c 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/TransportZoneBinding.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; public class TransportZoneBinding { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java index 7b37ac151f1..87765be12a2 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/VifAttachment.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; public class VifAttachment extends Attachment { diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index 8c99a819a4f..c228b08d5ee 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.resource; import java.util.ArrayList; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java index 436c86c2743..822c8c7ee93 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/element/NiciraNvpElementTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.element; import static org.junit.Assert.assertFalse; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java index 3e303b8aae4..db8637ccfb6 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.guru; import static org.junit.Assert.assertFalse; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NatRuleTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NatRuleTest.java index 1a635278d37..84b28fb8da8 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NatRuleTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NatRuleTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import static org.junit.Assert.assertTrue; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java index c541d87cae3..7f8f471595a 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiIT.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import static org.junit.Assert.assertTrue; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java index 2e4cfaf1a05..13d970c1cbc 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraNvpApiTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import static org.junit.Assert.assertTrue; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraTagTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraTagTest.java index 751280356d9..58dcedc6a89 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraTagTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/nicira/NiciraTagTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.nicira; import static org.junit.Assert.assertEquals; diff --git a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java index ad01218909e..2717c3125d8 100644 --- a/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java +++ b/plugins/network-elements/nicira-nvp/test/com/cloud/network/resource/NiciraNvpResourceTest.java @@ -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 @@ -14,6 +15,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + package com.cloud.network.resource; import static org.junit.Assert.assertFalse; diff --git a/plugins/network-elements/nicira-nvp/test/resources/config.properties b/plugins/network-elements/nicira-nvp/test/resources/config.properties index 67576923823..4006e38d64e 100644 --- a/plugins/network-elements/nicira-nvp/test/resources/config.properties +++ b/plugins/network-elements/nicira-nvp/test/resources/config.properties @@ -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 @@ -14,6 +15,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# nvp.host=${nvp-host} diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 47d66f60b13..decfd676cd4 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -1,19 +1,19 @@ + + 4.0.0 + cloud-plugin-storage-volume-nexenta + Apache CloudStack Plugin - Storage Volume Nexenta Provider + + org.apache.cloudstack + cloudstack-plugins + 4.4.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + \ No newline at end of file diff --git a/scripts/network/domr/createipAlias.sh b/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties old mode 100755 new mode 100644 similarity index 74% rename from scripts/network/domr/createipAlias.sh rename to plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties index c35658e6679..c2036006f1f --- a/scripts/network/domr/createipAlias.sh +++ b/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/module.properties @@ -1,4 +1,3 @@ -#!/usr/bin/env bash # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,12 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - - -usage() { - printf " %s routerip \n" $(basename $0) >&2 -} - -set -x -cert="/root/.ssh/id_rsa.cloud" -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$1 "/root/createIpAlias.sh $2" +name=storage-volume-nexenta +parent=storage \ No newline at end of file diff --git a/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml b/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml new file mode 100644 index 00000000000..6c83c1ac47f --- /dev/null +++ b/plugins/storage/volume/nexenta/resources/META-INF.cloudstack.storage-volume-solidfire/spring-storage-volume-nexenta-context.xml @@ -0,0 +1,32 @@ + + + + + + \ No newline at end of file diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java new file mode 100644 index 00000000000..70f4a4f140c --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/driver/NexentaPrimaryDataStoreDriver.java @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.driver; + +import static org.apache.cloudstack.storage.datastore.util.NexentaUtil.NexentaPluginParameters; + +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance; +import org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.NexentaStorZvol; +import org.apache.cloudstack.storage.datastore.util.NexentaUtil; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.host.Host; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Volume; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.dao.AccountDao; + +public class NexentaPrimaryDataStoreDriver implements PrimaryDataStoreDriver { + private static final Logger logger = Logger.getLogger(NexentaPrimaryDataStoreDriver.class); + + @Override + public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public long getVolumeSizeIncludingHypervisorSnapshotReserve(Volume volume, StoragePool pool) { + return 0; //To change body of implemented methods use File | Settings | File Templates. + } + + @Inject + private VolumeDao _volumeDao; + @Inject + PrimaryDataStoreDao _storagePoolDao; + @Inject + private StoragePoolDetailsDao _storagePoolDetailsDao; + @Inject + private AccountDao _accountDao; + + @Override + public Map getCapabilities() { + return null; + } + + @Override + public ChapInfo getChapInfo(VolumeInfo volumeInfo) { + return null; + } + + @Override + public DataTO getTO(DataObject data) { + return null; + } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + return null; + } + + private NexentaStorAppliance getNexentaStorAppliance(long storagePoolId) { + NexentaPluginParameters parameters = new NexentaPluginParameters(); + + parameters.setNmsUrl(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.NMS_URL).getValue()); + parameters.setVolume(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME).getValue()); + parameters.setStorageType(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_TYPE).getValue()); + parameters.setStorageHost(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_HOST).getValue()); + parameters.setStoragePort(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PORT).getValue()); + parameters.setStoragePath(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.STORAGE_PATH).getValue()); + parameters.setSparseVolumes(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.SPARSE_VOLUMES).getValue()); + parameters.setVolumeBlockSize(_storagePoolDetailsDao.findDetail(storagePoolId, NexentaUtil.VOLUME_BLOCK_SIZE).getValue()); + + return new NexentaStorAppliance(parameters); + } + + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) {} + + @Override + public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) {} + + @Override + public void createAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback callback) { + String iqn = null; + String errorMessage = null; + + if (dataObject.getType() != DataObjectType.VOLUME) { + errorMessage = "Invalid DataObjectType (" + dataObject.getType() + ") passed to createAsync"; + } else { + VolumeInfo volumeInfo = (VolumeInfo) dataObject; + + long storagePoolId = dataStore.getId(); + NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId); + + // TODO: maybe we should use md5(volume name) as volume name + NexentaStorZvol zvol = (NexentaStorZvol) appliance.createVolume(volumeInfo.getName(), volumeInfo.getSize()); + iqn = zvol.getIqn(); + + VolumeVO volume = this._volumeDao.findById(volumeInfo.getId()); + volume.set_iScsiName(iqn); + volume.setFolder(zvol.getName()); + volume.setPoolType(Storage.StoragePoolType.IscsiLUN); + volume.setPoolId(storagePoolId); + _volumeDao.update(volume.getId(), volume); + + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + long capacityBytes = storagePool.getCapacityBytes(); + long usedBytes = storagePool.getUsedBytes(); + usedBytes += volumeInfo.getSize(); + storagePool.setUsedBytes(usedBytes > capacityBytes ? capacityBytes : usedBytes); + _storagePoolDao.update(storagePoolId, storagePool); + } + + CreateCmdResult result = new CreateCmdResult(iqn, new Answer(null, errorMessage == null, errorMessage)); + result.setResult(errorMessage); + callback.complete(result); + } + + @Override + public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback callback) { + String errorMessage = null; + if (data.getType() == DataObjectType.VOLUME) { + VolumeInfo volumeInfo = (VolumeInfo) data; + long storagePoolId = store.getId(); + NexentaStorAppliance appliance = getNexentaStorAppliance(storagePoolId); + StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId); + + + +// _storagePoolDao.update(stoagePoolId); + } else { + errorMessage = String.format( + "Invalid DataObjectType(%s) passed to deleteAsync", + data.getType()); + } + CommandResult result = new CommandResult(); + result.setResult(errorMessage); + callback.complete(result); + } + + @Override + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) {} + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + return false; + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) {} +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java new file mode 100644 index 00000000000..c7ce33ab054 --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/lifecylce/NexentaPrimaryDataStoreLifeCycle.java @@ -0,0 +1,176 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.lifecylce; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.util.NexentaUtil; +import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.resource.ResourceManager; +import com.cloud.storage.StorageManager; +import com.cloud.storage.StoragePoolAutomation; + +public class NexentaPrimaryDataStoreLifeCycle + implements PrimaryDataStoreLifeCycle { + private static final Logger logger = + Logger.getLogger(NexentaPrimaryDataStoreLifeCycle.class); + + @Inject + private DataCenterDao zoneDao; + @Inject + private PrimaryDataStoreHelper dataStoreHelper; + @Inject + private ResourceManager _resourceMgr; + @Inject + StorageManager _storageMgr; + @Inject + private StoragePoolAutomation storagePoolAutomation; + + @Override + public DataStore initialize(Map dsInfos) { + String url = (String) dsInfos.get("url"); + Long zoneId = (Long) dsInfos.get("zoneId"); + String storagePoolName = (String) dsInfos.get("name"); + String providerName = (String) dsInfos.get("providerName"); + Long capacityBytes = (Long)dsInfos.get("capacityBytes"); + Long capacityIops = (Long)dsInfos.get("capacityIops"); + String tags = (String)dsInfos.get("tags"); + Map details = (Map) dsInfos.get("details"); + NexentaUtil.NexentaPluginParameters params = NexentaUtil.parseNexentaPluginUrl(url); + DataCenterVO zone = zoneDao.findById(zoneId); + String uuid = String.format("%s_%s_%s", NexentaUtil.PROVIDER_NAME, zone.getUuid(), params.getNmsUrl().getHost()); + + if (capacityBytes == null || capacityBytes <= 0) { + throw new IllegalArgumentException("'capacityBytes' must be present and greater than 0."); + } + + if (capacityIops == null || capacityIops <= 0) { + throw new IllegalArgumentException("'capacityIops' must be present and greater than 0."); + } + + PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); + + parameters.setHost(params.getStorageHost()); + parameters.setPort(params.getStoragePort()); + parameters.setPath(params.getStoragePath()); + parameters.setType(params.getStorageType()); + parameters.setUuid(uuid); + parameters.setZoneId(zoneId); + parameters.setName(storagePoolName); + parameters.setProviderName(providerName); + parameters.setManaged(true); + parameters.setCapacityBytes(capacityBytes); + parameters.setUsedBytes(0); + parameters.setCapacityIops(capacityIops); + parameters.setHypervisorType(Hypervisor.HypervisorType.Any); + parameters.setTags(tags); + + details.put(NexentaUtil.NMS_URL, params.getNmsUrl().toString()); + + details.put(NexentaUtil.VOLUME, params.getVolume()); + details.put(NexentaUtil.SPARSE_VOLUMES, params.getSparseVolumes().toString()); + + details.put(NexentaUtil.STORAGE_TYPE, params.getStorageType().toString()); + details.put(NexentaUtil.STORAGE_HOST, params.getStorageHost()); + details.put(NexentaUtil.STORAGE_PORT, params.getStoragePort().toString()); + details.put(NexentaUtil.STORAGE_PATH, params.getStoragePath()); + + parameters.setDetails(details); + + // this adds a row in the cloud.storage_pool table for this SolidFire cluster + return dataStoreHelper.createPrimaryDataStore(parameters); + } + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + return true; + } + + @Override + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { + return true; + } + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope, Hypervisor.HypervisorType hypervisorType) { + dataStoreHelper.attachZone(dataStore); + + List xenServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.XenServer, scope.getScopeId()); + List vmWareServerHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.VMware, scope.getScopeId()); + List kvmHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(Hypervisor.HypervisorType.KVM, scope.getScopeId()); + List hosts = new ArrayList(); + + hosts.addAll(xenServerHosts); + hosts.addAll(vmWareServerHosts); + hosts.addAll(kvmHosts); + + for (HostVO host : hosts) { + try { + _storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId()); + } catch (Exception e) { + logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e); + } + } + + return true; + } + + @Override + public boolean maintain(DataStore store) { + storagePoolAutomation.maintain(store); + dataStoreHelper.maintain(store); + + return true; + } + + @Override + public boolean cancelMaintain(DataStore store) { + dataStoreHelper.cancelMaintain(store); + storagePoolAutomation.cancelMaintain(store); + + return true; + } + + @Override + public boolean deleteDataStore(DataStore store) { + return dataStoreHelper.deletePrimaryDataStore(store); + } + + @Override + public boolean migrateToObjectStore(DataStore store) { + return false; + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java new file mode 100644 index 00000000000..950325288f3 --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaHostListener.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.provider; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; + +public class NexentaHostListener implements HypervisorHostListener { + private static final Logger logger = Logger.getLogger(NexentaHostListener.class); + + public boolean hostConnect(long hostId, long poolId) { + return true; + } + + public boolean hostDisconnected(long hostId, long poolId) { + return true; + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java new file mode 100644 index 00000000000..afd7e35c257 --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/provider/NexentaPrimaryDataStoreProvider.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.provider; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.stereotype.Component; + +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.storage.datastore.driver.NexentaPrimaryDataStoreDriver; +import org.apache.cloudstack.storage.datastore.lifecylce.NexentaPrimaryDataStoreLifeCycle; +import org.apache.cloudstack.storage.datastore.util.NexentaUtil; + +import com.cloud.utils.component.ComponentContext; + +@Component +public class NexentaPrimaryDataStoreProvider implements PrimaryDataStoreProvider { + private DataStoreLifeCycle lifeCycle; + private PrimaryDataStoreDriver driver; + private HypervisorHostListener listener; + + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + return lifeCycle; + } + + @Override + public DataStoreDriver getDataStoreDriver() { + return driver; + } + + @Override + public HypervisorHostListener getHostListener() { + return listener; + } + + @Override + public String getName() { + return NexentaUtil.PROVIDER_NAME; + } + + @Override + public boolean configure(Map params) { + lifeCycle = ComponentContext.inject(NexentaPrimaryDataStoreLifeCycle.class); + driver = ComponentContext.inject(NexentaPrimaryDataStoreDriver.class); + listener = ComponentContext.inject(NexentaHostListener.class); + + return true; + } + + @Override + public Set getTypes() { + Set types = new HashSet(); + + types.add(DataStoreProviderType.PRIMARY); + + return types; + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java new file mode 100644 index 00000000000..70565fcea32 --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsClient.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.BasicClientConnectionManager; +import org.apache.log4j.Logger; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; + +public class NexentaNmsClient { + private static final Logger logger = Logger.getLogger(NexentaNmsClient.class); + + protected NexentaNmsUrl nmsUrl = null; + protected DefaultHttpClient httpClient = null; + + NexentaNmsClient(NexentaNmsUrl nmsUrl) { + this.nmsUrl = nmsUrl; + } + + private static boolean isSuccess(int iCode) { + return iCode >= 200 && iCode < 300; + } + + protected DefaultHttpClient getClient() { + if (httpClient == null) { + if (nmsUrl.getSchema().equalsIgnoreCase("http")) { + httpClient = getHttpClient(); + } else { + httpClient = getHttpsClient(); + } + AuthScope authScope = new AuthScope(nmsUrl.getHost(), nmsUrl.getPort(), AuthScope.ANY_SCHEME, "basic"); + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(nmsUrl.getUsername(), nmsUrl.getPassword()); + httpClient.getCredentialsProvider().setCredentials(authScope, credentials); + } + return httpClient; + } + + protected DefaultHttpClient getHttpsClient() { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + X509TrustManager tm = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] {tm}, new SecureRandom()); + + SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + SchemeRegistry registry = new SchemeRegistry(); + + registry.register(new Scheme("https", nmsUrl.getPort(), socketFactory)); + + BasicClientConnectionManager mgr = new BasicClientConnectionManager(registry); + + return new DefaultHttpClient(mgr); + } catch (NoSuchAlgorithmException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } catch (KeyManagementException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } + } + + protected DefaultHttpClient getHttpClient() { + return new DefaultHttpClient(); + } + + @SuppressWarnings("unused") + static class NmsRequest { + private String method; + private String object; + private Object[] params; + + NmsRequest(String object, String method) { + this(method, object, null); + } + + NmsRequest(String object, String method, Object... params) { + this.method = method; + this.object = object; + this.params = params; + } + + public String toString() { + StringBuffer b = new StringBuffer(); + b.append("Request to ").append(object).append(" method ").append(method); + if (params != null) { + b.append(" params:"); + for (Object param:params) { + b.append(" ").append(param).append(","); + } + } + return b.toString(); + } + } + + @SuppressWarnings("unused") + static class NmsError { + private String message; + + public String getMesssage() { + return message; + } + } + + @SuppressWarnings("unused") + static class NmsResponse { + @SerializedName("tg_flash") protected String tgFlash; + + protected NmsError error; + + NmsResponse() {} + + NmsResponse(String tgFlash, NmsError error) { + this.tgFlash = tgFlash; + this.error = error; + } + + public String getTgFlash() { + return tgFlash; + } + + public NmsError getError() { + return error; + } + } + + public NmsResponse execute(Class responseClass, String object, String method, Object... params) { + StringBuilder sb = new StringBuilder(); + NmsRequest nmsRequest = new NmsRequest(object, method, params); + if (logger.isDebugEnabled()) { + logger.debug(nmsRequest); + } + final Gson gson = new Gson(); + String jsonRequest = gson.toJson(nmsRequest); + StringEntity input = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON); + HttpPost postRequest = new HttpPost(nmsUrl.toString()); + postRequest.setEntity(input); + + DefaultHttpClient httpClient = getClient(); + try { + HttpResponse response = httpClient.execute(postRequest); + final int status = response.getStatusLine().getStatusCode(); + if (!isSuccess(status)) { + throw new CloudRuntimeException("Failed on JSON-RPC API call. HTTP error code = " + status); + } + BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + String tmp; + while ((tmp = buffer.readLine()) != null) { + sb.append(tmp); + } + } catch (ClientProtocolException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } catch (IOException ex) { + throw new CloudRuntimeException(ex.getMessage()); + } finally { + if (httpClient != null) { + try { + httpClient.getConnectionManager().shutdown(); + } catch (Exception t) { + logger.debug(t.getMessage()); + } + } + } + + String responseString = sb.toString(); + if (logger.isDebugEnabled()) { + logger.debug("NexentaStor Appliance response: " + responseString); + } + + NmsResponse nmsResponse = (NmsResponse) gson.fromJson(responseString, responseClass); + if (nmsResponse.getError() != null) { + throw new CloudRuntimeException(nmsResponse.getError().getMesssage()); + } + + return nmsResponse; + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java new file mode 100644 index 00000000000..684b8dc1d0c --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaNmsUrl.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +public class NexentaNmsUrl { + protected final boolean isAuto; + protected String schema; + protected final String username; + protected final String password; + protected final String host; + protected int port; + + public NexentaNmsUrl(boolean isAuto, String schema, String username, String password, String host, int port) { + this.isAuto = isAuto; + this.schema = schema; + this.username = username; + this.password = password; + this.host = host; + this.port = port; + } + + public boolean isAuto() { + return this.isAuto; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public String getSchema() { + return this.schema; + } + + public String getUsername() { + return this.username; + } + + public String getPassword() { + return this.password; + } + + public String getHost() { + return this.host; + } + + public int getPort() { + return this.port; + } + + public String getPath() { + return "/rest/nms"; + } + + public String toString() { + StringBuilder b = new StringBuilder(); + if (isAuto) { + b.append("auto://"); + } else { + b.append(schema).append("://"); + } + if (username != null && password != null) { + b.append(username).append(":").append(password).append("@"); + } else if (username != null) { + b.append(username).append("@"); + } + b.append(host).append(":").append(port).append("/rest/nms/"); + return b.toString(); + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java new file mode 100644 index 00000000000..c1efc75e124 --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaStorAppliance.java @@ -0,0 +1,418 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +import java.util.HashMap; +import java.util.LinkedList; + +import org.apache.cloudstack.storage.datastore.util.NexentaNmsClient.NmsResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.annotations.SerializedName; + +public class NexentaStorAppliance { + private static final Logger logger = LogManager.getLogger(NexentaStorAppliance.class); + + protected NexentaNmsClient client; + protected NexentaUtil.NexentaPluginParameters parameters; + + public NexentaStorAppliance(NexentaUtil.NexentaPluginParameters parameters) { + client = new NexentaNmsClient(parameters.getNmsUrl()); + this.parameters = parameters; + } + + NexentaStorAppliance(NexentaNmsClient client, NexentaUtil.NexentaPluginParameters parameters) { + this.client = client; + this.parameters = parameters; + } + + String getVolumeName(String volumeName) { + if (volumeName.startsWith("/")) { + return String.format("%s%s", parameters.getVolume(), volumeName); + } + return String.format("%s/%s", parameters.getVolume(), volumeName); + } + + static String getTargetName(String volumeName) { + return NexentaUtil.ISCSI_TARGET_NAME_PREFIX + volumeName; + } + + static String getTargetGroupName(String volumeName) { + return NexentaUtil.ISCSI_TARGET_GROUP_PREFIX + volumeName; + } + + @SuppressWarnings("unused") + static final class IntegerNmsResponse extends NmsResponse { + Integer result; + + IntegerNmsResponse(int result) { + this.result = Integer.valueOf(result); + } + + public Integer getResult() { + return result; + } + } + + @SuppressWarnings("unused") + static final class IscsiTarget { + protected String status; + protected String protocol; + protected String name; + protected String sessions; + protected String alias; + protected String provider; + + IscsiTarget(String status, String protocol, String name, String sessions, String alias, String provider) { + this.status = status; + this.protocol = protocol; + this.name = name; + this.sessions = sessions; + this.alias = alias; + this.provider = provider; + } + } + + @SuppressWarnings("unused") + static final class ListOfIscsiTargetsNmsResponse extends NmsResponse { + protected HashMap result; + + ListOfIscsiTargetsNmsResponse() {} + + ListOfIscsiTargetsNmsResponse(HashMap result) { + this.result = result; + } + + public HashMap getResult() { + return result; + } + } + + /** + * Checks if iSCSI target exists. + * @param targetName iSCSI target name + * @return true if iSCSI target exists, else false + */ + boolean isIscsiTargetExists(String targetName) { + ListOfIscsiTargetsNmsResponse response = (ListOfIscsiTargetsNmsResponse) client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets"); + if (response == null) { + return false; + } + HashMap result = response.getResult(); + return result != null && result.keySet().contains(targetName); + } + + @SuppressWarnings("unused") + static final class CreateIscsiTargetRequestParams { + @SerializedName("target_name") String targetName; + + CreateIscsiTargetRequestParams(String targetName) { + this.targetName = targetName; + } + + @Override + public boolean equals(Object other) { + return other instanceof CreateIscsiTargetRequestParams && targetName.equals(((CreateIscsiTargetRequestParams) other).targetName); + } + } + + /** + * Creates iSCSI target on NexentaStor Appliance. + * @param targetName iSCSI target name + */ + void createIscsiTarget(String targetName) { + try { + client.execute(NmsResponse.class, "iscsitarget", "create_target", new CreateIscsiTargetRequestParams(targetName)); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("already configured")) { + throw ex; + } + logger.debug("Ignored target creation error: " + ex); + } + } + + @SuppressWarnings("unused") + static final class ListOfStringsNmsResponse extends NmsResponse { + LinkedList result; + + ListOfStringsNmsResponse() {} + + ListOfStringsNmsResponse(LinkedList result) { + this.result = result; + } + + public LinkedList getResult() { + return result; + } + } + + /** + * Checks if iSCSI target group already exists on NexentaStor Appliance. + * @param targetGroupName iSCSI target group name + * @return true if iSCSI target group already exists, else false + */ + boolean isIscsiTargetGroupExists(String targetGroupName) { + ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups"); + if (response == null) { + return false; + } + LinkedList result = response.getResult(); + return result != null && result.contains(targetGroupName); + } + + /** + * Creates iSCSI target group on NexentaStor Appliance. + * @param targetGroupName iSCSI target group name + */ + void createIscsiTargetGroup(String targetGroupName) { + try { + client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) { + throw ex; + } + logger.info("Ignored target group creation error: " + ex); + } + } + + /** + * Checks if iSCSI target is member of target group. + * @param targetGroupName iSCSI target group name + * @param targetName iSCSI target name + * @return true if target is member of iSCSI target group, else false + */ + boolean isTargetMemberOfTargetGroup(String targetGroupName, String targetName) { + ListOfStringsNmsResponse response = (ListOfStringsNmsResponse) client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName); + if (response == null) { + return false; + } + LinkedList result = response.getResult(); + return result != null && result.contains(targetName); + } + + /** + * Adds iSCSI target to target group. + * @param targetGroupName iSCSI target group name + * @param targetName iSCSI target name + */ + void addTargetGroupMember(String targetGroupName, String targetName) { + try { + client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("already exists") && !ex.getMessage().contains("target must be offline")) { + throw ex; + } + logger.debug("Ignored target group member addition error: " + ex); + } + } + + /** + * Checks if LU already exists on NexentaStor appliance. + * @param luName LU name + * @return true if LU already exists, else false + */ + boolean isLuExists(String luName) { + IntegerNmsResponse response; + try { + response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", luName); + } catch (CloudRuntimeException ex) { + if (ex.getMessage().contains("does not exist")) { + return false; + } + throw ex; + } + return response!= null && response.getResult() > 0; + } + + @SuppressWarnings("unused") + static final class LuParams { + @Override + public boolean equals(Object other) { + return other instanceof LuParams; + } + } + + /** + * Creates LU for volume. + * @param volumeName volume name + */ + void createLu(String volumeName) { + try { + client.execute(NmsResponse.class, "scsidisk", "create_lu", volumeName, new LuParams()); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("in use")) { + throw ex; + } + logger.info("Ignored LU creation error: " + ex); + } + } + + /** + * Checks if LU shared on NexentaStor appliance. + * @param luName LU name + * @return true if LU was already shared, else false + */ + boolean isLuShared(String luName) { + IntegerNmsResponse response; + try { + response = (IntegerNmsResponse) client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName); + } catch (CloudRuntimeException ex) { + if (ex.getMessage().contains("does not exist")) { + return false; + } + throw ex; + } + return response != null && response.getResult() > 0; + } + + @SuppressWarnings("unused") + static final class MappingEntry { + @SerializedName("target_group") String targetGroup; + String lun; + String zvol; + @SerializedName("host_group") String hostGroup; + @SerializedName("entry_number") String entryNumber; + + MappingEntry(String targetGroup, String lun) { + this.targetGroup = targetGroup; + this.lun = lun; + } + + static boolean isEquals(Object a, Object b) { + return (a == null && b == null) || (a != null && a.equals(b)); + } + + @Override + public boolean equals(Object other) { + if (other instanceof MappingEntry) { + MappingEntry o = (MappingEntry) other; + return isEquals(targetGroup, o.targetGroup) && isEquals(lun, o.lun) && isEquals(zvol, o.zvol) && + isEquals(hostGroup, o.hostGroup) && isEquals(entryNumber, o.entryNumber); + } + return false; + } + } + + @SuppressWarnings("unused") + static final class AddMappingEntryNmsResponse extends NmsResponse { + MappingEntry result; + } + + /** + * Adds LU mapping entry to iSCSI target group. + * @param luName LU name + * @param targetGroupName iSCSI target group name + */ + void addLuMappingEntry(String luName, String targetGroupName) { + MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0"); + try { + client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("view already exists")) { + throw ex; + } + logger.debug("Ignored LU mapping entry addition error " + ex); + } + } + + NexentaStorZvol createIscsiVolume(String volumeName, Long volumeSize) { + final String zvolName = getVolumeName(volumeName); + String volumeSizeString = String.format("%dB", volumeSize); + + client.execute(NmsResponse.class, "zvol", "create", zvolName, volumeSizeString, parameters.getVolumeBlockSize(), parameters.getSparseVolumes()); + + final String targetName = getTargetName(volumeName); + final String targetGroupName = getTargetGroupName(volumeName); + + if (!isIscsiTargetExists(targetName)) { + createIscsiTarget(targetName); + } + + if (!isIscsiTargetGroupExists(targetGroupName)) { + createIscsiTargetGroup(targetGroupName); + } + + if (!isTargetMemberOfTargetGroup(targetGroupName, targetName)) { + addTargetGroupMember(targetGroupName, targetName); + } + + if (!isLuExists(zvolName)) { + createLu(zvolName); + } + + if (!isLuShared(zvolName)) { + addLuMappingEntry(zvolName, targetGroupName); + } + + return new NexentaStorZvol(zvolName, targetName); + } + + static abstract class NexentaStorVolume { + protected String name; + + NexentaStorVolume(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + } + + public static final class NexentaStorZvol extends NexentaStorVolume { + protected String iqn; + + public NexentaStorZvol(String name, String iqn) { + super(name); + this.iqn = iqn; + } + + public String getIqn() { + return iqn; + } + } + + public void deleteIscsiVolume(String volumeName) { + try { + NmsResponse response = client.execute(NmsResponse.class, "zvol", "destroy", volumeName, ""); + } catch (CloudRuntimeException ex) { + if (!ex.getMessage().contains("does not exist")) { + throw ex; + } + logger.debug(String.format( + "Volume %s does not exist, it seems it was already " + + "deleted.", volumeName)); + } + } + + public NexentaStorVolume createVolume(String volumeName, Long volumeSize) { + return createIscsiVolume(volumeName, volumeSize); + } + + public void deleteVolume(String volumeName) { + deleteIscsiVolume(volumeName); + } +} diff --git a/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java new file mode 100644 index 00000000000..ee6a78ff49c --- /dev/null +++ b/plugins/storage/volume/nexenta/src/org/apache/cloudstack/storage/datastore/util/NexentaUtil.java @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.StringTokenizer; + +import com.cloud.storage.Storage; + +public class NexentaUtil { + public static final String PROVIDER_NAME = "Nexenta"; + + public static final String NMS_URL = "nmsUrl"; + public static final String VOLUME = "volume"; + + public static final String STORAGE_HOST = "storageHost"; + public static final String STORAGE_PORT = "storagePort"; + public static final String STORAGE_TYPE = "storageType"; + public static final String STORAGE_PATH = "storagePath"; + + public static final String DEFAULT_NMS_USER = "admin"; + public static final String DEFAULT_NMS_PASSWORD = "nexenta"; + + public static final String SPARSE_VOLUMES = "sparseVolumes"; + public static final String VOLUME_BLOCK_SIZE = "volumeBlockSize"; + + public static final int DEFAULT_NMS_PORT = 2000; + public static final int DEFAULT_ISCSI_TARGET_PORTAL_PORT = 3260; + public static final int DEFAULT_NFS_PORT = 2049; + + public static final String ISCSI_TARGET_NAME_PREFIX = "iqn.1986-03.com.sun:02:cloudstack-"; + public static final String ISCSI_TARGET_GROUP_PREFIX = "cloudstack/"; + + /** + * Parse NMS url into normalized parts like scheme, user, host and others. + * + * Example NMS URL: + * auto://admin:nexenta@192.168.1.1:2000/ + * + * NMS URL parts: + * auto true if url starts with auto://, protocol will be automatically switched to https if http not supported; + * scheme (auto) connection protocol (http or https); + * user (admin) NMS user; + * password (nexenta) NMS password; + * host (192.168.1.1) NMS host; + * port (2000) NMS port. + * + * @param nmsUrl url string to parse + * @return instance of NexentaConnection class + */ + public static NexentaNmsUrl parseNmsUrl(String nmsUrl) { + URI uri; + + try { + uri = new URI(nmsUrl); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid URI: " + nmsUrl); + } + + boolean isAuto = false; + String schema = uri.getScheme(); + if (schema == null || schema.isEmpty() || "auto".equalsIgnoreCase(schema)) { + schema = "http"; + isAuto = true; + } + + String username, password, userInfo = uri.getUserInfo(); + if (userInfo == null) { + username = DEFAULT_NMS_USER; + password = DEFAULT_NMS_PASSWORD; + } else { + if (userInfo.indexOf(':') < 0) { + username = userInfo; + password = DEFAULT_NMS_PASSWORD; + } else { + String[] parts = userInfo.split(":", 2); + username = parts[0]; + password = parts[1]; + } + } + + String host = uri.getHost(); + if (host == null) { + throw new IllegalArgumentException(String.format("NMS host required: %s.", nmsUrl)); + } + + int port = uri.getPort(); + if (port == -1) { + port = DEFAULT_NMS_PORT; + } + + return new NexentaNmsUrl(isAuto, schema, username, password, host, port); + } + + public static Storage.StoragePoolType getStorageType(String v) { + if ("iSCSI".equalsIgnoreCase(v)) { + return Storage.StoragePoolType.Iscsi; + } else if ("NFS".equalsIgnoreCase(v)) { + return Storage.StoragePoolType.NetworkFilesystem; + } + return Storage.StoragePoolType.Iscsi; + } + + public static class NexentaPluginParameters { + protected NexentaNmsUrl nmsUrl; + protected String volume; + protected Storage.StoragePoolType storageType = Storage.StoragePoolType.Iscsi; + protected String storageHost; + protected Integer storagePort; + protected String storagePath; + protected Boolean sparseVolumes = false; + protected String volumeBlockSize = "8K"; + + public void setNmsUrl(String url) { + this.nmsUrl = NexentaUtil.parseNmsUrl(url); + } + + public NexentaNmsUrl getNmsUrl() { + return nmsUrl; + } + + public void setVolume(String volume) { + if (volume.endsWith("/")) { + this.volume = volume.substring(0, volume.length() - 1); + } else { + this.volume = volume; + } + } + + public String getVolume() { + return volume; + } + + public void setStorageType(String storageType) { + this.storageType = NexentaUtil.getStorageType(storageType); + } + + public Storage.StoragePoolType getStorageType() { + return storageType; + } + + public void setStorageHost(String host) { + this.storageHost = host; + } + + public String getStorageHost() { + if (storageHost == null && nmsUrl != null) { + return nmsUrl.getHost(); + } + return storageHost; + } + + public void setStoragePort(String port) { + this.storagePort = Integer.parseInt(port); + } + + public Integer getStoragePort() { + if (storagePort == null && storageType != null) { + if (storageType == Storage.StoragePoolType.Iscsi) { + return DEFAULT_ISCSI_TARGET_PORTAL_PORT; + } else { + return DEFAULT_NFS_PORT; + } + } + return storagePort; + } + + public void setStoragePath(String path) { + this.storagePath = path; + } + + public String getStoragePath() { + return storagePath; + } + + public void setSparseVolumes(String sparseVolumes) { + this.sparseVolumes = Boolean.TRUE.toString().equalsIgnoreCase(sparseVolumes); + } + + public Boolean getSparseVolumes() { + return sparseVolumes; + } + + public void setVolumeBlockSize(String volumeBlockSize) { + this.volumeBlockSize = volumeBlockSize; + } + + public String getVolumeBlockSize() { + return volumeBlockSize; + } + } + + public static NexentaPluginParameters parseNexentaPluginUrl(String url) { + final String delimiter1 = ";"; + final String delimiter2 = "="; + StringTokenizer st = new StringTokenizer(url, delimiter1); + NexentaPluginParameters params = new NexentaPluginParameters(); + while (st.hasMoreElements()) { + String token = st.nextElement().toString(); + int idx = token.indexOf(delimiter2); + if (idx == -1) { + throw new RuntimeException("Invalid URL format"); + } + String[] urlKeyAndValue = token.split(delimiter2, 2); + if (NMS_URL.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setNmsUrl(urlKeyAndValue[1]); + } else if (VOLUME.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setVolume(urlKeyAndValue[1]); + } else if (STORAGE_TYPE.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setStorageType(urlKeyAndValue[1]); + } else if (STORAGE_HOST.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setStorageHost(urlKeyAndValue[1]); + } else if (STORAGE_PORT.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setStoragePort(urlKeyAndValue[1]); + } else if (STORAGE_PATH.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setStoragePath(urlKeyAndValue[1]); + } else if (SPARSE_VOLUMES.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setSparseVolumes(urlKeyAndValue[1]); + } else if (VOLUME_BLOCK_SIZE.equalsIgnoreCase(urlKeyAndValue[0])) { + params.setVolumeBlockSize(urlKeyAndValue[1]); + } + } + return params; + } +} diff --git a/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java b/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java new file mode 100644 index 00000000000..6dc59ebd0af --- /dev/null +++ b/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaStorApplianceTest.java @@ -0,0 +1,337 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.IscsiTarget; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.ListOfIscsiTargetsNmsResponse; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.CreateIscsiTargetRequestParams; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.ListOfStringsNmsResponse; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.IntegerNmsResponse; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.LuParams; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.MappingEntry; +import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.AddMappingEntryNmsResponse; +import static org.apache.cloudstack.storage.datastore.util.NexentaNmsClient.NmsResponse; + + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.LinkedList; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import com.cloud.utils.exception.CloudRuntimeException; + +@RunWith(MockitoJUnitRunner.class) +public class NexentaStorApplianceTest { + private NexentaNmsClient client; + + private NexentaStorAppliance appliance; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void init() { + final String url = "nmsUrl=https://admin:nexenta@10.1.3.182:8457;volume=cloudstack;storageType=iscsi"; + NexentaUtil.NexentaPluginParameters parameters = NexentaUtil.parseNexentaPluginUrl(url); + //client = new NexentaNmsClient(parameters.getNmsUrl()); + client = mock(NexentaNmsClient.class); + appliance = new NexentaStorAppliance(client, parameters); + } + + @Test + public void testIsIscsiTargetExists() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + + when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(null); + assertFalse(appliance.isIscsiTargetExists(targetName)); + + when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse()); + assertFalse(appliance.isIscsiTargetExists(targetName)); + + final HashMap result = new HashMap(); + + result.put("any", new IscsiTarget("Online", "iSCSI", "any", "0", "-", "iscsit")); + when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse(result)); + assertFalse(appliance.isIscsiTargetExists(targetName)); + + result.put(targetName, new IscsiTarget("Online", "iSCSI", targetName, "0", "-", "iscsit")); + when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse(result)); + assertTrue(appliance.isIscsiTargetExists(targetName)); + } + + final static String ISCSI_TARGET_ALREADY_CONFIGURED_ERROR = "Unable to create iscsi target\\n iSCSI target %s already configured\\n itadm create-target failed with error " + + "17\\n"; + + @Test + public void testCreateIscsiTarget() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + final CreateIscsiTargetRequestParams p = new CreateIscsiTargetRequestParams(targetName); + + appliance.createIscsiTarget(targetName); + verify(client).execute(NmsResponse.class, "iscsitarget", "create_target", p); + + final String error = String.format(ISCSI_TARGET_ALREADY_CONFIGURED_ERROR, targetName); + when(client.execute(NmsResponse.class, "iscsitarget", "create_target", p)).thenThrow(new CloudRuntimeException(error)); + appliance.createIscsiTarget(targetName); + } + + @Test + public void testCreateIscsiTargetFails() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + final CreateIscsiTargetRequestParams p = new CreateIscsiTargetRequestParams(targetName); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + when(client.execute(NmsResponse.class, "iscsitarget", "create_target", p)).thenThrow(new CloudRuntimeException("any exception")); + appliance.createIscsiTarget(targetName); + } + + @Test + public void testIsIscsiTargetGroupExists() { + final String targetGroup = NexentaStorAppliance.getTargetGroupName("volume1"); + + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(null); + assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); + + when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfIscsiTargetsNmsResponse()); + assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); + + LinkedList result = new LinkedList(); + + result.add("any"); + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfStringsNmsResponse(result)); + assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); + + result.add(targetGroup); + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfStringsNmsResponse(result)); + assertTrue(appliance.isIscsiTargetGroupExists(targetGroup)); + } + + final static String ISCSI_TARGET_GROUP_EXISTS_ERROR = "Unable to create targetgroup: stmfadm: %s: already exists\\n"; + + @Test + public void testCreateIscsiTargetGroup() { + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + + appliance.createIscsiTargetGroup(targetGroupName); + verify(client).execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName); + + final String error = String.format(ISCSI_TARGET_GROUP_EXISTS_ERROR, targetGroupName); + when(client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName)).thenThrow(new CloudRuntimeException(error)); + appliance.createIscsiTargetGroup(targetGroupName); + } + + @Test + public void testCreateIscsiTargetGroupFails() { + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + when(client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName)).thenThrow(new CloudRuntimeException("any exception")); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + appliance.createIscsiTargetGroup(targetGroupName); + } + + @Test + public void testIsMemberOfTargetGroup() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(null); + assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); + + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse()); + assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); + + LinkedList result = new LinkedList(); + + result.add("any"); + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse(result)); + assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); + + result.add(targetName); + when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse(result)); + assertTrue(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); + } + + @Test + public void testAddTargetGroupMember() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + + appliance.addTargetGroupMember(targetGroupName, targetName); + verify(client).execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName); + + String error = String.format(ISCSI_TARGET_ALREADY_EXISTS_IN_TARGET_GROUP_ERROR, targetName); + when(client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName)).thenThrow(new CloudRuntimeException(error)); + appliance.addTargetGroupMember(targetGroupName, targetName); + } + + final static String ISCSI_TARGET_ALREADY_EXISTS_IN_TARGET_GROUP_ERROR = "Unable to add member to targetgroup: stmfadm: %s: already exists\\n"; + + @Test + public void testAddTargetGroupMemberFails() { + final String targetName = NexentaStorAppliance.getTargetName("volume1"); + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + + when(client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName)).thenThrow(new CloudRuntimeException("any exception")); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + appliance.addTargetGroupMember(targetGroupName, targetName); + } + + @Test + public void testIsLuExists() { + final String volumeName = appliance.getVolumeName("volume1"); + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(null); + assertFalse(appliance.isLuExists(volumeName)); + + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(new IntegerNmsResponse(0)); + assertFalse(appliance.isLuExists(volumeName)); + + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(new IntegerNmsResponse(1)); + assertTrue(appliance.isLuExists(volumeName)); + + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenThrow(new CloudRuntimeException("does not exist")); + assertFalse(appliance.isLuExists(volumeName)); + } + + @Test + public void testIsLuExistsFails() { + final String volumeName = appliance.getVolumeName("volume1"); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenThrow(new CloudRuntimeException("any exception")); + assertTrue(appliance.isLuExists(volumeName)); + } + + final static String CREATE_LU_IN_USE_ERROR = "Unable to create lu with " + + "zvol '%s':\\n stmfadm: filename /dev/zvol/rdsk/%s: in use\\n"; + + @Test + public void testCreateLu() { + final String luName = appliance.getVolumeName("volume1"); + final LuParams p = new LuParams(); + + appliance.createLu(luName); + verify(client).execute(NmsResponse.class, "scsidisk", "create_lu", luName, p); + + String error = String.format(CREATE_LU_IN_USE_ERROR, luName, luName); + when(client.execute(NmsResponse.class, "scsidisk", "create_lu", luName, p)).thenThrow(new CloudRuntimeException(error)); + appliance.createLu(luName); + } + + @Test + public void testCreateLuFails() { + final String luName = appliance.getVolumeName("volume1"); + when(client.execute(NmsResponse.class, "scsidisk", "create_lu", luName, new LuParams())).thenThrow(new CloudRuntimeException("any exception")); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + appliance.createLu(luName); + } + + final static String ZVOL_DOES_NOT_EXISTS_ERROR = "Zvol '%s' does not exist"; + + @Test + public void testIsLuShared() { + final String luName = appliance.getVolumeName("volume1"); + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(null); + assertFalse(appliance.isLuShared(luName)); + + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(new IntegerNmsResponse(0)); + assertFalse(appliance.isLuShared(luName)); + + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(new IntegerNmsResponse(1)); + assertTrue(appliance.isLuShared(luName)); + + final String error = String.format(ZVOL_DOES_NOT_EXISTS_ERROR, luName); + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenThrow(new CloudRuntimeException(error)); + assertFalse(appliance.isLuShared(luName)); + } + + @Test + public void testIsLuSharedFails() { + final String luName = appliance.getVolumeName("volume1"); + when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenThrow(new CloudRuntimeException("any exception")); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + appliance.isLuShared(luName); + } + + final static String ADD_LUN_MAPPING_ENTRY_ERROR = "(rc: 256) Unable to " + + "add view to zvol '%s':\\n add-view: view already exists\\n"; + + @Test + public void testAddLuMappingEntry() { + final String luName = appliance.getVolumeName("volume1"); + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + final MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0"); + appliance.addLuMappingEntry(luName, targetGroupName); + verify(client).execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry); + + String error = String.format(ADD_LUN_MAPPING_ENTRY_ERROR, luName); + when(client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry)).thenThrow(new CloudRuntimeException(error)); + appliance.addLuMappingEntry(luName, targetGroupName); + } + + @Test + public void testAddLuMappingEntryTest() { + final String luName = appliance.getVolumeName("volume1"); + final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); + final MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0"); + when(client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry)).thenThrow(new CloudRuntimeException("any exception")); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + appliance.addLuMappingEntry(luName, targetGroupName); + } + + @Test + public void testCreateIscsiVolume() { + final String volumeName = "volume1"; + final Long volumeSize = Long.valueOf(1); + appliance.createIscsiVolume(volumeName, volumeSize); + } + + @Test + public void testDeleteIscsiVolume() { + final String volumeName = appliance.getVolumeName("volume1"); + appliance.deleteIscsiVolume(volumeName); + verify(client).execute(NmsResponse.class, "zvol", "destroy", volumeName, ""); + + when(client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "")).thenThrow(new CloudRuntimeException(String.format("Zvol '%s' does not exist", volumeName))); + appliance.deleteIscsiVolume(volumeName); + } + + @Test + public void testDeleteIscsiVolumeFails() { + final String volumeName = appliance.getVolumeName("volume1"); + exception.expect(CloudRuntimeException.class); + exception.expectMessage("any exception"); + when(client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "")).thenThrow(new CloudRuntimeException("any exception")); + appliance.deleteIscsiVolume(volumeName); + } +} diff --git a/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java b/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java new file mode 100644 index 00000000000..8f4498557c1 --- /dev/null +++ b/plugins/storage/volume/nexenta/test/org/apache/cloudstack/storage/datastore/util/NexentaUtilTest.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.datastore.util; + +import static junit.framework.Assert.assertNull; +import static org.junit.Assert.assertEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import com.cloud.storage.Storage; + +@RunWith(JUnit4.class) +public class NexentaUtilTest { + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void testParseNmsUrl() { + NexentaNmsUrl c; + + c = NexentaUtil.parseNmsUrl("auto://192.168.1.1/"); + assertEquals(c.toString(), "auto://admin:nexenta@192.168.1.1:2000/rest/nms/"); + assertEquals(c.getSchema(), "http"); + + c = NexentaUtil.parseNmsUrl("http://192.168.1.1/"); + assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/"); + + c = NexentaUtil.parseNmsUrl("http://192.168.1.1:8080"); + assertEquals(c.toString(), "http://admin:nexenta@192.168.1.1:8080/rest/nms/"); + + c = NexentaUtil.parseNmsUrl("https://root@192.168.1.1:8080"); + assertEquals(c.toString(), "https://root:nexenta@192.168.1.1:8080/rest/nms/"); + + c = NexentaUtil.parseNmsUrl("https://root:password@192.168.1.1:8080"); + assertEquals(c.toString(), "https://root:password@192.168.1.1:8080/rest/nms/"); + } + + @Test + public void testGetStorageType() { + assertEquals(NexentaUtil.getStorageType("iscsi"), Storage.StoragePoolType.Iscsi); + assertEquals(NexentaUtil.getStorageType("nfs"), Storage.StoragePoolType.NetworkFilesystem); + assertEquals(NexentaUtil.getStorageType("any"), Storage.StoragePoolType.Iscsi); + } + + @Test + public void testParseNexentaPluginUrl() { + String url = "nmsUrl=http://admin:nexenta@192.168.1.1:2000;"; + + NexentaUtil.NexentaPluginParameters parameters; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/"); + assertNull(parameters.getVolume()); + assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi); + assertEquals(parameters.getStorageHost(), "192.168.1.1"); + assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT); + assertNull(parameters.getStoragePath()); + assertEquals((boolean) parameters.getSparseVolumes(), false); + assertEquals(parameters.getVolumeBlockSize(), "8K"); + + url += "volume=cloudstack"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/"); + assertEquals(parameters.getVolume(), "cloudstack"); + + url += "/;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getVolume(), "cloudstack"); + + url += "storageType="; + parameters = NexentaUtil.parseNexentaPluginUrl(url + "nfs"); + assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem); + assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_NFS_PORT); + + parameters = NexentaUtil.parseNexentaPluginUrl(url + "iscsi"); + assertEquals(parameters.getStorageType(), Storage.StoragePoolType.Iscsi); + assertEquals((int) parameters.getStoragePort(), NexentaUtil.DEFAULT_ISCSI_TARGET_PORTAL_PORT); + + url += "nfs;storageHost=192.168.1.2;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getStorageHost(), "192.168.1.2"); + + url += "storagePort=3000;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals((int) parameters.getStoragePort(), 3000); + + url += "storagePath=/volumes/cloudstack;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getStoragePath(), "/volumes/cloudstack"); + + url += "sparseVolumes=true;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getSparseVolumes(), Boolean.TRUE); + + url += "volumeBlockSize=128K;"; + parameters = NexentaUtil.parseNexentaPluginUrl(url); + assertEquals(parameters.getVolumeBlockSize(), "128K"); + + url += "unknownParameter=value;"; // NOTE: exception should not be raised + parameters = NexentaUtil.parseNexentaPluginUrl(url); + + assertEquals(parameters.getNmsUrl().toString(), "http://admin:nexenta@192.168.1.1:2000/rest/nms/"); + assertEquals(parameters.getVolume(), "cloudstack"); + assertEquals(parameters.getStorageType(), Storage.StoragePoolType.NetworkFilesystem); + assertEquals(parameters.getStorageHost(), "192.168.1.2"); + assertEquals((int) parameters.getStoragePort(), 3000); + assertEquals(parameters.getStoragePath(), "/volumes/cloudstack"); + assertEquals(parameters.getSparseVolumes(), Boolean.TRUE); + assertEquals(parameters.getVolumeBlockSize(), "128K"); + + exception.expect(RuntimeException.class); + exception.expectMessage("Invalid URL format"); + + NexentaUtil.parseNexentaPluginUrl(url + "invalidParameter"); + } +} diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 7d305e0f1b3..014413d3452 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -217,6 +217,12 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } } + @Override + public ChapInfo getChapInfo(VolumeInfo volumeInfo) { + return null; + } + + /* @Override public ChapInfo getChapInfo(VolumeInfo volumeInfo) { long accountId = volumeInfo.getAccountId(); @@ -239,6 +245,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { return new ChapInfoImpl(chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret); } + */ // get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups) // if the VAG exists diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java index 0bfbab60424..afba27238a4 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapAuthenticator.java @@ -25,6 +25,7 @@ import org.apache.log4j.Logger; import com.cloud.server.auth.DefaultUserAuthenticator; import com.cloud.user.UserAccount; import com.cloud.user.dao.UserAccountDao; +import com.cloud.utils.Pair; public class LdapAuthenticator extends DefaultUserAuthenticator { private static final Logger s_logger = Logger.getLogger(LdapAuthenticator.class.getName()); @@ -45,17 +46,23 @@ public class LdapAuthenticator extends DefaultUserAuthenticator { } @Override - public boolean authenticate(final String username, final String password, final Long domainId, final Map requestParameters) { + public Pair authenticate(final String username, final String password, final Long domainId, final Map requestParameters) { final UserAccount user = _userAccountDao.getUserAccount(username, domainId); if (user == null) { s_logger.debug("Unable to find user with " + username + " in domain " + domainId); - return false; + return new Pair(false, null); } else if (_ldapManager.isLdapEnabled()) { - return _ldapManager.canAuthenticate(username, password); + boolean result = _ldapManager.canAuthenticate(username, password); + ActionOnFailedAuthentication action = null; + if (result == false) { + action = ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT; + } + return new Pair(result, action); + } else { - return false; + return new Pair(false, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT); } } diff --git a/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java b/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java index f1fe448ffb5..c1415d256bb 100644 --- a/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java +++ b/plugins/user-authenticators/md5/src/com/cloud/server/auth/MD5UserAuthenticator.java @@ -27,6 +27,7 @@ import org.apache.log4j.Logger; import com.cloud.user.UserAccount; import com.cloud.user.dao.UserAccountDao; +import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -42,21 +43,21 @@ public class MD5UserAuthenticator extends DefaultUserAuthenticator { private UserAccountDao _userAccountDao; @Override - public boolean authenticate(String username, String password, Long domainId, Map requestParameters) { + public Pair authenticate(String username, String password, Long domainId, Map requestParameters) { if (s_logger.isDebugEnabled()) { s_logger.debug("Retrieving user: " + username); } UserAccount user = _userAccountDao.getUserAccount(username, domainId); if (user == null) { s_logger.debug("Unable to find user with " + username + " in domain " + domainId); - return false; + return new Pair(false, null); } if (!user.getPassword().equals(encode(password))) { s_logger.debug("Password does not match"); - return false; + return new Pair(false, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT); } - return true; + return new Pair(true, null); } @Override diff --git a/plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java b/plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java index ac03fde1dda..0afbbfc1c95 100644 --- a/plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java +++ b/plugins/user-authenticators/plain-text/src/com/cloud/server/auth/PlainTextUserAuthenticator.java @@ -24,6 +24,7 @@ import org.apache.log4j.Logger; import com.cloud.user.UserAccount; import com.cloud.user.dao.UserAccountDao; +import com.cloud.utils.Pair; @Local(value = {UserAuthenticator.class}) public class PlainTextUserAuthenticator extends DefaultUserAuthenticator { @@ -33,7 +34,7 @@ public class PlainTextUserAuthenticator extends DefaultUserAuthenticator { private UserAccountDao _userAccountDao; @Override - public boolean authenticate(String username, String password, Long domainId, Map requestParameters) { + public Pair authenticate(String username, String password, Long domainId, Map requestParameters) { if (s_logger.isDebugEnabled()) { s_logger.debug("Retrieving user: " + username); } @@ -41,14 +42,14 @@ public class PlainTextUserAuthenticator extends DefaultUserAuthenticator { UserAccount user = _userAccountDao.getUserAccount(username, domainId); if (user == null) { s_logger.debug("Unable to find user with " + username + " in domain " + domainId); - return false; + return new Pair(false, null); } if (!user.getPassword().equals(password)) { s_logger.debug("Password does not match"); - return false; + return new Pair(false, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT); } - return true; + return new Pair(true, null); } @Override diff --git a/plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java b/plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java index 8dac9c49714..36305f18c99 100644 --- a/plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java +++ b/plugins/user-authenticators/sha256salted/src/com/cloud/server/auth/SHA256SaltedUserAuthenticator.java @@ -30,6 +30,7 @@ import org.bouncycastle.util.encoders.Base64; import com.cloud.user.UserAccount; import com.cloud.user.dao.UserAccountDao; +import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @Local(value = {UserAuthenticator.class}) @@ -45,7 +46,7 @@ public class SHA256SaltedUserAuthenticator extends DefaultUserAuthenticator { * @see com.cloud.server.auth.UserAuthenticator#authenticate(java.lang.String, java.lang.String, java.lang.Long, java.util.Map) */ @Override - public boolean authenticate(String username, String password, Long domainId, Map requestParameters) { + public Pair authenticate(String username, String password, Long domainId, Map requestParameters) { if (s_logger.isDebugEnabled()) { s_logger.debug("Retrieving user: " + username); } @@ -71,7 +72,12 @@ public class SHA256SaltedUserAuthenticator extends DefaultUserAuthenticator { try { String hashedPassword = encode(password, salt); /* constantTimeEquals comes first in boolean since we need to thwart timing attacks */ - return constantTimeEquals(realPassword, hashedPassword) && realUser; + boolean result = constantTimeEquals(realPassword, hashedPassword) && realUser; + ActionOnFailedAuthentication action = null; + if (!result && realUser) { + action = ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT; + } + return new Pair(result, action); } catch (NoSuchAlgorithmException e) { throw new CloudRuntimeException("Unable to hash password", e); } catch (UnsupportedEncodingException e) { diff --git a/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java b/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java index 46d9af89a24..0a9bd2fa7c2 100644 --- a/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java +++ b/plugins/user-authenticators/sha256salted/test/src/com/cloud/server/auth/test/AuthenticatorTest.java @@ -92,11 +92,11 @@ public class AuthenticatorTest { @Test public void testAuthentication() throws UnsupportedEncodingException, NoSuchAlgorithmException { Map dummyMap = new HashMap(); - assertEquals("32 byte salt authenticated", true, authenticator.authenticate("admin", "password", 0L, dummyMap)); - assertEquals("20 byte salt authenticated", true, authenticator.authenticate("admin20Byte", "password", 0L, dummyMap)); - assertEquals("fake user not authenticated", false, authenticator.authenticate("fake", "fake", 0L, dummyMap)); - assertEquals("bad password not authenticated", false, authenticator.authenticate("admin", "fake", 0L, dummyMap)); - assertEquals("20 byte user bad password not authenticated", false, authenticator.authenticate("admin20Byte", "fake", 0L, dummyMap)); + assertEquals("32 byte salt authenticated", true, authenticator.authenticate("admin", "password", 0L, dummyMap).first()); + assertEquals("20 byte salt authenticated", true, authenticator.authenticate("admin20Byte", "password", 0L, dummyMap).first()); + assertEquals("fake user not authenticated", false, authenticator.authenticate("fake", "fake", 0L, dummyMap).first()); + assertEquals("bad password not authenticated", false, authenticator.authenticate("admin", "fake", 0L, dummyMap).first()); + assertEquals("20 byte user bad password not authenticated", false, authenticator.authenticate("admin20Byte", "fake", 0L, dummyMap).first()); } // @Test diff --git a/pom.xml b/pom.xml index c661d31da6e..d8c8851a3bf 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ - 1.6 + 1.7 UTF-8 1.2.16 @@ -87,6 +87,7 @@ 1.0.10 4.0.0 2.11 + 2.5 @@ -171,7 +172,6 @@ engine plugins framework - test client services maven-standard @@ -448,40 +448,105 @@ org.apache.maven.plugins maven-checkstyle-plugin + + + cloudstack-checkstyle + none + false + + - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${cs.checkstyle.version} - - - org.apache.cloudstack - checkstyle - ${project.version} - - - + com.mycila + license-maven-plugin - validate + cloudstack-checklicence + none check - - true - cloud-style.xml - true - true - ${project.basedir} - **\/*.java - **\/deps\/,**\/test\/,**\/target\/,**\/bin\/,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/awsapi\/,**\/XenServerJava\/,**\/apidoc\/ - + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + none + + check + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${cs.checkstyle.version} + + + org.apache.cloudstack + checkstyle + ${project.version} + + + + + cloudstack-checkstyle + validate + + check + + + + + true + cloud-style.xml + true + true + ${project.basedir} + **\/*.java + **\/deps\/,**\/test\/,**\/target\/,**\/bin\/,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/awsapi\/,**\/XenServerJava\/,**\/apidoc\/ + + + + com.mycila + license-maven-plugin + ${cs.mycila.license.version} + + + cloudstack-checklicence + process-classes + + check + + + + + true + true +
LICENSE.header
+ + XML_STYLE +     DOUBLESLASH_STYLE +     SEMICOLON_STYLE + + false + + **/target/** + .settings/** + .checkstyle + .project + .classpath + +
+
maven-clean-plugin @@ -525,6 +590,15 @@ + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + 9000 + ${basedir}/target/site/tempdir + + @@ -562,11 +636,12 @@ - com.mycila.maven-license-plugin - maven-license-plugin - [1.9.0,) + com.mycila + license-maven-plugin + [2.5,) format + check @@ -787,9 +862,64 @@ + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.3 + + Max + High + true + false + 1024 + + + + cloudstack-findbugs + + check + + + +
+ + + + org.codehaus.mojo + findbugs-maven-plugin + + Low + Default + + + + org.apache.maven.plugins + maven-javadoc-plugin + + 128m + 1g + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.7 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.6 + + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + + awsapi @@ -820,6 +950,7 @@ tools/devcloud/devcloud.cfg + test developer tools @@ -844,5 +975,41 @@ vmware-base + + disablecheckstyle + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + cloudstack-checkstyle + none + true + + + + + + + + enablefindbugs + + + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + process-classes + true + + + + + +
diff --git a/scripts/network/domr/bumpUpPriority.sh b/scripts/network/domr/bumpUpPriority.sh deleted file mode 100755 index 3a7eaf94e4e..00000000000 --- a/scripts/network/domr/bumpUpPriority.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -usage() { - printf "Usage:\n %s \n" $(basename $0) >&2 - printf " %s \n" $(basename $0) >&2 -} - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/bumpup_priority.sh" -exit $? diff --git a/scripts/network/domr/call_firewall.sh b/scripts/network/domr/call_firewall.sh deleted file mode 100755 index f6ad0be1316..00000000000 --- a/scripts/network/domr/call_firewall.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# $Id: call_firewall.sh 9132 2010-06-04 20:17:43Z manuel $ $HeadURL: svn://svn.lab.vmops.com/repos/branches/2.0.0/java/scripts/vm/hypervisor/xenserver/patch/call_firewall.sh $ -# firewall.sh -- allow some ports / protocols to vm instances -usage() { - printf "Usage for Firewall rule : %s: -F " $(basename $0) >&2 - printf "Usage for other purposes : %s: (-A|-D) -i -r -P protocol (-p port_range | -t icmp_type_code) -l -d [-f -u -y -z ] \n" $(basename $0) >&2 -} - -#set -x - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi -fflag= -eflag= -while getopts ':FE' OPTION -do - case $OPTION in - F) fflag=1 - ;; - E) eflag=1 - ;; - \?) ;; - esac -done - -if [ -n "$eflag" ] -then - ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewallRule_egress.sh $*" -elif [ -n "$fflag" ] -then - ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall_rule.sh $*" -else - ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall.sh $*" -fi -exit $? diff --git a/scripts/network/domr/call_loadbalancer.sh b/scripts/network/domr/call_loadbalancer.sh deleted file mode 100755 index 070947cbb15..00000000000 --- a/scripts/network/domr/call_loadbalancer.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# $Id: call_loadbalancer.sh 9132 2010-06-04 20:17:43Z manuel $ $HeadURL: svn://svn.lab.vmops.com/repos/branches/2.0.0/java/scripts/vm/hypervisor/xenserver/patch/call_loadbalancer.sh $ -# loadbalancer.sh -- reconfigure loadbalancer rules - -usage() { - printf "Usage: %s: -i -a -d -f -s \n" $(basename $0) >&2 -} - -set -x - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - -copy_haproxy() { - local domRIp=$1 - local cfg=$2 - - scp -P 3922 -q -o StrictHostKeyChecking=no -i $cert $cfg root@$domRIp:/etc/haproxy/haproxy.cfg.new - return $? -} - -iflag= -aflag= -dflag= -fflag= -sflag= - -while getopts 'i:a:d:f:s:' OPTION -do - case $OPTION in - i) iflag=1 - domRIp="$OPTARG" - ;; - a) aflag=1 - addedIps="$OPTARG" - ;; - d) dflag=1 - removedIps="$OPTARG" - ;; - f) fflag=1 - cfgfile="$OPTARG" - ;; - s) sflag=1 - statsIps="$OPTARG" - ;; - ?) usage - exit 2 - ;; - esac -done - -cert="/root/.ssh/id_rsa.cloud" - -if [ "$iflag$fflag" != "11" ] -then - usage - exit 2 -fi - -# Check if DomR is up and running. If it isn't, exit 1. -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - -copy_haproxy $domRIp $cfgfile - -if [ $? -gt 0 ] -then - printf "Reconfiguring loadbalancer failed\n" - exit 1 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/loadbalancer.sh $*" -exit $? diff --git a/scripts/network/domr/deleteipAlias.sh b/scripts/network/domr/deleteipAlias.sh deleted file mode 100755 index 6816edd524c..00000000000 --- a/scripts/network/domr/deleteipAlias.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -usage() { - printf " %s routerip \n" $(basename $0) >&2 -} - -set -x -cert="/root/.ssh/id_rsa.cloud" -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$1 "/root/deleteIpAlias.sh $2 $3" diff --git a/scripts/network/domr/dhcp_entry.sh b/scripts/network/domr/dhcp_entry.sh deleted file mode 100755 index fb5a1669e72..00000000000 --- a/scripts/network/domr/dhcp_entry.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# $Id: dhcp_entry.sh 9804 2010-06-22 18:36:49Z alex $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/network/domr/dhcp_entry.sh $ -# dhcp_entry.sh -- add dhcp entry on domr -# @VERSION@ - -usage() { - printf "Usage: %s: -r -m -v -n -s -d -N -6 -u [-z]\n" $(basename $0) >&2 - exit 2 -} - -cert="/root/.ssh/id_rsa.cloud" - -domrIp= -vmMac= -vmIp= -vmName= -staticrt= -dfltrt= -dns= -ipv6= -duid= - -opts= - -while getopts 'r:m:v:n:d:s:N:6:u:z' OPTION -do - case $OPTION in - r) domrIp="$OPTARG" - ;; - v) vmIp="$OPTARG" - opts="$opts -4 $vmIp" - ;; - m) vmMac="$OPTARG" - opts="$opts -m $vmMac" - ;; - n) vmName="$OPTARG" - opts="$opts -h $vmName" - ;; - s) staticrt="$OPTARG" - opts="$opts -s $staticrt" - ;; - d) dfltrt="$OPTARG" - opts="$opts -d $dfltrt" - ;; - N) dns="$OPTARG" - opts="$opts -n $dns" - ;; - 6) ipv6="$OPTARG" - opts="$opts -6 $ipv6" - ;; - u) duid="$OPTARG" - opts="$opts -u $duid" - ;; - z) opts="$opts -N" - ;; - ?) usage - exit 1 - ;; - esac -done - -ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domrIp "/root/edithosts.sh $opts " >/dev/null - -exit $? diff --git a/scripts/network/domr/save_password_to_domr.sh b/scripts/network/domr/save_password_to_domr.sh deleted file mode 100755 index 9b44663fd79..00000000000 --- a/scripts/network/domr/save_password_to_domr.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - -# $Id: save_password_to_domr.sh 9804 2010-06-22 18:36:49Z alex $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/network/domr/save_password_to_domr.sh $ -# @VERSION@ - -PASSWD_FILE=/var/cache/cloud/passwords - -# $1 filename -# $2 keyname -# $3 value -replace_in_file_on_domr() { - local filename=$1 - local keyname=$2 - local value=$3 - $VIA_SSH "sed -i /$keyname=/d $filename; \ - echo "$keyname=$value" >> $filename " - - # $VIA_SSH "sed -e /$keyname/d $filename > $filename.new; \ - # mv $filename.new $filename;\ - # echo "$keyname=$value" >> $filename " - - return $? -} - -cert="/root/.ssh/id_rsa.cloud" - -while getopts 'r:v:p:' OPTION -do - case $OPTION in - r) - DOMR_IP="$OPTARG" - ;; - v) VM_IP="$OPTARG" - ;; - p) - ENCODEDPASSWORD="$OPTARG" - PASSWORD=$(echo $ENCODEDPASSWORD | tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]') - ;; - ?) echo "Incorrect usage" - exit 1 - ;; - esac -done - -VIA_SSH="ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$DOMR_IP" - -$VIA_SSH "if [ ! -f $PASSWD_FILE ]; then touch $PASSWD_FILE; fi;" - -replace_in_file_on_domr $PASSWD_FILE $VM_IP $PASSWORD - -if [ $? -ne 0 ] -then - exit 1 -fi - -exit 0 diff --git a/scripts/vm/hypervisor/xenserver/vhd-util b/scripts/vm/hypervisor/xenserver/vhd-util deleted file mode 100755 index 46d62dd44d9..00000000000 Binary files a/scripts/vm/hypervisor/xenserver/vhd-util and /dev/null differ diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 2e14fad5b9c..2f0f347c783 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -177,21 +177,6 @@ def savePassword(session, args): return txt -@echo -def saveDhcpEntry(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/cloud/bin/dhcp_entry.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - logging.debug(" save dhcp entry failed " ) - txt = '' - - return txt - @echo def setLinkLocalIP(session, args): brName = args['brName'] @@ -237,23 +222,6 @@ def setLinkLocalIP(session, args): txt = 'success' return txt - - -@echo -def setFirewallRule(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/cloud/bin/call_firewall.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - logging.debug(" set firewall rule failed " ) - txt = '' - - return txt - @echo def routerProxy(session, args): sargs = args['args'] @@ -262,69 +230,10 @@ def routerProxy(session, args): cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) - if txt is None or len(txt) == 0 : - txt = 'success' + txt = 'succ#' + txt except: logging.debug("routerProxy command " + sargs + " failed " ) - txt = '' - - return txt - - - -@echo -def setLoadBalancerRule(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/cloud/bin/call_loadbalancer.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - logging.debug(" set loadbalancer rule failed " ) - txt = '' - - return txt -@echo -def configdnsmasq(session, args): - routerip = args['routerip'] - args = args['args'] - target = "root@"+routerip - try: - util.pread2(['ssh','-p','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',target,'/root/dnsmasq.sh',args]) - txt='success' - except: - logging.debug("failed to config dnsmasq server") - txt='' - return txt - -@echo -def createipAlias(session, args): - args = args['args'] - cmd = args.split(' ') - cmd.insert(0, "/opt/cloud/bin/createipAlias.sh") - cmd.insert(0, "bin/bash") - try: - txt=util.pread2(cmd) - txt='success' - except: - logging.debug("failed to create ip alias on router vm") - txt='' - return txt - -@echo -def deleteipAlias(session, args): - args = args['args'] - cmd = args.split(' ') - cmd.insert(0, "/opt/cloud/bin/deleteipAlias.sh") - cmd.insert(0, "bin/bash") - try: - txt=util.pread2(cmd) - txt='success' - except: - logging.debug("failed to create ip alias on router vm") - txt='' + txt = 'fail#' + txt return txt @echo @@ -354,13 +263,12 @@ def createFileInDomr(session, args): f.write(file_contents) f.close() target = "root@" + domrip + ":" + file_path - util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + txt = util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) util.pread2(['rm',tmpfile]) - txt = 'success' + txt = 'succ#' + txt except: - logging.debug(" failed to create HA proxy cfg file ") - txt = '' - + logging.debug("failed to create file " + file_path + " in VR, contain: " + file_contents) + txt = 'fail#' + txt return txt @echo @@ -1608,41 +1516,21 @@ def network_rules(session, args): except: logging.debug("Failed to network rule !") -@echo -def bumpUpPriority(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/cloud/bin/bumpUpPriority.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - logging.debug("bump up priority fail! ") - txt = '' - - return txt - - if __name__ == "__main__": XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, "getgateway": getgateway, "preparemigration": preparemigration, "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, "savePassword": savePassword, - "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, "routerProxy": routerProxy, - "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, + "routerProxy": routerProxy, + "createFile": createFile, "deleteFile": deleteFile, "network_rules":network_rules, "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, "destroy_network_rules_for_vm":destroy_network_rules_for_vm, "default_network_rules_systemvm":default_network_rules_systemvm, "network_rules_vmSecondaryIp":network_rules_vmSecondaryIp, - "createipAlias":createipAlias, - "configdnsmasq":configdnsmasq, - "deleteipAlias":deleteipAlias, "get_rule_logs_for_vms":get_rule_logs_for_vms, "add_to_VCPUs_params_live":add_to_VCPUs_params_live, "setLinkLocalIP":setLinkLocalIP, "cleanup_rules":cleanup_rules, - "bumpUpPriority":bumpUpPriority, "createFileInDomr":createFileInDomr, "kill_copy_process":kill_copy_process}) diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index a7c64b0984e..1d94de3d60b 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -700,7 +700,7 @@ def cleanup_rules(): logging.debug("vm " + vm_name + " is not running or paused, cleaning up iptable rules") cleanup.append(vm_name) - chainscmd = """ebtables-save | awk '/:i/ { gsub(/(^:|-(in|out))/, "") ; print $1}'""" + chainscmd = """ebtables-save | awk '/:i/ { gsub(/(^:|-(in|out|ips))/, "") ; print $1}'""" chains = execute(chainscmd).split('\n') for chain in chains: if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]: diff --git a/server/pom.xml b/server/pom.xml index 86e7b76a6c2..1646dc706df 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -189,7 +189,6 @@ maven-antrun-plugin - 1.7 generate-resource diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index d4ee85e4569..53a294e4e00 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -120,12 +120,8 @@
- - - - diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index 2e43da3b1da..31b273ff2d0 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -307,7 +307,9 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { } } //didn't find in upper tree - if (zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { + if (zoneDomainRecord != null && + accountDomainRecord != null && + zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { return true; } } diff --git a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java index b67eccbd2d7..946eee6da49 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java @@ -243,35 +243,36 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat // List vms = _vmInstanceDao.listByLastHostId(hostId); List vms = null; long usedCapacity = 0; - for (VMInstanceVO vm : vms) { - if (skipCalculation(vm)) { - continue; - } - - ServiceOffering so = null; - - if (vm.getType() == VirtualMachine.Type.User) { - UserVmVO userVm = _vmDao.findById(vm.getId()); - if (userVm == null) { + if (vms != null) { + for (VMInstanceVO vm : vms) { + if (skipCalculation(vm)) { continue; } - } - so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + ServiceOffering so = null; - if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { - usedCapacity += so.getRamSize() * 1024L * 1024L; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + - usedCapacity + " Bytes"); + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _vmDao.findById(vm.getId()); + if (userVm == null) { + continue; + } } - } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { - usedCapacity += so.getCpu() * so.getSpeed(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + - usedCapacity + " Bytes"); + so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { + usedCapacity += so.getRamSize() * 1024L * 1024L; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + + usedCapacity + " Bytes"); + } + } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { + usedCapacity += so.getCpu() * so.getSpeed(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + + usedCapacity + " Bytes"); + } } } } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 4414e3b18f0..a23244b86f0 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -738,14 +738,6 @@ public class ApiDBUtils { return s_vmDao.findById(vmId); } - public static long getMemoryOrCpuCapacitybyHost(Long hostId, short capacityType) { - // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) - // so if this Utils class can have some kind of config rather than a static initializer (maybe from - // management server instantiation?) then maybe the management server method can be moved entirely - // into this utils class. - return s_ms.getMemoryOrCpuCapacityByHost(hostId, capacityType); - } - public static long getStorageCapacitybyPool(Long poolId, short capacityType) { // TODO: This method is for the API only, but it has configuration values (ramSize for system vms) // so if this Utils class can have some kind of config rather than a static initializer (maybe from diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 9f4f766fc45..55ef53ae2b9 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -427,8 +427,8 @@ public class ApiDispatcher { } } else { DateFormat format = BaseCmd.INPUT_FORMAT; - format.setLenient(false); synchronized (format) { + format.setLenient(false); field.set(cmdObj, format.parse(paramObj.toString())); } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index c9e5581865f..a50b3eeffb2 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -384,8 +384,9 @@ public class ApiResponseHelper implements ResponseGenerator { populateDomain(resourceLimitResponse, accountTemp.getDomainId()); } resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); + if ((limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) && limit.getMax() >= 0) { - resourceLimitResponse.setMax((long)Math.ceil(limit.getMax() / ResourceType.bytesToGiB)); + resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB)); } else { resourceLimitResponse.setMax(limit.getMax()); } @@ -1804,8 +1805,6 @@ public class ApiResponseHelper implements ResponseGenerator { public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { SecurityGroupResponse response = new SecurityGroupResponse(); Map securiytGroupAccounts = new HashMap(); - Map allowedSecurityGroups = new HashMap(); - Map allowedSecuriytGroupAccounts = new HashMap(); if ((securityRules != null) && !securityRules.isEmpty()) { SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0); @@ -3008,11 +3007,10 @@ public class ApiResponseHelper implements ResponseGenerator { response.setCidr(result.getCidr()); StaticRoute.State state = result.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + if (state.equals(StaticRoute.State.Revoke)) { + state = StaticRoute.State.Deleting; } - response.setState(stateToSet); + response.setState(state.toString()); populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); @@ -3501,11 +3499,11 @@ public class ApiResponseHelper implements ResponseGenerator { ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse(); ruleResponse.setInstancePort(lb.getDefaultPortStart()); ruleResponse.setSourcePort(lb.getSourcePortStart()); - String stateToSet = lb.getState().toString(); + FirewallRule.State stateToSet = lb.getState(); if (stateToSet.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + stateToSet = FirewallRule.State.Deleting; } - ruleResponse.setState(stateToSet); + ruleResponse.setState(stateToSet.toString()); ruleResponse.setObjectName("loadbalancerrule"); ruleResponses.add(ruleResponse); lbResponse.setLbRules(ruleResponses); diff --git a/server/src/com/cloud/api/ApiSerializerHelper.java b/server/src/com/cloud/api/ApiSerializerHelper.java index cd5c7e65fdc..7426d9f1675 100644 --- a/server/src/com/cloud/api/ApiSerializerHelper.java +++ b/server/src/com/cloud/api/ApiSerializerHelper.java @@ -24,7 +24,7 @@ import org.apache.cloudstack.api.ResponseObject; public class ApiSerializerHelper { public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName()); - public static String token = "/"; + private static String token = "/"; public static String toSerializedString(Object result) { if (result != null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 3fb3495f7ae..d715db65c67 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -159,11 +159,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); - public static boolean encodeApiResponse = false; - public static String jsonContentType = "text/javascript"; - public static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal - @Inject - ApiDispatcher _dispatcher; + private static boolean encodeApiResponse = false; + private static String jsonContentType = "text/javascript"; + private static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal + @Inject ApiDispatcher _dispatcher; @Inject private AccountManager _accountMgr; @@ -241,7 +240,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer s_apiNameCmdClassMap.put(apiName, cmdClass); } - encodeApiResponse = Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key())); + setEncodeApiResponse(Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key()))); String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; @@ -379,7 +378,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer buildAuditTrail(auditTrailSb, command[0], response); } else { if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { - String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]); + String errorString = "Unknown API command: " + command[0]; s_logger.warn(errorString); auditTrailSb.append(" " + errorString); throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString); @@ -722,10 +721,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer try { checkCommandAvailable(user, commandName); + } catch (RequestLimitException ex) { + s_logger.debug(ex.getMessage()); + throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage()); } catch (PermissionDeniedException ex) { s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user"); - throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + - " does not exist or it is not available for user with id:" + userId); + throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist or it is not available for user with id:" + + userId); } // verify secret key exists @@ -1099,7 +1101,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer @Inject public void setPluggableServices(List pluggableServices) { - this._pluggableServices = pluggableServices; + _pluggableServices = pluggableServices; } public List getApiAccessCheckers() { @@ -1108,6 +1110,18 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer @Inject public void setApiAccessCheckers(List apiAccessCheckers) { - this._apiAccessCheckers = apiAccessCheckers; + _apiAccessCheckers = apiAccessCheckers; + } + + public static boolean isEncodeApiResponse() { + return encodeApiResponse; + } + + private static void setEncodeApiResponse(boolean encodeApiResponse) { + ApiServer.encodeApiResponse = encodeApiResponse; + } + + public static String getJsonContentType() { + return jsonContentType; } } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6a33c14baaf..46f7eba8bee 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -375,7 +375,7 @@ public class ApiServlet extends HttpServlet { private void writeResponse(HttpServletResponse resp, String response, int responseCode, String responseType) { try { if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - resp.setContentType(ApiServer.jsonContentType + "; charset=UTF-8"); + resp.setContentType(ApiServer.getJsonContentType() + "; charset=UTF-8"); } else { resp.setContentType("text/xml; charset=UTF-8"); } diff --git a/server/src/com/cloud/api/EncodedStringTypeAdapter.java b/server/src/com/cloud/api/EncodedStringTypeAdapter.java index cde144830aa..50dbd0d48cd 100644 --- a/server/src/com/cloud/api/EncodedStringTypeAdapter.java +++ b/server/src/com/cloud/api/EncodedStringTypeAdapter.java @@ -37,7 +37,7 @@ public class EncodedStringTypeAdapter implements JsonSerializer { } private static String encodeString(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { diff --git a/server/src/com/cloud/api/doc/Alert.java b/server/src/com/cloud/api/doc/Alert.java index e73cb0e5351..3e61d0ba268 100644 --- a/server/src/com/cloud/api/doc/Alert.java +++ b/server/src/com/cloud/api/doc/Alert.java @@ -16,9 +16,15 @@ // under the License. package com.cloud.api.doc; -public class Alert { - private String type; - private int value; +import java.io.Serializable; + +public class Alert implements Serializable{ + /** + * + */ + private static final long serialVersionUID = 960408026527837920L; + private final String type; + private final int value; public Alert(String type, int value) { this.type = type; diff --git a/server/src/com/cloud/api/doc/Command.java b/server/src/com/cloud/api/doc/Command.java index 998b39fefab..549ca291ffe 100644 --- a/server/src/com/cloud/api/doc/Command.java +++ b/server/src/com/cloud/api/doc/Command.java @@ -16,10 +16,15 @@ // under the License. package com.cloud.api.doc; +import java.io.Serializable; import java.util.ArrayList; -public class Command { +public class Command implements Serializable{ + /** + * + */ + private static final long serialVersionUID = -4318310162503004975L; private String name; private String description; private String usage; @@ -85,7 +90,7 @@ public class Command { } public Argument getReqArgByName(String name) { - for (Argument a : this.getRequest()) { + for (Argument a : getRequest()) { if (a.getName().equals(name)) { return a; } @@ -94,7 +99,7 @@ public class Command { } public Argument getResArgByName(String name) { - for (Argument a : this.getResponse()) { + for (Argument a : getResponse()) { if (a.getName().equals(name)) { return a; } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 5a953dea25b..149b0d906f0 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -19,6 +19,7 @@ package com.cloud.api.query; import java.util.ArrayList; import java.util.EnumSet; import java.util.Hashtable; +import java.util.LinkedHashMap; import java.util.List; import org.apache.log4j.Logger; @@ -360,7 +361,7 @@ public class ViewResponseHelper { } public static List createTemplateResponse(TemplateJoinVO... templates) { - Hashtable vrDataList = new Hashtable(); + LinkedHashMap vrDataList = new LinkedHashMap(); for (TemplateJoinVO vr : templates) { TemplateResponse vrData = vrDataList.get(vr.getTempZonePair()); if (vrData == null) { diff --git a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java index 90c155fc773..bcf8d4cd440 100644 --- a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java @@ -25,12 +25,15 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.response.ImageStoreDetailResponse; import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.storage.ImageStore; +import com.cloud.utils.StringUtils; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -57,7 +60,7 @@ public class ImageStoreJoinDaoImpl extends GenericDaoBase 0) { - ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, ids.getDetailValue()); + if ( detailName != null && detailName.length() > 0 ){ + String detailValue = ids.getDetailValue(); + if (detailName.equals(ApiConstants.KEY) || detailName.equals(ApiConstants.S3_SECRET_KEY)) { + detailValue = DBEncryptionUtil.decrypt(detailValue); + } + ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, detailValue); osResponse.addDetail(osdResponse); } osResponse.setObjectName("imagestore"); @@ -84,8 +96,12 @@ public class ImageStoreJoinDaoImpl extends GenericDaoBase 0) { - ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, ids.getDetailValue()); + if ( detailName != null && detailName.length() > 0 ){ + String detailValue = ids.getDetailValue(); + if (detailName.equals(ApiConstants.KEY) || detailName.equals(ApiConstants.S3_SECRET_KEY)) { + detailValue = DBEncryptionUtil.decrypt(detailValue); + } + ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, detailValue); response.addDetail(osdResponse); } return response; diff --git a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java index 0a5fb5eb66e..274bf1c24b8 100644 --- a/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java @@ -34,6 +34,7 @@ import com.cloud.capacity.Capacity; import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePool; import com.cloud.storage.StorageStats; +import com.cloud.utils.StringUtils; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -60,7 +61,7 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase im activeTmpltSearch.done(); // select distinct pair (template_id, zone_id) - this._count = "select count(distinct temp_zone_pair) from template_view WHERE "; + _count = "select count(distinct temp_zone_pair) from template_view WHERE "; } private String getTemplateStatus(TemplateJoinVO template) { @@ -383,6 +384,9 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg); } // query details by batches + Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); + isAscending = (isAscending == null ? true : isAscending); + Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, null, null); List uvList = new ArrayList(); // query details by batches int curr_index = 0; @@ -397,7 +401,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im sc.setParameters("templateState", VirtualMachineTemplate.State.Active); } sc.setParameters("tempZonePairIN", labels); - List vms = searchIncludingRemoved(sc, null, null, false); + List vms = searchIncludingRemoved(sc, searchFilter, null, false); if (vms != null) { uvList.addAll(vms); } @@ -415,7 +419,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im sc.setParameters("templateState", VirtualMachineTemplate.State.Active); } sc.setParameters("tempZonePairIN", labels); - List vms = searchIncludingRemoved(sc, null, null, false); + List vms = searchIncludingRemoved(sc, searchFilter, null, false); if (vms != null) { uvList.addAll(vms); } diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 07449a23e3d..08478e2958b 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -99,7 +99,11 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem userVmResponse.setId(userVm.getUuid()); userVmResponse.setName(userVm.getName()); - userVmResponse.setDisplayName(userVm.getDisplayName()); + if (userVm.getDisplayName() != null) { + userVmResponse.setDisplayName(userVm.getDisplayName()); + } else { + userVmResponse.setDisplayName(userVm.getName()); + } if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { userVmResponse.setProjectId(userVm.getProjectUuid()); diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 472a8cba2af..9e4fc21caeb 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -34,8 +34,8 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; -import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -48,10 +48,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private long id; @Column(name = "name", updatable = false, nullable = false, length = 255) - private String name = null; + private final String name = null; @Column(name = "display_name", updatable = false, nullable = false, length = 255) - private String displayName = null; + private final String displayName = null; @Column(name = "account_id") private long accountId; @@ -60,7 +60,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String accountUuid; @Column(name = "account_name") - private String accountName = null; + private final String accountName = null; @Column(name = "account_type") private short accountType; @@ -72,10 +72,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String domainUuid; @Column(name = "domain_name") - private String domainName = null; + private final String domainName = null; @Column(name = "domain_path") - private String domainPath = null; + private final String domainPath = null; @Column(name = "instance_group_id") private long instanceGroupId; @@ -97,7 +97,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { */ @Enumerated(value = EnumType.STRING) @Column(name = "state", updatable = true, nullable = false, length = 32) - private State state = null; + private final State state = null; @Column(name = GenericDao.CREATED_COLUMN) private Date created; @@ -121,10 +121,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "ha_enabled", updatable = true, nullable = true) private boolean haEnabled; - @Encrypt - @Column(name = "vnc_password", updatable = true, nullable = false, length = 255) - protected String vncPassword; - @Column(name = "limit_cpu_use", updatable = true, nullable = true) private boolean limitCpuUse; @@ -153,7 +149,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String dataCenterUuid; @Column(name = "data_center_name") - private String dataCenterName = null; + private final String dataCenterName = null; @Column(name = "security_group_enabled") private boolean securityGroupEnabled; @@ -238,7 +234,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String volumeUuid; @Column(name = "volume_device_id") - private Long volumeDeviceId = null; + private final Long volumeDeviceId = null; @Column(name = "volume_type") @Enumerated(EnumType.STRING) @@ -537,10 +533,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { return haEnabled; } - public String getVncPassword() { - return vncPassword; - } - public String getPrivateIpAddress() { return privateIpAddress; } @@ -754,9 +746,11 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { } public String getDetail(String name) { - assert (details != null) : "Did you forget to load the details?"; + if (details == null) { + throw new CloudRuntimeException("No details to get. Did you forget to load the details?"); + } - return details != null ? details.get(name) : null; + return details.get(name); } public String getUserData() { diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index d8b728a9f3a..f276e89d5e1 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -291,7 +291,7 @@ public class ApiResponseSerializer { } private static String encodeParam(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 0c581415f07..6ba67749aef 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -402,6 +402,10 @@ public enum Config { "10", "The maximum number of subnets per customer gateway", null), + MaxNumberOfSecondaryIPsPerNIC( + "Network", ManagementServer.class, Integer.class, + "vm.network.nic.max.secondary.ipaddresses", "256", + "Specify the number of secondary ip addresses per nic per vm", null), // Console Proxy ConsoleProxyCapacityStandby( @@ -1372,9 +1376,6 @@ public enum Config { "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.", null), //NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"), - HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null), - EncryptionKey("Hidden", ManagementServer.class, String.class, "security.encryption.key", null, "base64 encoded key data", null), - EncryptionIV("Hidden", ManagementServer.class, String.class, "security.encryption.iv", null, "base64 encoded IV data", null), RouterRamSize("Hidden", NetworkOrchestrationService.class, Integer.class, "router.ram.size", "128", "Default RAM for router VM (in MB).", null), DefaultPageSize("Advanced", ManagementServer.class, Long.class, "default.page.size", "500", "Default page size for API list* commands", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 9d148faa6db..20037167487 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -36,6 +36,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -83,7 +85,6 @@ import org.apache.cloudstack.region.dao.RegionDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.log4j.Logger; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; @@ -1689,7 +1690,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage); } catch (InvalidParameterValueException noStorage) { PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management); - _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), mgmtTraffic.getXenNetworkLabel(), + _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(), mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(), mgmtTraffic.getHypervNetworkLabel()); s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId() @@ -2640,8 +2641,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } return NetUtils.supersetOrSubset.neitherSubetNorSuperset; - } else if (newVlanGateway == null || newVlanGateway == null) { - throw new InvalidParameterValueException("either both netmask and gateway should be passed or both should me omited."); + } else if (newVlanGateway == null || newVlanNetmask == null) { + throw new InvalidParameterValueException( + "either both netmask and gateway should be passed or both should me omited."); } else { if (!NetUtils.sameSubnet(startIP, newVlanGateway, newVlanNetmask)) { throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet"); diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 20366095048..3a1c387c344 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -25,6 +25,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import com.cloud.agent.AgentManager; @@ -53,7 +54,6 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol protected HostDao _hostDao; @Inject protected UserVmDao _userVmDao; - private String _instance; protected String _consoleProxyUrlDomain; @Inject private VMInstanceDao _instanceDao; @@ -74,11 +74,13 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol ConfigurationDao _configDao; @Inject ManagementServer _ms; + @Inject + KeysManager _keysMgr; public class AgentBasedAgentHook extends AgentHookBase { - public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, ms); + public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr); } @Override @@ -119,11 +121,9 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol _sslEnabled = true; } - _instance = configs.get("instance.name"); - _consoleProxyUrlDomain = configs.get("consoleproxy.url.domain"); - _listener = new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _ms)); + _listener = new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr)); _agentMgr.registerForHostEvents(_listener, true, true, false); if (s_logger.isInfoEnabled()) { diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java index 57fa43a6aaf..2e0bada3abb 100644 --- a/server/src/com/cloud/consoleproxy/AgentHookBase.java +++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java @@ -26,6 +26,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import com.cloud.agent.AgentManager; @@ -45,10 +46,10 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; -import com.cloud.server.ManagementServer; import com.cloud.servlet.ConsoleProxyPasswordBasedEncryptor; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.utils.Ternary; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @@ -65,17 +66,16 @@ public abstract class AgentHookBase implements AgentHook { ConfigurationDao _configDao; AgentManager _agentMgr; KeystoreManager _ksMgr; - ManagementServer _ms; final Random _random = new Random(System.currentTimeMillis()); - private String _hashKey; + KeysManager _keysMgr; - public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - this._instanceDao = instanceDao; - this._hostDao = hostDao; - this._agentMgr = agentMgr; - this._configDao = cfgDao; - this._ksMgr = ksMgr; - this._ms = ms; + public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + _instanceDao = instanceDao; + _hostDao = hostDao; + _agentMgr = agentMgr; + _configDao = cfgDao; + _ksMgr = ksMgr; + _keysMgr = keysMgr; } @Override @@ -193,7 +193,9 @@ public abstract class AgentHookBase implements AgentHook { assert (ksBits != null); if (ksBits == null) { - s_logger.error("Could not find and construct a valid SSL certificate"); + String msg = "Could not find and construct a valid SSL certificate"; + s_logger.error(msg); + throw new CloudRuntimeException(msg); } cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword); cmd.setEncryptorPassword(getEncryptorPassword()); @@ -230,15 +232,15 @@ public abstract class AgentHookBase implements AgentHook { // if we failed after reset, something is definitely wrong for (int i = 0; i < 2; i++) { - key = _ms.getEncryptionKey(); - iv = _ms.getEncryptionIV(); + key = _keysMgr.getEncryptionKey(); + iv = _keysMgr.getEncryptionIV(); keyIvPair = new ConsoleProxyPasswordBasedEncryptor.KeyIVPair(key, iv); if (keyIvPair.getIvBytes() == null || keyIvPair.getIvBytes().length != 16 || keyIvPair.getKeyBytes() == null || keyIvPair.getKeyBytes().length != 16) { s_logger.warn("Console access AES KeyIV sanity check failed, reset and regenerate"); - _ms.resetEncryptionKeyIV(); + _keysMgr.resetEncryptionKeyIV(); } else { break; } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 466ebc28beb..813888707a3 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.consoleproxy; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -28,14 +29,11 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.security.keys.KeysManager; import org.apache.cloudstack.framework.security.keystore.KeystoreDao; import org.apache.cloudstack.framework.security.keystore.KeystoreManager; import org.apache.cloudstack.framework.security.keystore.KeystoreVO; @@ -43,6 +41,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -54,7 +53,6 @@ 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.manager.Commands; -import com.cloud.certificate.dao.CertificateDao; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.ZoneConfig; @@ -99,16 +97,13 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolStatus; 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.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.DateUtil; @@ -141,6 +136,8 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; // // Possible console proxy state transition cases @@ -182,57 +179,44 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject private ConfigurationDao _configDao; @Inject - private CertificateDao _certDao; - @Inject private VMInstanceDao _instanceDao; @Inject private TemplateDataStoreDao _vmTemplateStoreDao; @Inject private AgentManager _agentMgr; @Inject - private StorageManager _storageMgr; + private NetworkOrchestrationService _networkMgr; @Inject - NetworkOrchestrationService _networkMgr; + private NetworkModel _networkModel; @Inject - NetworkModel _networkModel; + private AccountManager _accountMgr; @Inject - AccountManager _accountMgr; + private ServiceOfferingDao _offeringDao; @Inject - ServiceOfferingDao _offeringDao; + private DiskOfferingDao _diskOfferingDao; @Inject - DiskOfferingDao _diskOfferingDao; + private NetworkOfferingDao _networkOfferingDao; @Inject - NetworkOfferingDao _networkOfferingDao; + private PrimaryDataStoreDao _storagePoolDao; @Inject - PrimaryDataStoreDao _storagePoolDao; + private UserVmDetailsDao _vmDetailsDao; @Inject - UserVmDetailsDao _vmDetailsDao; + private ResourceManager _resourceMgr; @Inject - ResourceManager _resourceMgr; + private NetworkDao _networkDao; @Inject - NetworkDao _networkDao; + private RulesManager _rulesMgr; @Inject - RulesManager _rulesMgr; + private IPAddressDao _ipAddressDao; @Inject - TemplateManager templateMgr; + private KeysManager _keysMgr; @Inject - IPAddressDao _ipAddressDao; - @Inject - ManagementServer _ms; - @Inject - ClusterManager _clusterMgr; + private VirtualMachineManager _itMgr; private ConsoleProxyListener _listener; private ServiceOfferingVO _serviceOffering; - NetworkOffering _publicNetworkOffering; - NetworkOffering _managementNetworkOffering; - NetworkOffering _linkLocalNetworkOffering; - - @Inject - private VirtualMachineManager _itMgr; - /* * private final ExecutorService _requestHandlerScheduler = Executors.newCachedThreadPool(new * NamedThreadFactory("Request-handler")); @@ -267,8 +251,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy public class VmBasedAgentHook extends AgentHookBase { - public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, ManagementServer ms) { - super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, ms); + public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr, AgentManager agentMgr, KeysManager keysMgr) { + super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr, keysMgr); } @Override @@ -500,7 +484,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy byte[] details = proxy.getSessionDetails(); status = gson.fromJson(details != null ? new String(details, Charset.forName("US-ASCII")) : null, ConsoleProxyStatus.class); } catch (Throwable e) { - s_logger.warn("Unable to parse proxy session details : " + proxy.getSessionDetails()); + s_logger.warn("Unable to parse proxy session details : " + Arrays.toString(proxy.getSessionDetails())); } if (status != null && status.getConnections() != null) { @@ -884,14 +868,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy return l.size() < launchLimit; } - private HypervisorType currentHypervisorType(long dcId) { - List l = - _consoleProxyDao.getProxyListInStates(dcId, VirtualMachine.State.Starting, VirtualMachine.State.Running, VirtualMachine.State.Stopping, - VirtualMachine.State.Stopped, VirtualMachine.State.Migrating, VirtualMachine.State.Shutdowned, VirtualMachine.State.Unknown); - - return l.size() > 0 ? l.get(0).getHypervisorType() : HypervisorType.Any; - } - private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo) { if (proxyCountInfo.getCount() * _capacityPerProxy - vmCountInfo.getCount() <= _standbyCapacity) { @@ -969,11 +945,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy } } else { if (s_logger.isDebugEnabled()) { - if (template == null) { - s_logger.debug("Zone host is ready, but console proxy template is null"); - } else { - s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); - } + s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); } } } @@ -1262,7 +1234,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy value = agentMgrConfigs.get("port"); _mgmtPort = NumbersUtil.parseInt(value, 8250); - _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _ms)); + _listener = new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr, _keysMgr)); _agentMgr.registerForHostEvents(_listener, true, true, false); _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this); @@ -1327,7 +1299,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy StringBuilder buf = profile.getBootArgsBuilder(); buf.append(" template=domP type=consoleproxy"); - buf.append(" host=").append(ClusterManager.ManagementHostIPAdr.value()); + buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value()); buf.append(" port=").append(_mgmtPort); buf.append(" name=").append(profile.getVirtualMachine().getHostName()); if (_sslEnabled) { @@ -1677,13 +1649,11 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Override public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { - // TODO Auto-generated method stub return null; } @Override public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - // TODO Auto-generated method stub return null; } @@ -1704,7 +1674,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject public void setConsoleProxyAllocators(List consoleProxyAllocators) { - this._consoleProxyAllocators = consoleProxyAllocators; + _consoleProxyAllocators = consoleProxyAllocators; } } diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/com/cloud/dc/DedicatedResourceVO.java index 9948f504158..e7d7b3b282c 100644 --- a/server/src/com/cloud/dc/DedicatedResourceVO.java +++ b/server/src/com/cloud/dc/DedicatedResourceVO.java @@ -29,6 +29,11 @@ import javax.persistence.Table; @Table(name = "dedicated_resources") public class DedicatedResourceVO implements DedicatedResources { + /** + * + */ + private static final long serialVersionUID = -6659510127145101917L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -59,7 +64,7 @@ public class DedicatedResourceVO implements DedicatedResources { private long affinityGroupId; public DedicatedResourceVO() { - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); } public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId, Long accountId, long affinityGroupId) { @@ -69,7 +74,7 @@ public class DedicatedResourceVO implements DedicatedResources { this.hostId = hostId; this.domainId = domainId; this.accountId = accountId; - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); this.affinityGroupId = affinityGroupId; } @@ -115,7 +120,7 @@ public class DedicatedResourceVO implements DedicatedResources { } public DedicatedResourceVO(long dedicatedResourceId) { - this.id = dedicatedResourceId; + id = dedicatedResourceId; } @Override @@ -138,7 +143,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public String getUuid() { - return this.uuid; + return uuid; } public void setUuid(String uuid) { @@ -153,7 +158,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public boolean equals(Object obj) { if (obj instanceof DedicatedResourceVO) { - return ((DedicatedResourceVO)obj).getId() == this.getId(); + return ((DedicatedResourceVO)obj).getId() == getId(); } else { return false; } diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 8cad796d966..35a0b39acb2 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.deploy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -91,6 +92,7 @@ import com.cloud.org.Grouping; import com.cloud.resource.ResourceState; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -163,7 +165,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setStoragePoolAllocators(List storagePoolAllocators) { - this._storagePoolAllocators = storagePoolAllocators; + _storagePoolAllocators = storagePoolAllocators; } protected List _hostAllocators; @@ -173,7 +175,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setHostAllocators(List hostAllocators) { - this._hostAllocators = hostAllocators; + _hostAllocators = hostAllocators; } @Inject @@ -219,7 +221,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setPlanners(List planners) { - this._planners = planners; + _planners = planners; } protected List _affinityProcessors; @@ -229,7 +231,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setAffinityGroupProcessors(List affinityProcessors) { - this._affinityProcessors = affinityProcessors; + _affinityProcessors = affinityProcessors; } @Override @@ -1140,9 +1142,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy List suitablePools = new ArrayList(); StoragePool pool = null; if (toBeCreated.getPoolId() != null) { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); } else { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); } if (!pool.isInMaintenance()) { @@ -1154,7 +1156,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) { canReusePool = true; } else if (plan.getDataCenterId() == exstPoolDcId) { - DataStore dataStore = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId()); if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) { canReusePool = true; } @@ -1202,8 +1204,12 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy s_logger.debug("Calling StoragePoolAllocators to find suitable pools"); DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) { + diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray())); + } + + DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); boolean useLocalStorage = false; if (vmProfile.getType() != VirtualMachine.Type.User) { String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); @@ -1253,9 +1259,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } } - if (suitableVolumeStoragePools.values() != null) { - poolsToAvoidOutput.removeAll(suitableVolumeStoragePools.values()); + HashSet toRemove = new HashSet(); + for (List lsp : suitableVolumeStoragePools.values()) { + for (StoragePool sp : lsp) { + toRemove.add(sp.getId()); + } } + poolsToAvoidOutput.removeAll(toRemove); + if (avoid.getPoolsToAvoid() != null) { avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput); } diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 0363a0d81dd..d435381b69b 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -25,6 +25,7 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.vm.VirtualMachine; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -181,7 +182,7 @@ public class ActionEventUtils { } org.apache.cloudstack.framework.events.Event event = - new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), null); + new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), entityUuid); Map eventDescription = new HashMap(); Account account = s_accountDao.findById(accountId); @@ -233,6 +234,8 @@ public class ActionEventUtils { else if (eventType.startsWith("USER.")) { return User.class; + }else if (eventType.startsWith("VM.")){ + return VirtualMachine.class; } return null; diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index da1bb88bbba..770099c65fd 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -28,8 +28,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -41,7 +39,6 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.configuration.Config; import com.cloud.dc.ClusterVO; -import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.DiscoveredWithErrorException; import com.cloud.exception.DiscoveryException; @@ -49,10 +46,8 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; -import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; @@ -70,17 +65,9 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements private String _kvmPublicNic; private String _kvmGuestNic; @Inject - HostDao _hostDao = null; - @Inject - ClusterDao _clusterDao; - @Inject ResourceManager _resourceMgr; @Inject AgentManager _agentMgr; - @Inject - ConfigurationDao _configDao; - @Inject - NetworkModel _networkMgr; @Override public abstract Hypervisor.HypervisorType getHypervisorType(); diff --git a/server/src/com/cloud/network/ExternalIpAddressAllocator.java b/server/src/com/cloud/network/ExternalIpAddressAllocator.java index 2b84231c050..3cf358067ee 100644 --- a/server/src/com/cloud/network/ExternalIpAddressAllocator.java +++ b/server/src/com/cloud/network/ExternalIpAddressAllocator.java @@ -40,7 +40,6 @@ import com.cloud.utils.exception.CloudRuntimeException; @Local(value = IpAddrAllocator.class) public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAllocator { private static final Logger s_logger = Logger.getLogger(ExternalIpAddressAllocator.class); - String _name; @Inject ConfigurationDao _configDao = null; @Inject @@ -52,10 +51,10 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public IpAddr getPrivateIpAddress(String macAddr, long dcId, long podId) { - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return new IpAddr(); } - String urlString = this._externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("getIP:" + urlString); BufferedReader in = null; @@ -101,11 +100,11 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public boolean releasePrivateIpAddress(String ip, long dcId, long podId) { /*TODO: call API to release the ip address from external DHCP server*/ - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return false; } - String urlString = this._externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("releaseIP:" + urlString); BufferedReader in = null; diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 6596074ad34..09f73a4d17a 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.network; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -28,6 +29,8 @@ import java.util.UUID; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; @@ -39,7 +42,6 @@ import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIpDao; import org.apache.cloudstack.region.PortableIpVO; import org.apache.cloudstack.region.Region; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -570,8 +572,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage IPAddressVO ip = markIpAsUnavailable(addrId); - assert (ip != null) : "Unable to mark the ip address id=" + addrId + " as unavailable."; if (ip == null) { + String msg = "Unable to mark the ip address id=" + addrId + " as unavailable."; + s_logger.error(msg); return true; } @@ -684,10 +687,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = true; sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray())); } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); } else { if (podId != null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); @@ -727,7 +730,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); addrs = _ipAddressDao.lockRows(sc, filter, true); } } @@ -852,6 +855,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException, InsufficientAddressCapacityException { + if (owner == null) { + s_logger.error("No account to assign an ip to."); + return null; + } + final long ownerId = owner.getId(); PublicIp ip = null; @@ -883,13 +891,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { - if (owner != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Releasing lock account " + ownerId); - } - - _accountDao.releaseFromLockTable(ownerId); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock account " + ownerId); } + _accountDao.releaseFromLockTable(ownerId); + if (ip == null) { s_logger.error("Unable to get source nat ip address for account " + ownerId); } @@ -1218,7 +1224,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage s_logger.debug("Associating ip " + ipToAssoc + " to network " + network); - IPAddressVO ip = _ipAddressDao.findById(ipId); + IPAddressVO ip = ipToAssoc; //_ipAddressDao.findById(ipId); //update ip address with networkId ip.setAssociatedWithNetworkId(networkId); ip.setSourceNat(isSourceNat); @@ -1235,18 +1241,16 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { if (!success && releaseOnFailure) { - if (ip != null) { - try { - s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip); - _ipAddressDao.markAsUnavailable(ip.getId()); - if (!applyIpAssociations(network, true)) { - // if fail to apply ip assciations again, unassign ip address without updating resource - // count and generating usage event as there is no need to keep it in the db - _ipAddressDao.unassignIpAddress(ip.getId()); - } - } catch (Exception e) { - s_logger.warn("Unable to disassociate ip address for recovery", e); + try { + s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip); + _ipAddressDao.markAsUnavailable(ip.getId()); + if (!applyIpAssociations(network, true)) { + // if fail to apply ip assciations again, unassign ip address without updating resource + // count and generating usage event as there is no need to keep it in the db + _ipAddressDao.unassignIpAddress(ip.getId()); } + } catch (Exception e) { + s_logger.warn("Unable to disassociate ip address for recovery", e); } } } @@ -1327,7 +1331,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipToAssoc, _vlanDao.findById(ipToAssoc.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set services = ipToServices.get(publicIp); if (services != null && !services.isEmpty()) { throw new InvalidParameterValueException("IP " + ipToAssoc + " has services and rules associated in the network " + networkId); @@ -1368,7 +1372,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set ipServices = ipToServices.get(publicIp); if (ipServices != null && !ipServices.isEmpty()) { return false; @@ -1671,14 +1675,14 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public boolean applyStaticNats(List staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException { - Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); - boolean success = true; - if (staticNats == null || staticNats.size() == 0) { s_logger.debug("There are no static nat rules for the network elements"); return true; } + Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); + boolean success = true; + // get the list of public ip's owned by the network List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); List publicIps = new ArrayList(); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index 52a08e1480e..68807d38939 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -1017,14 +1017,14 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { List map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId); for (NetworkOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Network.Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; @@ -1533,6 +1533,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Override public void checkNetworkPermissions(Account owner, Network network) { + if (network == null) { + throw new CloudRuntimeException("no network to check permissions for."); + } // Perform account permission check if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) { AccountVO networkOwner = _accountDao.findById(network.getAccountId()); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 056190f1c4a..d02f1760e1d 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -669,6 +669,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid network id is given"); } + int maxAllowedIpsPerNic = NumbersUtil.parseInt(_configDao.getValue(Config.MaxNumberOfSecondaryIPsPerNIC.key()), 10); + Long nicWiseIpCount = _nicSecondaryIpDao.countByNicId(nicId); + if(nicWiseIpCount.intValue() >= maxAllowedIpsPerNic) { + s_logger.error("Maximum Number of Ips \"vm.network.nic.max.secondary.ipaddresses = \"" + maxAllowedIpsPerNic + " per Nic has been crossed for the nic " + nicId + "."); + throw new InsufficientAddressCapacityException("Maximum Number of Ips per Nic has been crossed.", Nic.class, nicId); + } + + s_logger.debug("Calling the ip allocation ..."); String ipaddr = null; //Isolated network can exist in Basic zone only, so no need to verify the zone type @@ -3526,7 +3534,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true) - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // verify input parameters @@ -3582,6 +3590,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { vlan, hypervLabel); pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType); + // For public traffic, get isolation method of physical network and update the public network accordingly + // each broadcast type will individually need to be qualified for support of public traffic + List isolationMethods = network.getIsolationMethods(); + if ((isolationMethods.size() == 1 && isolationMethods.get(0).toLowerCase().equals("vxlan")) + || (isolationMethod != null && isolationMethods.contains(isolationMethod) && isolationMethod.toLowerCase().equals("vxlan"))) { + // find row in networks table that is defined as 'Public', created when zone was deployed + NetworkVO publicNetwork = _networksDao.listByZoneAndTrafficType(network.getDataCenterId(),TrafficType.Public).get(0); + if (publicNetwork != null) { + s_logger.debug("setting public network " + publicNetwork + " to broadcast type vxlan"); + publicNetwork.setBroadcastDomainType(BroadcastDomainType.Vxlan); + _networksDao.persist(publicNetwork); + } + } + return pNetworktrafficType; } catch (Exception ex) { s_logger.warn("Exception: ", ex); diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java index a6e21801586..13ff385da90 100755 --- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ControlNetworkGuru.java @@ -224,12 +224,12 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu Map dbParams = _configDao.getConfiguration(params); - _cidr = dbParams.get(Config.ControlCidr); + _cidr = dbParams.get(Config.ControlCidr.toString()); if (_cidr == null) { _cidr = "169.254.0.0/16"; } - _gateway = dbParams.get(Config.ControlGateway); + _gateway = dbParams.get(Config.ControlGateway.toString()); if (_gateway == null) { _gateway = NetUtils.getLinkLocalGateway(); } diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index 34e97d34423..95d7790f2cb 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -103,7 +103,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { if (offering.getTrafficType() == TrafficType.Public) { NetworkVO ntwk = - new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Vlan, offering.getId(), State.Setup, plan.getDataCenterId(), + new NetworkVO(offering.getTrafficType(), Mode.Static, network.getBroadcastDomainType(), offering.getId(), State.Setup, plan.getDataCenterId(), plan.getPhysicalNetworkId()); return ntwk; } else { @@ -122,9 +122,15 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { nic.setIp4Address(ip.getAddress().toString()); nic.setGateway(ip.getGateway()); nic.setNetmask(ip.getNetmask()); - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); + if (network.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + nic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vxlan); + } else { + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + } nic.setFormat(AddressFormat.Ip4); nic.setReservationId(String.valueOf(ip.getVlanTag())); nic.setMacAddress(ip.getMacAddress()); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 82332b731b2..bf2516a24a9 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -42,11 +42,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigDepot; @@ -57,6 +56,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; @@ -107,7 +107,6 @@ import com.cloud.alert.AlertManager; import com.cloud.api.ApiAsyncJobDispatcher; import com.cloud.api.ApiDispatcher; import com.cloud.api.ApiGsonHelper; -import com.cloud.cluster.ClusterManager; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.cluster.dao.ManagementServerHostDao; import com.cloud.configuration.Config; @@ -1835,9 +1834,17 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V defaultNic.setGateway(sourceNatIp.getGateway()); defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + // get broadcast from public network + Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId()); + if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + } else { + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + } if (hasGuestNetwork) { defaultNic.setDeviceId(2); } @@ -2050,7 +2057,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V // DOMR control command is sent over management server in VMware if (dest.getHost().getHypervisorType() == HypervisorType.VMware || dest.getHost().getHypervisorType() == HypervisorType.Hyperv) { s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + dest.getPod().getCidrAddress() + "/" + - dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + ClusterManager.ManagementHostIPAdr.value()); + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + ApiServiceConfiguration.ManagementHostIPAdr.value()); if (s_logger.isInfoEnabled()) { s_logger.info("Add management server explicit route to DomR."); @@ -2118,7 +2125,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V buf.append(" dnssearchorder=").append(domain_suffix); } - if (profile.getHypervisorType() == HypervisorType.VMware) { + if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) { buf.append(" extra_pubnics=" + _routerExtraPublicNics); } diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index cd684407c2e..d5f9405bf59 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -40,6 +40,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd; import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd; @@ -51,8 +54,6 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; @@ -373,7 +374,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro protected String generateRulesetSignature(Map> ingress, Map> egress) { String ruleset = ingress.toString(); - ruleset.concat(egress.toString()); + ruleset = ruleset.concat(egress.toString()); return DigestUtils.md5Hex(ruleset); } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 2face90a7a4..51e476f4ee6 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -424,14 +424,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis List map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId); for (VpcOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 5e7d9a96617..5a0ed1cf64c 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -624,6 +624,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { domainUuid = domain.getUuid(); } ex.addProxyObject(domainUuid, "domainId"); + throw ex; } //verify permissions diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 3a7251b2095..13c3051d861 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -877,7 +877,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue()); - if (oldCount != newCount) { + if (!Long.valueOf(oldCount).equals(newCount)) { s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation."); } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index b46708d4633..cbf3728de80 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -32,9 +32,9 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; @@ -43,6 +43,7 @@ import javax.crypto.SecretKey; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.ConfigKey; @@ -52,7 +53,6 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; -import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource; @@ -152,6 +152,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio @Inject protected ConfigurationManager _configMgr; + public ConfigurationServerImpl() { setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP); } @@ -240,14 +241,14 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio if (hostIpAdr != null) { Boolean devel = Boolean.valueOf(_configDao.getValue("developer")); if (devel) { - String value = _configDao.getValue(ClusterManager.ManagementHostIPAdr.key()); + String value = _configDao.getValue(ApiServiceConfiguration.ManagementHostIPAdr.key()); if (value != null && !value.equals("localhost")) { needUpdateHostIp = false; } } if (needUpdateHostIp) { - _configDao.update(ClusterManager.ManagementHostIPAdr.key(), ClusterManager.ManagementHostIPAdr.category(), hostIpAdr); + _configDepot.createOrUpdateConfigObject(ApiServiceConfiguration.class.getSimpleName(), ApiServiceConfiguration.ManagementHostIPAdr, hostIpAdr); s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host."); } } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index b93e0276584..3b5f5ff206a 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.server; +import com.cloud.host.DetailVO; import com.cloud.host.HostVO; import com.cloud.storage.GuestOSVO; import com.cloud.utils.Pair; @@ -47,6 +48,8 @@ public interface ManagementServer extends ManagementService, PluggableService { */ HostVO getHostBy(long hostId); + DetailVO findDetail(long hostId, String name); + String getConsoleAccessUrlRoot(long vmId); GuestOSVO getGuestOs(Long guestOsId); @@ -61,12 +64,4 @@ public interface ManagementServer extends ManagementService, PluggableService { public long getMemoryOrCpuCapacityByHost(Long hostId, short capacityType); - String getHashKey(); - - String getEncryptionKey(); - - String getEncryptionIV(); - - void resetEncryptionKeyIV(); - } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index a015b4b0c2f..4bffa3f60dd 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -19,8 +19,6 @@ package com.cloud.server; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.URLDecoder; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -200,6 +198,7 @@ import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd; import org.apache.cloudstack.api.command.admin.vm.ExpungeVMCmd; +import org.apache.cloudstack.api.command.admin.vm.GetVMUserDataCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd; import org.apache.cloudstack.api.command.admin.vm.MigrateVirtualMachineWithVolumeCmd; import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd; @@ -756,9 +755,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Inject ClusterManager _clusterMgr; - private String _hashKey = null; - private String _encryptionKey = null; - private String _encryptionIV = null; @Inject protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @@ -858,6 +854,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _hostDao.findById(hostId); } + @Override + public DetailVO findDetail(long hostId, String name) { + return _detailsDao.findDetail(hostId, name); + } + @Override public long getId() { return MacAddress.getMacAddress().toLong(); @@ -942,15 +943,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return result; } - private Date massageDate(Date date, int hourOfDay, int minute, int second) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.set(Calendar.HOUR_OF_DAY, hourOfDay); - cal.set(Calendar.MINUTE, minute); - cal.set(Calendar.SECOND, second); - return cal.getTime(); - } - @Override public List searchForClusters(long zoneId, Long startIndex, Long pageSizeVal, String hypervisorType) { Filter searchFilter = new Filter(ClusterVO.class, "id", true, startIndex, pageSizeVal); @@ -2868,6 +2860,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(GenerateAlertCmd.class); cmdList.add(ListOvsElementsCmd.class); cmdList.add(ConfigureOvsElementCmd.class); + cmdList.add(GetVMUserDataCmd.class); return cmdList; } @@ -3391,65 +3384,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return result; } - @Override - public String getHashKey() { - // although we may have race conditioning here, database transaction serialization should - // give us the same key - if (_hashKey == null) { - _hashKey = _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), getBase64EncodedRandomKey(128), Config.HashKey.getDescription()); - } - return _hashKey; - } - - @Override - public String getEncryptionKey() { - if (_encryptionKey == null) { - _encryptionKey = _configDao.getValueAndInitIfNotExist(Config.EncryptionKey.key(), Config.EncryptionKey.getCategory(), getBase64EncodedRandomKey(128), - Config.EncryptionKey.getDescription()); - } - return _encryptionKey; - } - - @Override - public String getEncryptionIV() { - if (_encryptionIV == null) { - _encryptionIV = _configDao.getValueAndInitIfNotExist(Config.EncryptionIV.key(), Config.EncryptionIV.getCategory(), getBase64EncodedRandomKey(128), - Config.EncryptionIV.getDescription()); - } - return _encryptionIV; - } - - @Override - @DB - public void resetEncryptionKeyIV() { - - SearchBuilder sb = _configDao.createSearchBuilder(); - sb.and("name1", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.or("name2", sb.entity().getName(), SearchCriteria.Op.EQ); - sb.done(); - - SearchCriteria sc = sb.create(); - sc.setParameters("name1", Config.EncryptionKey.key()); - sc.setParameters("name2", Config.EncryptionIV.key()); - - _configDao.expunge(sc); - _encryptionKey = null; - _encryptionIV = null; - } - - private static String getBase64EncodedRandomKey(int nBits) { - SecureRandom random; - try { - random = SecureRandom.getInstance("SHA1PRNG"); - byte[] keyBytes = new byte[nBits / 8]; - random.nextBytes(keyBytes); - return Base64.encodeBase64URLSafeString(keyBytes); - } catch (NoSuchAlgorithmException e) { - s_logger.error("Unhandled exception: ", e); - } - return null; - } - @Override public SSHKeyPair createSSHKeyPair(CreateSSHKeyPairCmd cmd) { Account caller = CallContext.current().getCallingAccount(); diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 95ae047cea8..601ab126992 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -839,11 +839,11 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc Double sum = avgCounter.get(counter_count); Double avg = sum / currentVM; Operator op = conditionVO.getRelationalOperator(); - boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent == avg)) - || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg >= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg > thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg <= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg < thresholdPercent)); + boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent.equals(avg))) + || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg.doubleValue() >= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg.doubleValue() > thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg.doubleValue() <= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg.doubleValue() < thresholdPercent.doubleValue())); if (!bConditionCheck) { bValid = false; diff --git a/server/src/com/cloud/server/auth/UserAuthenticator.java b/server/src/com/cloud/server/auth/UserAuthenticator.java index 3fccebc4dc7..895c3c06a61 100644 --- a/server/src/com/cloud/server/auth/UserAuthenticator.java +++ b/server/src/com/cloud/server/auth/UserAuthenticator.java @@ -18,6 +18,7 @@ package com.cloud.server.auth; import java.util.Map; +import com.cloud.utils.Pair; import com.cloud.utils.component.Adapter; /** @@ -25,15 +26,18 @@ import com.cloud.utils.component.Adapter; * */ public interface UserAuthenticator extends Adapter { + public enum ActionOnFailedAuthentication { + INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT; + } /** * * @param username * @param password * @param domainId - * @return true if the user has been successfully authenticated, false otherwise + * @return the pair of 2 booleans - first identifies the success of authenciation, the second - whether to increase incorrect login attempts count in case of failed authentication */ - public boolean authenticate(String username, String password, Long domainId, Map requestParameters); + public Pair authenticate(String username, String password, Long domainId, Map requestParameters); /** * @param password diff --git a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java index e9793373c16..ce06a9624a9 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java +++ b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java @@ -27,7 +27,11 @@ public class ConsoleProxyClientParam { private String clientTunnelUrl; private String clientTunnelSession; + private String hypervHost; + private String ajaxSessionId; + private String username; + private String password; public ConsoleProxyClientParam() { clientHostPort = 0; @@ -89,26 +93,51 @@ public class ConsoleProxyClientParam { this.clientTunnelSession = clientTunnelSession; } - public String getLocale() { - return this.locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } - public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { this.ajaxSessionId = ajaxSessionId; } + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + public String getClientMapKey() { if (clientTag != null && !clientTag.isEmpty()) return clientTag; return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String host) { + hypervHost = host; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index 0359a45c8b6..6a5c6a9060d 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -43,7 +43,7 @@ import org.springframework.web.context.support.SpringBeanAutowiringSupport; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import org.apache.cloudstack.api.IdentityService; +import org.apache.cloudstack.framework.security.keys.KeysManager; import com.cloud.exception.PermissionDeniedException; import com.cloud.host.HostVO; @@ -81,13 +81,13 @@ public class ConsoleProxyServlet extends HttpServlet { @Inject ManagementServer _ms; @Inject - IdentityService _identityService; - @Inject EntityManager _entityMgr; @Inject UserVmDetailsDao _userVmDetailsDao; + @Inject + KeysManager _keysMgr; - static ManagementServer s_ms; + static KeysManager s_keysMgr; private final Gson _gson = new GsonBuilder().create(); @@ -97,7 +97,7 @@ public class ConsoleProxyServlet extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext()); - s_ms = _ms; + s_keysMgr = _keysMgr; } @Override @@ -114,7 +114,7 @@ public class ConsoleProxyServlet extends HttpServlet { return; } - if (_ms.getHashKey() == null) { + if (_keysMgr.getHashKey() == null) { s_logger.debug("Console/thumbnail access denied. Ticket service is not ready yet"); sendResponse(resp, "Service is not ready"); return; @@ -165,13 +165,15 @@ public class ConsoleProxyServlet extends HttpServlet { } String vmIdString = req.getParameter("vm"); - Long vmId = _identityService.getIdentityId("vm_instance", vmIdString); - if (vmId == null) { + VirtualMachine vm = _entityMgr.findByUuid(VirtualMachine.class, vmIdString); + if (vm == null) { s_logger.info("invalid console servlet command parameter: " + vmIdString); sendResponse(resp, ""); return; } + Long vmId = vm.getId(); + if (!checkSessionPermision(req, vmId, accountObj)) { sendResponse(resp, "Permission denied"); return; @@ -326,15 +328,21 @@ public class ConsoleProxyServlet extends HttpServlet { s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo); - if (hostInfo != null && hostInfo.startsWith("consoleurl")) { - String tokens[] = hostInfo.split("&"); + if (hostInfo != null) { + if (hostInfo.startsWith("consoleurl")) { + String tokens[] = hostInfo.split("&"); - if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) { - host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim(); - tunnelUrl = tokens[0].substring("consoleurl=".length()); - tunnelSession = tokens[1].split("=")[1]; + if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) { + host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim(); + tunnelUrl = tokens[0].substring("consoleurl=".length()); + tunnelSession = tokens[1].split("=")[1]; + } else { + host = ""; + } + } else if (hostInfo.startsWith("instanceId")) { + host = hostInfo.substring(hostInfo.indexOf('=') + 1); } else { - host = ""; + host = hostInfo; } } else { host = hostInfo; @@ -344,8 +352,8 @@ public class ConsoleProxyServlet extends HttpServlet { } private String getEncryptorPassword() { - String key = _ms.getEncryptionKey(); - String iv = _ms.getEncryptionIV(); + String key = _keysMgr.getEncryptionKey(); + String iv = _keysMgr.getEncryptionIV(); ConsoleProxyPasswordBasedEncryptor.KeyIVPair keyIvPair = new ConsoleProxyPasswordBasedEncryptor.KeyIVPair(key, iv); return _gson.toJson(keyIvPair); @@ -360,9 +368,17 @@ public class ConsoleProxyServlet extends HttpServlet { Ternary parsedHostInfo = parseHostInfo(portInfo.first()); String sid = vm.getVncPassword(); - String tag = String.valueOf(vm.getId()); - tag = _identityService.getIdentityUuid("vm_instance", tag); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + String tag = vm.getUuid(); + + int port = -1; + if (portInfo.second() == -9) { + //for hyperv + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); + } else { + port = portInfo.second(); + } + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); @@ -371,6 +387,12 @@ public class ConsoleProxyServlet extends HttpServlet { param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); + } if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); @@ -395,21 +417,39 @@ public class ConsoleProxyServlet extends HttpServlet { Ternary parsedHostInfo = parseHostInfo(portInfo.first()); - UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); + int port = -1; + if (portInfo.second() == -9) { + //for hyperv + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); + } else { + port = portInfo.second(); + } + String sid = vm.getVncPassword(); + UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); + String tag = vm.getUuid(); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); param.setClientHostAddress(parsedHostInfo.first()); - param.setClientHostPort(portInfo.second()); + param.setClientHostPort(port); param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (details != null) { param.setLocale(details.getValue()); } - if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { + + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); + } + if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); } @@ -440,7 +480,7 @@ public class ConsoleProxyServlet extends HttpServlet { long ts = normalizedHashTime.getTime(); ts = ts / 60000; // round up to 1 minute - String secretKey = s_ms.getHashKey(); + String secretKey = s_keysMgr.getHashKey(); SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); mac.init(keySpec); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index ac0c438aab9..55582c6421d 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -59,6 +59,7 @@ import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.Outcome; +import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO; @@ -73,6 +74,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -327,6 +329,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Inject protected AsyncJobManager _jobMgr; + @Inject + protected VmWorkJobDao _workJobDao; + VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); // TODO @@ -444,8 +449,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null); - volume.setAccountId(owner.getAccountId()); - volume.setDomainId(owner.getDomainId()); + volume.setAccountId((owner == null) ? null : owner.getAccountId()); + volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); volume.setDiskOfferingId(diskOfferingId); // volume.setSize(size); @@ -911,8 +916,19 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateResizeVolume(volume.getId(), currentSize, newSize, - newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(userVm.getId()); + } + try { + return orchestrateResizeVolume(volume.getId(), currentSize, newSize, + newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = resizeVolumeThroughJobQueue(userVm.getId(), volume.getId(), currentSize, newSize, newDiskOffering != null ? cmd.getNewDiskOfferingId() : null, shrinkOk); @@ -1102,7 +1118,18 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateAttachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(command.getVirtualMachineId()); + } + try { + return orchestrateAttachVolumeToVM(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = attachVolumeToVmThroughJobQueue(command.getVirtualMachineId(), command.getId(), command.getDeviceId()); @@ -1405,7 +1432,16 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateDetachVolumeFromVM(vmId, volumeId); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmId); + } + try { + return orchestrateDetachVolumeFromVM(vmId, volumeId); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = detachVolumeFromVmThroughJobQueue(vmId, volumeId); @@ -1482,12 +1518,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary); - if (!sendCommand || (answer != null && answer.getResult())) { // Mark the volume as detached _volsDao.detachVolume(volume.getId()); + // volume.getPoolId() should be null if the VM we are attaching the disk to has never been started before + DataStore dataStore = volume.getPoolId() != null ? dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary) : null; + volService.disconnectVolumeFromHost(volFactory.getVolume(volume.getId()), host, dataStore); return _volsDao.findById(volumeId); @@ -1570,7 +1607,18 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + return orchestrateMigrateVolume(vol.getId(), destPool.getId(), liveMigrateVolume); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = migrateVolumeThroughJobQueue(vm.getId(), vol.getId(), destPool.getId(), liveMigrateVolume); @@ -1661,7 +1709,18 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vm.getId()); + } + try { + return orchestrateTakeVolumeSnapshot(volumeId, policyId, snapshotId, account, quiescevm); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = takeVolumeSnapshotThroughJobQueue(vm.getId(), volumeId, policyId, snapshotId, account.getId(), quiescevm); @@ -1955,14 +2014,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic } } - DataStore dataStore = dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary); - - boolean queryForChap = true; + // volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before + DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null; + // if we don't have a host, the VM we are attaching the disk to has never been started before if (host != null) { try { - // if connectVolumeToHost returns true, then we do not want to use CHAP because the volume is already connected to the host(s) - queryForChap = !volService.connectVolumeToHost(volFactory.getVolume(volumeToAttach.getId()), host, dataStore); + volService.connectVolumeToHost(volFactory.getVolume(volumeToAttach.getId()), host, dataStore); } catch (Exception e) { volService.disconnectVolumeFromHost(volFactory.getVolume(volumeToAttach.getId()), host, dataStore); @@ -1985,7 +2043,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName()); - ChapInfo chapInfo = queryForChap ? volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore) : null; + ChapInfo chapInfo = volService.getChapInfo(volFactory.getVolume(volumeToAttach.getId()), dataStore); Map details = new HashMap(); @@ -2187,7 +2245,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -2234,7 +2292,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -2278,7 +2336,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -2323,7 +2381,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -2368,7 +2426,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -2425,4 +2483,23 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic public Pair handleVmWorkJob(VmWork work) throws Exception { return _jobHandlerProxy.handleVmWorkJob(work); } + + private VmWorkJobVO createPlaceHolderWork(long instanceId) { + VmWorkJobVO workJob = new VmWorkJobVO(""); + + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER); + workJob.setCmd(""); + workJob.setCmdInfo(""); + + workJob.setAccountId(0); + workJob.setUserId(0); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(instanceId); + workJob.setInitMsid(ManagementServerNode.getManagementServerId()); + + _workJobDao.persist(workJob); + + return workJob; + } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index f42bca09b91..a5d3d4c2dcf 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -30,8 +30,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -43,6 +42,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.utils.identity.ManagementServerNode; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -1014,7 +1014,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar StringBuilder buf = profile.getBootArgsBuilder(); buf.append(" template=domP type=secstorage"); - buf.append(" host=").append(ClusterManager.ManagementHostIPAdr.value()); + buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value()); buf.append(" port=").append(_mgmtPort); buf.append(" name=").append(profile.getVirtualMachine().getHostName()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index a1af95c3ff2..3b32c851f0a 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -27,7 +27,7 @@ import com.cloud.vm.SecondaryStorageVmVO; public interface SecondaryStorageVmManager extends Manager { - public static final int DEFAULT_SS_VM_RAMSIZE = 256; // 256M + public static final int DEFAULT_SS_VM_RAMSIZE = 512; // 512M public static final int DEFAULT_SS_VM_CPUMHZ = 500; // 500 MHz public static final int DEFAULT_SS_VM_MTUSIZE = 1500; public static final int DEFAULT_SS_VM_CAPACITY = 50; // max command execution session per SSVM diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index a202ad28517..be896f063bd 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,70 +25,101 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.context.CallContext; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import com.cloud.api.query.dao.ResourceTagJoinDao; -import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.DataCenterVO; import com.cloud.domain.Domain; +import com.cloud.domain.PartOf; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.RemoteAccessVpnDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; -import com.cloud.network.dao.Site2SiteVpnConnectionDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.rules.dao.PortForwardingRulesDao; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.NetworkACLItemDao; -import com.cloud.network.vpc.dao.NetworkACLDao; -import com.cloud.network.vpc.dao.StaticRouteDao; -import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.network.vpc.dao.VpcGatewayDao; -import com.cloud.projects.dao.ProjectDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.RemoteAccessVpnVO; +import com.cloud.network.dao.Site2SiteCustomerGatewayVO; +import com.cloud.network.dao.Site2SiteVpnConnectionVO; +import com.cloud.network.dao.Site2SiteVpnGatewayVO; +import com.cloud.network.rules.FirewallRuleVO; +import com.cloud.network.rules.PortForwardingRuleVO; +import com.cloud.network.security.SecurityGroupVO; +import com.cloud.network.vpc.NetworkACLItemVO; +import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.StaticRouteVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.projects.ProjectVO; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.server.TaggedResourceService; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; -import com.cloud.user.dao.UserDao; +import com.cloud.user.OwnedBy; +import com.cloud.user.UserVO; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.DbUtil; -import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.uuididentity.dao.IdentityDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.snapshot.VMSnapshotVO; -@Component @Local(value = {TaggedResourceService.class}) public class TaggedResourceManagerImpl extends ManagerBase implements TaggedResourceService { public static final Logger s_logger = Logger.getLogger(TaggedResourceManagerImpl.class); - private static Map> s_daoMap = new HashMap>(); + private static final Map> s_typeMap = new HashMap>(); + static { + s_typeMap.put(ResourceObjectType.UserVm, UserVmVO.class); + s_typeMap.put(ResourceObjectType.Volume, VolumeVO.class); + s_typeMap.put(ResourceObjectType.Template, VMTemplateVO.class); + s_typeMap.put(ResourceObjectType.ISO, VMTemplateVO.class); + s_typeMap.put(ResourceObjectType.Snapshot, SnapshotVO.class); + s_typeMap.put(ResourceObjectType.Network, NetworkVO.class); + s_typeMap.put(ResourceObjectType.LoadBalancer, LoadBalancerVO.class); + s_typeMap.put(ResourceObjectType.PortForwardingRule, PortForwardingRuleVO.class); + s_typeMap.put(ResourceObjectType.FirewallRule, FirewallRuleVO.class); + s_typeMap.put(ResourceObjectType.SecurityGroup, SecurityGroupVO.class); + s_typeMap.put(ResourceObjectType.PublicIpAddress, IPAddressVO.class); + s_typeMap.put(ResourceObjectType.Project, ProjectVO.class); + s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class); + s_typeMap.put(ResourceObjectType.Nic, NicVO.class); + s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLVO.class); + s_typeMap.put(ResourceObjectType.StaticRoute, StaticRouteVO.class); + s_typeMap.put(ResourceObjectType.VMSnapshot, VMSnapshotVO.class); + s_typeMap.put(ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class); + s_typeMap.put(ResourceObjectType.Zone, DataCenterVO.class); + s_typeMap.put(ResourceObjectType.ServiceOffering, ServiceOfferingVO.class); + s_typeMap.put(ResourceObjectType.Storage, StoragePoolVO.class); + s_typeMap.put(ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class); + s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLItemVO.class); + s_typeMap.put(ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class); + s_typeMap.put(ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class); + s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class); + s_typeMap.put(ResourceObjectType.User, UserVO.class); + s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); + } + @Inject + EntityManager _entityMgr; @Inject AccountManager _accountMgr; @Inject @@ -96,95 +127,11 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Inject ResourceTagJoinDao _resourceTagJoinDao; @Inject - IdentityDao _identityDao; - @Inject DomainManager _domainMgr; - @Inject - UserVmDao _userVmDao; - @Inject - VolumeDao _volumeDao; - @Inject - VMTemplateDao _templateDao; - @Inject - SnapshotDao _snapshotDao; - @Inject - NetworkDao _networkDao; - @Inject - LoadBalancerDao _lbDao; - @Inject - PortForwardingRulesDao _pfDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - SecurityGroupDao _securityGroupDao; - @Inject - RemoteAccessVpnDao _vpnDao; - @Inject - IPAddressDao _publicIpDao; - @Inject - ProjectDao _projectDao; - @Inject - VpcDao _vpcDao; - @Inject - StaticRouteDao _staticRouteDao; - @Inject - VMSnapshotDao _vmSnapshotDao; - @Inject - NicDao _nicDao; - @Inject - NetworkACLItemDao _networkACLItemDao; - @Inject - DataCenterDao _dataCenterDao; - @Inject - ServiceOfferingDao _serviceOffDao; - @Inject - PrimaryDataStoreDao _storagePoolDao; - @Inject - VpcGatewayDao _vpcGatewayDao; - @Inject - NetworkACLDao _networkACLListDao; - @Inject - Site2SiteVpnGatewayDao _vpnGatewayDao; - @Inject - Site2SiteCustomerGatewayDao _customerGatewayDao; - @Inject - Site2SiteVpnConnectionDao _vpnConnectionDao; - @Inject - UserDao _userDao; - @Inject - DiskOfferingDao _diskOffDao; + @Override public boolean configure(String name, Map params) throws ConfigurationException { - s_daoMap.put(ResourceObjectType.UserVm, _userVmDao); - s_daoMap.put(ResourceObjectType.Volume, _volumeDao); - s_daoMap.put(ResourceObjectType.Template, _templateDao); - s_daoMap.put(ResourceObjectType.ISO, _templateDao); - s_daoMap.put(ResourceObjectType.Snapshot, _snapshotDao); - s_daoMap.put(ResourceObjectType.Network, _networkDao); - s_daoMap.put(ResourceObjectType.LoadBalancer, _lbDao); - s_daoMap.put(ResourceObjectType.PortForwardingRule, _pfDao); - s_daoMap.put(ResourceObjectType.FirewallRule, _firewallDao); - s_daoMap.put(ResourceObjectType.SecurityGroup, _securityGroupDao); - s_daoMap.put(ResourceObjectType.PublicIpAddress, _publicIpDao); - s_daoMap.put(ResourceObjectType.Project, _projectDao); - s_daoMap.put(ResourceObjectType.Vpc, _vpcDao); - s_daoMap.put(ResourceObjectType.Nic, _nicDao); - s_daoMap.put(ResourceObjectType.NetworkACL, _networkACLItemDao); - s_daoMap.put(ResourceObjectType.StaticRoute, _staticRouteDao); - s_daoMap.put(ResourceObjectType.VMSnapshot, _vmSnapshotDao); - s_daoMap.put(ResourceObjectType.RemoteAccessVpn, _vpnDao); - s_daoMap.put(ResourceObjectType.Zone, _dataCenterDao); - s_daoMap.put(ResourceObjectType.ServiceOffering, _serviceOffDao); - s_daoMap.put(ResourceObjectType.Storage, _storagePoolDao); - s_daoMap.put(ResourceObjectType.PrivateGateway, _vpcGatewayDao); - s_daoMap.put(ResourceObjectType.NetworkACLList, _networkACLListDao); - s_daoMap.put(ResourceObjectType.VpnGateway, _vpnGatewayDao); - s_daoMap.put(ResourceObjectType.CustomerGateway, _customerGatewayDao); - s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDao); - s_daoMap.put(ResourceObjectType.User, _userDao); - s_daoMap.put(ResourceObjectType.DiskOffering, _diskOffDao); - return true; } @@ -200,59 +147,31 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override public long getResourceId(String resourceId, ResourceObjectType resourceType) { - GenericDao dao = s_daoMap.get(resourceType); - if (dao == null) { - throw new CloudRuntimeException("Dao is not loaded for the resource type " + resourceType); + Class clazz = s_typeMap.get(resourceType); + Object entity = _entityMgr.findByUuid(clazz, resourceId); + if (entity != null) { + return ((InternalIdentity)entity).getId(); } - Class claz = DbUtil.getEntityBeanType(dao); - - Long identityId = null; - - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - identityId = _identityDao.getIdentityId(tableName, resourceId); - if (identityId != null) { - break; - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } - claz = claz.getSuperclass(); + entity = _entityMgr.findById(clazz, resourceId); + if (entity != null) { + return ((InternalIdentity)entity).getId(); } - - if (identityId == null) { - throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); - } - return identityId; + throw new InvalidParameterValueException("Unable to find resource by id " + resourceId + " and type " + resourceType); } private Pair getAccountDomain(long resourceId, ResourceObjectType resourceType) { + Class clazz = s_typeMap.get(resourceType); - Pair pair = null; - GenericDao dao = s_daoMap.get(resourceType); - Class claz = DbUtil.getEntityBeanType(dao); - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - pair = _identityDao.getAccountDomainInfo(tableName, resourceId, resourceType); - if (pair.first() != null || pair.second() != null) { - break; - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } - claz = claz.getSuperclass(); + Object entity = _entityMgr.findById(clazz, resourceId); + Long accountId = null; + Long domainId = null; + if (entity instanceof OwnedBy) { + accountId = ((OwnedBy)entity).getAccountId(); } - Long accountId = pair.first(); - Long domainId = pair.second(); + if (entity instanceof PartOf) { + domainId = ((PartOf)entity).getDomainId(); + } if (accountId == null) { accountId = Account.ACCOUNT_ID_SYSTEM; @@ -327,32 +246,14 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso @Override public String getUuid(String resourceId, ResourceObjectType resourceType) { - GenericDao dao = s_daoMap.get(resourceType); - Class claz = DbUtil.getEntityBeanType(dao); + Class clazz = s_typeMap.get(resourceType); - String identiyUUId = null; - - while (claz != null && claz != Object.class) { - try { - String tableName = DbUtil.getTableName(claz); - if (tableName == null) { - throw new InvalidParameterValueException("Unable to find resource of type " + resourceType + " in the database"); - } - - claz = claz.getSuperclass(); - if (claz == Object.class) { - identiyUUId = _identityDao.getIdentityUuid(tableName, resourceId); - } - } catch (Exception ex) { - //do nothing here, it might mean uuid field is missing and we have to search further - } + Object entity = _entityMgr.findById(clazz, resourceId); + if (entity != null && entity instanceof Identity) { + return ((Identity)entity).getUuid(); } - if (identiyUUId == null) { - return resourceId; - } - - return identiyUUId; + return resourceId; } @Override diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 59aab3b64b7..e3999122b53 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -176,8 +176,14 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat } boolean isAdmin = _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN; + boolean isRegionStore = false; + List stores = _imgStoreDao.findRegionImageStores(); + if (stores != null && stores.size() > 0) { + isRegionStore = true; + } - if (!isAdmin && zoneId == null) { + if (!isAdmin && zoneId == null && !isRegionStore ) { + // domain admin and user should also be able to register template on a region store throw new InvalidParameterValueException("Please specify a valid zone Id."); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index ac641a2010c..56232d27609 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -425,7 +425,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (isISO) { desc = Upload.Type.ISO.toString(); } - eventId = eventId == null ? 0 : eventId; + eventId = (eventId == null ? 0 : eventId); if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) { throw new PermissionDeniedException("Extraction has been disabled by admin"); @@ -1785,7 +1785,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } // Don't allow to modify system template - if (id == Long.valueOf(1)) { + if (Long.valueOf(1).equals(id)) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); ex.addProxyObject(String.valueOf(id), "templateId"); throw ex; diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/com/cloud/test/IPRangeConfig.java index f4619955f4f..1d564714087 100755 --- a/server/src/com/cloud/test/IPRangeConfig.java +++ b/server/src/com/cloud/test/IPRangeConfig.java @@ -69,7 +69,7 @@ public class IPRangeConfig { long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "public", -1, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else if (type.equals("private")) { if (args.length != 5 && args.length != 6) { @@ -92,7 +92,7 @@ public class IPRangeConfig { long podId = PodZoneConfig.getPodId(pod, zone); long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "private", podId, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else { printError(usage()); @@ -569,31 +569,6 @@ public class IPRangeConfig { "Unable to start DB connection to read guest cidr network. Please contact Cloud Support."); } -// public static String getGuestIpNetwork() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.ip.network\"", "value", -// "Unable to start DB connection to read guest IP network. Please contact Cloud Support."); -// } -// -// public static String getGuestNetmask() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.netmask\"", "value", -// "Unable to start DB connection to read guest netmask. Please contact Cloud Support."); -// } - -// public static String getGuestSubnet() { -// String guestIpNetwork = getGuestIpNetwork(); -// String guestNetmask = getGuestNetmask(); -// -// if (guestIpNetwork == null || guestIpNetwork.isEmpty()) printError("Please enter a valid guest IP network address."); -// if (guestNetmask == null || guestNetmask.isEmpty()) printError("Please enter a valid guest IP network netmask"); -// -// return NetUtils.getSubNet(guestIpNetwork, guestNetmask); -// } - -// public static long getGuestCidrSize() { -// String guestNetmask = getGuestNetmask(); -// return NetUtils.getCidrSize(guestNetmask); -// } - public static boolean validCIDR(final String cidr) { if (cidr == null || cidr.isEmpty()) { return false; diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 52045897619..186cfb2afa2 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -21,6 +21,7 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -37,9 +38,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker; @@ -55,6 +53,8 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.vo.ControlledViewEntity; @@ -111,6 +111,7 @@ import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.server.auth.UserAuthenticator; +import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeApiService; @@ -1965,13 +1966,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } boolean authenticated = false; + HashSet actionsOnFailedAuthenticaion = new HashSet(); for (UserAuthenticator authenticator : _userAuthenticators) { - if (authenticator.authenticate(username, password, domainId, requestParameters)) { + Pair result = authenticator.authenticate(username, password, domainId, requestParameters); + if (result.first()) { authenticated = true; break; + } else if (result.second() != null) { + actionsOnFailedAuthenticaion.add(result.second()); } } + boolean updateIncorrectLoginCount = actionsOnFailedAuthenticaion.contains(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT); + if (authenticated) { UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId); if (userAccount == null) { @@ -2009,12 +2016,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M if (!isInternalAccount(userAccount.getType())) { // Internal accounts are not disabled int attemptsMade = userAccount.getLoginAttempts() + 1; - if (attemptsMade < _allowedLoginAttempts) { - updateLoginAttempts(userAccount.getId(), attemptsMade, false); - s_logger.warn("Login attempt failed. You have " + (_allowedLoginAttempts - attemptsMade) + " attempt(s) remaining"); - } else { - updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts, true); - s_logger.warn("User " + userAccount.getUsername() + " has been disabled due to multiple failed login attempts." + " Please contact admin."); + if (updateIncorrectLoginCount) { + if (attemptsMade < _allowedLoginAttempts) { + updateLoginAttempts(userAccount.getId(), attemptsMade, false); + s_logger.warn("Login attempt failed. You have " + (_allowedLoginAttempts - attemptsMade) + " attempt(s) remaining"); + } else { + updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts, true); + s_logger.warn("User " + userAccount.getUsername() + " has been disabled due to multiple failed login attempts." + " Please contact admin."); + } } } } else { diff --git a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java b/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java deleted file mode 100644 index 3475104dbc3..00000000000 --- a/server/src/com/cloud/uuididentity/dao/IdentityDaoImpl.java +++ /dev/null @@ -1,241 +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.uuididentity.dao; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.server.ResourceTag.ResourceObjectType; -import com.cloud.utils.Pair; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.TransactionLegacy; - -@Component -@Local(value = {IdentityDao.class}) -public class IdentityDaoImpl extends GenericDaoBase implements IdentityDao { - private static final Logger s_logger = Logger.getLogger(IdentityDaoImpl.class); - - public IdentityDaoImpl() { - } - - @Override - @DB - public Long getIdentityId(String tableName, String identityString) { - assert (tableName != null); - assert (identityString != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s`", tableName)); - pstmt.executeQuery(); - } catch (SQLException e) { - throw new InvalidParameterValueException("uuid field doesn't exist in table " + tableName); - } - - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT id FROM `%s` WHERE id=? OR uuid=?", tableName) - - // TODO : after graceful period, use following line turn on more secure check - // String.format("SELECT id FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", mapper.entityTableName()) - ); - - long id = 0; - try { - // TODO : use regular expression to determine - id = Long.parseLong(identityString); - } catch (NumberFormatException e) { - // this could happen when it is a uuid string, so catch and ignore it - } - - pstmt.setLong(1, id); - pstmt.setString(2, identityString); - - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - return rs.getLong(1); - } else { - if (id == -1L) - return id; - - throw new InvalidParameterValueException("Object " + tableName + "(uuid: " + identityString + ") does not exist."); - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - return null; - } - - @DB - @Override - public Pair getAccountDomainInfo(String tableName, Long identityId, ResourceObjectType resourceType) { - assert (tableName != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - Long domainId = null; - Long accountId = null; - //get domainId - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT domain_id FROM `%s` WHERE id=?", tableName)); - pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - if (rs.getLong(1) != 0) { - domainId = rs.getLong(1); - } - } - } catch (SQLException e) { - } - - //get accountId - try { - String account = "account_id"; - if (resourceType == ResourceObjectType.Project) { - account = "project_account_id"; - } - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT " + account + " FROM `%s` WHERE id=?", tableName)); - pstmt.setLong(1, identityId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - if (rs.getLong(1) != 0) { - accountId = rs.getLong(1); - } - } - } catch (SQLException e) { - } - return new Pair(accountId, domainId); - } finally { - txn.close(); - } - } - - @DB - @Override - public String getIdentityUuid(String tableName, String identityString) { - assert (tableName != null); - assert (identityString != null); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT uuid FROM `%s` WHERE id=? OR uuid=?", tableName) - // String.format("SELECT uuid FROM %s WHERE (id=? AND uuid IS NULL) OR uuid=?", tableName) - ); - - long id = 0; - try { - // TODO : use regular expression to determine - id = Long.parseLong(identityString); - } catch (NumberFormatException e) { - // this could happen when it is a uuid string, so catch and ignore it - } - - pstmt.setLong(1, id); - pstmt.setString(2, identityString); - - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - String uuid = rs.getString(1); - if (uuid != null && !uuid.isEmpty()) - return uuid; - return identityString; - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - - return identityString; - } - - @Override - @DB - public void initializeDefaultUuid(String tableName) { - assert (tableName != null); - List l = getNullUuidRecords(tableName); - - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - txn.start(); - for (Long id : l) { - setInitialUuid(tableName, id); - } - txn.commit(); - } catch (SQLException e) { - txn.rollback(); - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - } - - @DB - List getNullUuidRecords(String tableName) { - List l = new ArrayList(); - - PreparedStatement pstmt = null; - TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB); - try { - try { - pstmt = txn.prepareAutoCloseStatement(String.format("SELECT id FROM `%s` WHERE uuid IS NULL", tableName)); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - l.add(rs.getLong(1)); - } - } catch (SQLException e) { - s_logger.error("Unexpected exception ", e); - } - } finally { - txn.close(); - } - return l; - } - - @DB - void setInitialUuid(String tableName, long id) throws SQLException { - TransactionLegacy txn = TransactionLegacy.currentTxn(); - - PreparedStatement pstmtUpdate = null; - pstmtUpdate = txn.prepareAutoCloseStatement(String.format("UPDATE `%s` SET uuid=? WHERE id=?", tableName)); - - pstmtUpdate.setString(1, String.valueOf(id)); - pstmtUpdate.setLong(2, id); - pstmtUpdate.executeUpdate(); - } -} diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index e9cccc4fe36..1dcaf798a5d 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -34,6 +34,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -79,8 +82,6 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -458,7 +459,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir protected boolean _dailyOrHourly = false; private int capacityReleaseInterval; - protected String _name; protected String _instance; protected String _zone; protected boolean _instanceNameFlag; @@ -965,10 +965,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (network == null) { throw new InvalidParameterValueException("unable to find a network with id " + networkId); } - if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain) - && !(network.getAclType() == ACLType.Account && network.getAccountId() == vmInstance.getAccountId())) { - throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vmId: " + vmId); + + if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain) + && !(network.getAclType() == ACLType.Account && network.getAccountId() == vmInstance.getAccountId())) { + throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vmId: " + vmId); + } } + List allNics = _nicDao.listByVmId(vmInstance.getId()); for (NicVO nic : allNics) { if (nic.getNetworkId() == network.getId()) @@ -2632,10 +2636,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (network.getDataCenterId() != zone.getId()) { throw new InvalidParameterValueException("Network id=" + network.getId() + " doesn't belong to zone " + zone.getId()); } - if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain) - && !(network.getAclType() == ACLType.Account && network.getAccountId() == accountId)) { - throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vm"); + + //relax the check if the caller is admin account + if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + if (!(network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Domain) + && !(network.getAclType() == ACLType.Account && network.getAccountId() == accountId)) { + throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vm"); + } } + IpAddresses requestedIpPair = null; if (requestedIps != null && !requestedIps.isEmpty()) { requestedIpPair = requestedIps.get(network.getId()); @@ -2962,6 +2971,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir long vmId = cmd.getEntityId(); Long hostId = cmd.getHostId(); UserVmVO vm = _vmDao.findById(vmId); + CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid()); Pair> vmParamPair = null; try { @@ -3994,13 +4004,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir //if hosts are dedicated to different account/domains, raise an alert if (srcExplDedicated && destExplDedicated) { - if ((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost) != accountOfDedicatedHost(destHost))) { + if (!((accountOfDedicatedHost(srcHost) == null) || (accountOfDedicatedHost(srcHost).equals(accountOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } - if ((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost) != domainOfDedicatedHost(destHost))) { + if (!((domainOfDedicatedHost(srcHost) == null) || (domainOfDedicatedHost(srcHost).equals(domainOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); @@ -4797,4 +4807,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir public ConfigKey[] getConfigKeys() { return new ConfigKey[] {EnableDynamicallyScaleVm}; } + + @Override + public String getVmUserData(long vmId) { + UserVmVO vm = _vmDao.findById(vmId); + if (vm == null) { + throw new InvalidParameterValueException("Unable to find virual machine with id " + vmId); + } + + //check permissions + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, vm); + return vm.getUserData(); + } } diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 7d6e0ec71c1..78652a22aee 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -41,10 +41,12 @@ import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.Outcome; +import org.apache.cloudstack.framework.jobs.dao.VmWorkJobDao; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl; import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO; import org.apache.cloudstack.jobs.JobInfo; +import org.apache.cloudstack.utils.identity.ManagementServerNode; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -103,7 +105,6 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana public static final String VM_WORK_JOB_HANDLER = VMSnapshotManagerImpl.class.getSimpleName(); - String _name; @Inject VMInstanceDao _vmInstanceDao; @Inject VMSnapshotDao _vmSnapshotDao; @@ -124,6 +125,9 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana @Inject AsyncJobManager _jobMgr; + @Inject + VmWorkJobDao _workJobDao; + VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); int _vmSnapshotMax; @@ -364,7 +368,17 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateCreateVMSnapshot(vmId, vmSnapshotId, quiescevm); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmId); + } + try { + return orchestrateCreateVMSnapshot(vmId, vmSnapshotId, quiescevm); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = createVMSnapshotThroughJobQueue(vmId, vmSnapshotId, quiescevm); @@ -452,7 +466,16 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateDeleteVMSnapshot(vmSnapshotId); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmSnapshot.getVmId()); + } + try { + return orchestrateDeleteVMSnapshot(vmSnapshotId); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } } else { Outcome outcome = deleteVMSnapshotThroughJobQueue(vmSnapshot.getVmId(), vmSnapshotId); @@ -558,7 +581,18 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateRevertToVMSnapshot(vmSnapshotId); + + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmSnapshotVo.getVmId()); + } + try { + return orchestrateRevertToVMSnapshot(vmSnapshotId); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = revertToVMSnapshotThroughJobQueue(vmSnapshotVo.getVmId(), vmSnapshotId); @@ -684,7 +718,17 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext(); if (!VmJobEnabled.value() || jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) { // avoid re-entrance - return orchestrateDeleteAllVMSnapshots(vmId, type); + VmWorkJobVO placeHolder = null; + if (VmJobEnabled.value()) { + placeHolder = createPlaceHolderWork(vmId); + } + try { + return orchestrateDeleteAllVMSnapshots(vmId, type); + } finally { + if (VmJobEnabled.value()) + _workJobDao.expunge(placeHolder.getId()); + } + } else { Outcome outcome = deleteAllVMSnapshotsThroughJobQueue(vmId, type); @@ -828,7 +872,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -872,7 +916,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -916,7 +960,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -960,7 +1004,7 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana workJob.setAccountId(callingAccount.getId()); workJob.setUserId(callingUser.getId()); workJob.setStep(VmWorkJobVO.Step.Starting); - workJob.setVmType(vm.getType()); + workJob.setVmType(VirtualMachine.Type.Instance); workJob.setVmInstanceId(vm.getId()); workJob.setRelated(AsyncJobExecutionContext.getOriginJobContextId()); @@ -1009,4 +1053,23 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana public Pair handleVmWorkJob(VmWork work) throws Exception { return _jobHandlerProxy.handleVmWorkJob(work); } + + private VmWorkJobVO createPlaceHolderWork(long instanceId) { + VmWorkJobVO workJob = new VmWorkJobVO(""); + + workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER); + workJob.setCmd(""); + workJob.setCmdInfo(""); + + workJob.setAccountId(0); + workJob.setUserId(0); + workJob.setStep(VmWorkJobVO.Step.Starting); + workJob.setVmType(VirtualMachine.Type.Instance); + workJob.setVmInstanceId(instanceId); + workJob.setInitMsid(ManagementServerNode.getManagementServerId()); + + _workJobDao.persist(workJob); + + return workJob; + } } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 846e2f58d8e..226788370e6 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -404,10 +404,10 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) + * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // TODO Auto-generated method stub return null; diff --git a/server/test/resources/network-mgr-component.xml b/server/test/resources/network-mgr-component.xml index b55a68b0fcf..a0ddce04c0c 100644 --- a/server/test/resources/network-mgr-component.xml +++ b/server/test/resources/network-mgr-component.xml @@ -174,7 +174,6 @@ under the License. - diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml index 5737a858a10..05585a1027a 100755 --- a/services/console-proxy-rdp/rdpconsole/pom.xml +++ b/services/console-proxy-rdp/rdpconsole/pom.xml @@ -72,7 +72,6 @@ org.bouncycastle bcprov-jdk16 - 1.46 diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java index 43abb273477..9cb523137ec 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java @@ -30,7 +30,7 @@ public class BufferedImageCanvas extends Canvas { private static final long serialVersionUID = 1L; // Offline screen buffer - private BufferedImage offlineImage; + protected BufferedImage offlineImage; // Cached Graphics2D object for offline screen buffer private Graphics2D graphics; @@ -76,4 +76,8 @@ public class BufferedImageCanvas extends Canvas { return graphics; } + public void updateFrameBuffer(int x, int y, int w, int h) { + //this method will be used to mark the dirty tiles + } + } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java index 55ca8fdbf64..f3a73d70dbd 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java @@ -77,13 +77,14 @@ public class AwtCanvasAdapter extends BaseElement { } private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) { - // TODO Auto-generated method stub // Copy image canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY); // Request update of repainted area + canvas.updateFrameBuffer(order.x, order.y, order.width, order.height); canvas.repaint(order.x, order.y, order.width, order.height); + } private void handleBitmap(BitmapOrder order, ByteBuffer buf) { @@ -137,6 +138,7 @@ public class AwtCanvasAdapter extends BaseElement { g.drawImage(rectImage, x, y, null); // Request update of repainted area + canvas.updateFrameBuffer(x, y, width, height); canvas.repaint(x, y, width, height); } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java index afde70698e3..a3db165c2fa 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java @@ -63,6 +63,9 @@ import common.adapter.AwtCanvasAdapter; public class RdpClient extends PipelineImpl { + AwtMouseEventSource mouseEventSource = null; + AwtKeyEventSource keyEventSource = null; + /** * Name of last OneTimePacket in handshake sequence. */ @@ -333,8 +336,8 @@ public class RdpClient extends PipelineImpl { // Main network // - AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse"); - AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard"); + mouseEventSource = new AwtMouseEventSource("mouse"); + keyEventSource = new AwtKeyEventSource("keyboard"); // Subscribe packet sender to various events canvas.addMouseListener(mouseEventSource); @@ -390,4 +393,12 @@ public class RdpClient extends PipelineImpl { link("client_x224_data_queue", "client_tpkt_queue", "client_tpkt_queue< queue"); } + + public AwtMouseEventSource getMouseEventSource() { + return mouseEventSource; + } + + public AwtKeyEventSource getKeyEventSource() { + return keyEventSource; + } } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java index f2b19e1af49..2d1e8fca6c3 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java @@ -343,7 +343,7 @@ public class AwtRdpKeyboardAdapter extends BaseElement { default: System.err.println("Key is not mapped: " + event + "."); - return 57; // Space + return event.getKeyCode(); } } diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index bc780a70fb5..5d0b3bc9565 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -44,6 +44,11 @@ cloud-utils ${project.version}
+ + rdpclient + cloudstack-service-console-proxy-rdpclient + ${project.version} + diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java index f889cdbf05b..02fda6424be 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java @@ -196,8 +196,8 @@ public class ConsoleProxy { Object result; try { result = - authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), - param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); + authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), + param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); } catch (IllegalAccessException e) { s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + param.getClientTag(), e); authResult.setSuccess(false); @@ -407,7 +407,7 @@ public class ConsoleProxy { synchronized (connectionMap) { viewer = connectionMap.get(clientKey); if (viewer == null) { - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); s_logger.info("Added viewer object " + viewer); @@ -418,7 +418,7 @@ public class ConsoleProxy { viewer.initClient(param); } else if (!param.getClientHostPassword().equals(viewer.getClientHostPassword())) { s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.getClientHostPassword() + ", sid in request: " + - param.getClientHostPassword()); + param.getClientHostPassword()); viewer.initClient(param); } } @@ -442,7 +442,7 @@ public class ConsoleProxy { ConsoleProxyClient viewer = connectionMap.get(clientKey); if (viewer == null) { authenticationExternally(param); - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); @@ -457,7 +457,7 @@ public class ConsoleProxy { } if (param.getClientHostPassword() == null || param.getClientHostPassword().isEmpty() || - !param.getClientHostPassword().equals(viewer.getClientHostPassword())) + !param.getClientHostPassword().equals(viewer.getClientHostPassword())) throw new AuthenticationException("Cannot use the existing viewer " + viewer + ": bad sid"); if (!viewer.isFrontEndAlive()) { @@ -479,6 +479,14 @@ public class ConsoleProxy { } } + private static ConsoleProxyClient getClient(ConsoleProxyClientParam param) { + if (param.getHypervHost() != null) { + return new ConsoleProxyRdpClient(); + } else { + return new ConsoleProxyVncClient(); + } + } + public static void removeViewer(ConsoleProxyClient viewer) { synchronized (connectionMap) { for (Map.Entry entry : connectionMap.entrySet()) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java index 18d97d250af..fa0bd06c09e 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java @@ -80,6 +80,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { String console_url = queryMap.get("consoleurl"); String console_host_session = queryMap.get("sessionref"); String vm_locale = queryMap.get("locale"); + String hypervHost = queryMap.get("hypervHost"); + String username = queryMap.get("username"); + String password = queryMap.get("password"); if (tag == null) tag = ""; @@ -128,6 +131,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { param.setClientTunnelUrl(console_url); param.setClientTunnelSession(console_host_session); param.setLocale(vm_locale); + param.setHypervHost(hypervHost); + param.setUsername(username); + param.setPassword(password); viewer = ConsoleProxy.getAjaxVncViewer(param, ajaxSessionIdStr); } catch (Exception e) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java index a04dd306960..e62ac4531b9 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java @@ -33,6 +33,10 @@ public class ConsoleProxyClientParam { private String locale; private String ajaxSessionId; + private String hypervHost; + private String username; + private String password; + public ConsoleProxyClientParam() { clientHostPort = 0; } @@ -94,7 +98,7 @@ public class ConsoleProxyClientParam { } public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { @@ -102,7 +106,7 @@ public class ConsoleProxyClientParam { } public String getLocale() { - return this.locale; + return locale; } public void setLocale(String locale) { @@ -115,4 +119,28 @@ public class ConsoleProxyClientParam { return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String hypervHost) { + this.hypervHost = hypervHost; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index 7811d5030cf..51a703ae4b4 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -54,14 +54,29 @@ public class ConsoleProxyHttpHandlerHelper { // make sure we get information from token only guardUserInput(map); if (param != null) { - if (param.getClientHostAddress() != null) + if (param.getClientHostAddress() != null) { + s_logger.debug("decode token. host: " + param.getClientHostAddress()); map.put("host", param.getClientHostAddress()); - if (param.getClientHostPort() != 0) + } else { + s_logger.error("decode token. host info is not found!"); + } + if (param.getClientHostPort() != 0) { + s_logger.debug("decode token. port: " + param.getClientHostPort()); map.put("port", String.valueOf(param.getClientHostPort())); - if (param.getClientTag() != null) + } else { + s_logger.error("decode token. port info is not found!"); + } + if (param.getClientTag() != null) { + s_logger.debug("decode token. tag: " + param.getClientTag()); map.put("tag", param.getClientTag()); - if (param.getClientHostPassword() != null) + } else { + s_logger.error("decode token. tag info is not found!"); + } + if (param.getClientHostPassword() != null) { map.put("sid", param.getClientHostPassword()); + } else { + s_logger.error("decode token. sid info is not found!"); + } if (param.getClientTunnelUrl() != null) map.put("consoleurl", param.getClientTunnelUrl()); if (param.getClientTunnelSession() != null) @@ -70,6 +85,14 @@ public class ConsoleProxyHttpHandlerHelper { map.put("ticket", param.getTicket()); if (param.getLocale() != null) map.put("locale", param.getLocale()); + if (param.getHypervHost() != null) + map.put("hypervHost", param.getHypervHost()); + if (param.getUsername() != null) + map.put("username", param.getUsername()); + if (param.getPassword() != null) + map.put("password", param.getPassword()); + } else { + s_logger.error("Unable to decode token"); } } else { // we no longer accept information from parameter other than token @@ -88,5 +111,8 @@ public class ConsoleProxyHttpHandlerHelper { map.remove("sessionref"); map.remove("ticket"); map.remove("locale"); + map.remove("hypervHost"); + map.remove("username"); + map.remove("password"); } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java new file mode 100644 index 00000000000..d5a3fcd3639 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java @@ -0,0 +1,322 @@ +// 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.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.apache.log4j.Logger; + +import rdpclient.RdpClient; +import streamer.Pipeline; +import streamer.PipelineImpl; +import streamer.SocketWrapper; +import streamer.apr.AprSocketWrapperImpl; +import streamer.ssl.SSLState; + +import com.cloud.consoleproxy.rdp.KeysymToKeycode; +import com.cloud.consoleproxy.rdp.RdpBufferedImageCanvas; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.AwtKeyEventSource; +import common.AwtMouseEventSource; +import common.ScreenDescription; +import common.SizeChangeListener; + +public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { + + private static final Logger s_logger = Logger.getLogger(ConsoleProxyRdpClient.class); + + private static final int SHIFT_KEY_MASK = 64; + private static final int CTRL_KEY_MASK = 128; + private static final int META_KEY_MASK = 256; + private static final int ALT_KEY_MASK = 512; + + private RdpClient _client; + private ScreenDescription _screen; + private SocketWrapper _socket = null; + private RdpBufferedImageCanvas _canvas = null; + + private Thread _worker; + private volatile boolean _workerDone = false; + + private AwtMouseEventSource _mouseEventSource = null; + private AwtKeyEventSource _keyEventSource = null; + + public RdpBufferedImageCanvas getCanvas() { + return _canvas; + } + + public void setCanvas(RdpBufferedImageCanvas canvas) { + _canvas = canvas; + } + + @Override + public void onClientConnected() { + // TODO Auto-generated method stub + } + + @Override + public void onClientClose() { + s_logger.info("Received client close indication. remove viewer from map."); + ConsoleProxy.removeViewer(this); + } + + @Override + public boolean isHostConnected() { + //FIXME + return true; + } + + @Override + public boolean isFrontEndAlive() { + if (_socket != null) { + if (_workerDone || System.currentTimeMillis() - getClientLastFrontEndActivityTime() > ConsoleProxy.VIEWER_LINGER_SECONDS * 1000) { + s_logger.info("Front end has been idle for too long"); + _socket.shutdown(); + return false; + } else { + return true; + } + } else { + return false; + } + } + + @Override + public void sendClientRawKeyboardEvent(InputEventType event, int code, int modifiers) { + if (_client == null) + return; + + updateFrontEndActivityTime(); + + KeyEvent keyEvent = map(event, code, modifiers); + switch (event) { + case KEY_DOWN: + _keyEventSource.keyPressed(keyEvent); + break; + + case KEY_UP: + _keyEventSource.keyReleased(keyEvent); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + } + + private KeyEvent map(InputEventType event, int code, int modifiers) { + int keycode = KeysymToKeycode.getKeycode(code); + char keyChar = (char)keycode; + + KeyEvent keyEvent = null; + int modifier = mapModifier(modifiers); + + switch (event) { + case KEY_DOWN: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_UP: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + return keyEvent; + } + + @Override + public void sendClientMouseEvent(InputEventType event, int x, int y, int code, int modifiers) { + if (_client == null) + return; + updateFrontEndActivityTime(); + + int mousecode = mapMouseButton(code); + + if (event == InputEventType.MOUSE_DOWN) { + _mouseEventSource.mousePressed(new MouseEvent(_canvas, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), mapMouseDownModifier(code, modifiers), x, y, 1, false, + mousecode)); + } + + if (event == InputEventType.MOUSE_UP) { + _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), mapMouseUpModifier(code, modifiers), x, y, 1, false, + mousecode))); + } + + if (event == InputEventType.MOUSE_MOVE) { + _mouseEventSource.mouseMoved(new MouseEvent(_canvas, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), mapModifier(modifiers), x, y, 0, false)); + } + } + + public int mapMouseDownModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_DOWN_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_DOWN_MASK; + default: + } + return mod; + } + + public int mapMouseUpModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_MASK; + default: + } + return mod; + } + + private int mapModifier(int modifiers) { + int mod = 0; + + if ((modifiers & SHIFT_KEY_MASK) != 0) + mod = mod | InputEvent.SHIFT_DOWN_MASK; + + if ((modifiers & CTRL_KEY_MASK) != 0) + mod = mod | InputEvent.CTRL_DOWN_MASK; + + if ((modifiers & META_KEY_MASK) != 0) + mod = mod | InputEvent.META_DOWN_MASK; + + if ((modifiers & ALT_KEY_MASK) != 0) + mod = mod | InputEvent.ALT_DOWN_MASK; + + return mod; + } + + public int mapMouseButton(int code) { + switch (code) { + case 0: + return MouseEvent.BUTTON1; + case 2: + return MouseEvent.BUTTON3; + default: + return MouseEvent.BUTTON2; + } + + } + + @Override + public void initClient(final ConsoleProxyClientParam param) { + _workerDone = false; + + int canvasWidth = 1024; + int canvasHeight = 768; + setClientParam(param); + + final String host = param.getHypervHost(); + final String password = param.getPassword(); + final String instanceId = param.getClientHostAddress(); + final int port = param.getClientHostPort(); + + _screen = new ScreenDescription(); + _canvas = new RdpBufferedImageCanvas(this, canvasWidth, canvasHeight); + onFramebufferSizeChange(canvasWidth, canvasHeight); + + _screen.addSizeChangeListener(new SizeChangeListener() { + @Override + public void sizeChanged(int width, int height) { + if (_canvas != null) { + _canvas.setCanvasSize(width, height); + } + } + }); + + final SSLState sslState = new SSLState(); + + final String username = param.getUsername(); + String name = null; + String domain = null; + if (username.contains("\\")) { + String[] tokens = username.split("\\\\"); + name = tokens[1]; + domain = tokens[0]; + } else { + name = username; + domain = "Workgroup"; + } + + _client = new RdpClient("client", host, domain, name, password, instanceId, _screen, _canvas, + sslState); + + _mouseEventSource = _client.getMouseEventSource(); + _keyEventSource = _client.getKeyEventSource(); + + _worker = new Thread(new Runnable() { + @Override + public void run() { + _socket = new AprSocketWrapperImpl("socket", sslState); + Pipeline pipeline = new PipelineImpl("Client"); + pipeline.add(_socket, _client); + pipeline.link("socket", _client.getId(), "socket"); + pipeline.validate(); + + InetSocketAddress address = new InetSocketAddress(host, port); + ConsoleProxy.ensureRoute(host); + + try { + // Connect socket to remote server and run main loop(s) + _socket.connect(address); + } catch (IOException e) { + e.printStackTrace(); + } finally { + shutdown(); + } + + s_logger.info("Receiver thread stopped."); + _workerDone = true; + } + }); + _worker.setDaemon(true); + _worker.start(); + } + + @Override + public void closeClient() { + _workerDone = true; + shutdown(); + } + + @Override + protected FrameBufferCanvas getFrameBufferCavas() { + return _canvas; + } + + protected void shutdown() { + if (_socket != null) + _socket.shutdown(); + } +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java new file mode 100644 index 00000000000..f13dfe6c419 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java @@ -0,0 +1,138 @@ +// 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.rdp; + +import java.awt.event.KeyEvent; + +public class KeysymToKeycode { + + // some of this keymap is taken from http://openwonderland.googlecode.com/svn/trunk/modules/foundation/xremwin/src/classes/org/jdesktop/wonderland/modules/xremwin/client/KeycodeToKeysym.java + private final static int[][] map = { + /* XK_BackSpace */{0xFF08, KeyEvent.VK_BACK_SPACE}, + /* XK_Tab */{0xFF09, KeyEvent.VK_TAB}, + /* XK_Clear */{0xFF0B, KeyEvent.VK_CLEAR}, + /* XK_Return */{0xFF0D, KeyEvent.VK_ENTER}, + /* XK_Pause */{0xFF13, KeyEvent.VK_PAUSE}, + /* XK_Scroll_Lock */{0xFF14, KeyEvent.VK_SCROLL_LOCK}, + /* XK_Escape */{0xFF1B, KeyEvent.VK_ESCAPE}, + /* XK_Delete */{0xFFFF, KeyEvent.VK_DELETE}, + /* XK_Home */{0xFF50, KeyEvent.VK_HOME}, + /* XK_Left */{0xFF51, KeyEvent.VK_LEFT}, + /* XK_Up */{0xFF52, KeyEvent.VK_UP}, + /* XK_Right */{0xFF53, KeyEvent.VK_RIGHT}, + /* XK_Down */{0xFF54, KeyEvent.VK_DOWN}, + /* XK_Page_Up */{0xFF55, KeyEvent.VK_PAGE_UP}, + /* XK_Page_Down */{0xFF56, KeyEvent.VK_PAGE_DOWN}, + /* XK_End */{0xFF57, KeyEvent.VK_END}, + /* XK_Print */{0xFF61, KeyEvent.VK_PRINTSCREEN}, + /* XK_Insert */{0xFF63, KeyEvent.VK_INSERT}, + /* XK_Undo */{0xFF65, KeyEvent.VK_UNDO}, + /* XK_Find */{0xFF68, KeyEvent.VK_FIND}, + /* XK_Cancel */{0xFF69, KeyEvent.VK_CANCEL}, + /* XK_Help */{0xFF6A, KeyEvent.VK_HELP}, + /* XK_Mode_switch */{0xFF7E, KeyEvent.VK_MODECHANGE}, + /* XK_Num_Lock */{0xFF7F, KeyEvent.VK_NUM_LOCK}, + /* XK_F1 */{0xFFBE, KeyEvent.VK_F1}, + /* XK_F2 */{0xFFBF, KeyEvent.VK_F2}, + /* XK_F3 */{0xFFC0, KeyEvent.VK_F3}, + /* XK_F4 */{0xFFC1, KeyEvent.VK_F4}, + /* XK_F5 */{0xFFC2, KeyEvent.VK_F5}, + /* XK_F6 */{0xFFC3, KeyEvent.VK_F6}, + /* XK_F7 */{0xFFC4, KeyEvent.VK_F7}, + /* XK_F8 */{0xFFC5, KeyEvent.VK_F8}, + /* XK_F9 */{0xFFC6, KeyEvent.VK_F9}, + /* XK_F10 */{0xFFC7, KeyEvent.VK_F10}, + /* XK_F11 */{0xFFC8, KeyEvent.VK_F11}, + /* XK_F12 */{0xFFC9, KeyEvent.VK_F12}, + /* XK_F13 */{0xFFCA, KeyEvent.VK_F13}, + /* XK_F14 */{0xFFCB, KeyEvent.VK_F14}, + /* XK_F15 */{0xFFCC, KeyEvent.VK_F15}, + /* XK_F16 */{0xFFCD, KeyEvent.VK_F16}, + /* XK_F17 */{0xFFCE, KeyEvent.VK_F17}, + /* XK_F18 */{0xFFCF, KeyEvent.VK_F18}, + /* XK_F19 */{0xFFD0, KeyEvent.VK_F19}, + /* XK_F20 */{0xFFD1, KeyEvent.VK_F20}, + /* XK_F21 */{0xFFD2, KeyEvent.VK_F21}, + /* XK_F22 */{0xFFD3, KeyEvent.VK_F22}, + /* XK_F23 */{0xFFD4, KeyEvent.VK_F23}, + /* XK_F24 */{0xFFD5, KeyEvent.VK_F24}, + /* XK_Shift_L */{0xFFE1, KeyEvent.VK_SHIFT}, + /* XK_Control_L */{0xFFE3, KeyEvent.VK_CONTROL}, + /* XK_Caps_Lock */{0xFFE5, KeyEvent.VK_CAPS_LOCK}, + /* XK_Meta_L */{0xFFE7, KeyEvent.VK_META}, + /* XK_Alt_L */{0xFFE9, KeyEvent.VK_ALT}, + /* XK_a */{0x0061, KeyEvent.VK_A}, + /* XK_b */{0x0062, KeyEvent.VK_B}, + /* XK_c */{0x0063, KeyEvent.VK_C}, + /* XK_d */{0x0064, KeyEvent.VK_D}, + /* XK_e */{0x0065, KeyEvent.VK_E}, + /* XK_f */{0x0066, KeyEvent.VK_F}, + /* XK_g */{0x0067, KeyEvent.VK_G}, + /* XK_h */{0x0068, KeyEvent.VK_H}, + /* XK_i */{0x0069, KeyEvent.VK_I}, + /* XK_j */{0x006a, KeyEvent.VK_J}, + /* XK_k */{0x006b, KeyEvent.VK_K}, + /* XK_l */{0x006c, KeyEvent.VK_L}, + /* XK_m */{0x006d, KeyEvent.VK_M}, + /* XK_n */{0x006e, KeyEvent.VK_N}, + /* XK_o */{0x006f, KeyEvent.VK_O}, + /* XK_p */{0x0070, KeyEvent.VK_P}, + /* XK_q */{0x0071, KeyEvent.VK_Q}, + /* XK_r */{0x0072, KeyEvent.VK_R}, + /* XK_s */{0x0073, KeyEvent.VK_S}, + /* XK_t */{0x0074, KeyEvent.VK_T}, + /* XK_u */{0x0075, KeyEvent.VK_U}, + /* XK_v */{0x0076, KeyEvent.VK_V}, + /* XK_w */{0x0077, KeyEvent.VK_W}, + /* XK_x */{0x0078, KeyEvent.VK_X}, + /* XK_y */{0x0079, KeyEvent.VK_Y}, + /* XK_z */{0x007a, KeyEvent.VK_Z}, + {0x0060, KeyEvent.VK_BACK_QUOTE}, + {0x007e, KeyEvent.VK_BACK_QUOTE}, + {0x0021, KeyEvent.VK_1}, + {0x0040, KeyEvent.VK_2}, + {0x0023, KeyEvent.VK_3}, + {0x0024, KeyEvent.VK_4}, + {0x0025, KeyEvent.VK_5}, + {0x005e, KeyEvent.VK_6}, + {0x0026, KeyEvent.VK_7}, + {0x002A, KeyEvent.VK_8}, + {0x0028, KeyEvent.VK_9}, + {0x0029, KeyEvent.VK_0}, + {0x005f, KeyEvent.VK_MINUS}, + {0x002b, KeyEvent.VK_EQUALS}, + {0x007b, KeyEvent.VK_OPEN_BRACKET}, + {0x007d, KeyEvent.VK_CLOSE_BRACKET}, + {0x007c, KeyEvent.VK_BACK_SLASH}, + {0x003a, KeyEvent.VK_SEMICOLON}, + {0x0027, KeyEvent.VK_QUOTE}, + {0x0022, KeyEvent.VK_QUOTE}, + {0x003c, KeyEvent.VK_COMMA}, + {0x003e, KeyEvent.VK_PERIOD}, + {0x003f, KeyEvent.VK_SLASH}, + }; + + public static int getKeycode(int keysym) { + for (int i = 0; i < (map.length); i++) { + if (map[i][0] == keysym) { + return map[i][1]; + } + } + return keysym; + } + +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java new file mode 100644 index 00000000000..4214574a7e5 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java @@ -0,0 +1,103 @@ +// 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.rdp; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.List; + +import com.cloud.consoleproxy.ConsoleProxyRdpClient; +import com.cloud.consoleproxy.util.ImageHelper; +import com.cloud.consoleproxy.util.TileInfo; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.BufferedImageCanvas; + +public class RdpBufferedImageCanvas extends BufferedImageCanvas implements FrameBufferCanvas { + /** + * + */ + private static final long serialVersionUID = 1L; + + private final ConsoleProxyRdpClient _rdpClient; + + public RdpBufferedImageCanvas(ConsoleProxyRdpClient client, int width, int height) { + super(width, height); + _rdpClient = client; + } + + @Override + public Image getFrameBufferScaledImage(int width, int height) { + if (offlineImage != null) + return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); + return null; + } + + @Override + public byte[] getFrameBufferJpeg() { + int width = offlineImage.getWidth(); + int height = offlineImage.getHeight(); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + synchronized (offlineImage) { + g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null); + g.dispose(); + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + + return imgBits; + } + + @Override + public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight) { + int width = Math.max(tileWidth, tileWidth * tileList.size()); + + BufferedImage bufferedImage = new BufferedImage(width, tileHeight, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + + synchronized (offlineImage) { + int i = 0; + for (TileInfo tile : tileList) { + Rectangle rc = tile.getTileRect(); + g.drawImage(offlineImage, i * tileWidth, 0, i * tileWidth + rc.width, rc.height, rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); + i++; + } + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + return imgBits; + } + + @Override + public void updateFrameBuffer(int x, int y, int w, int h) { + _rdpClient.onFramebufferUpdate(x, y, w, h); + } + +} diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 30722e2fdd0..3d994438d98 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1716,7 +1716,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S parent += File.separator; } String absoluteTemplatePath = parent + relativeTemplatePath; - File tmpltParent = new File(absoluteTemplatePath).getParentFile(); + + File tmpltParent; + if(absoluteTemplatePath.endsWith(String.valueOf(obj.getId()))) { + tmpltParent = new File(absoluteTemplatePath); + } else { + tmpltParent = new File(absoluteTemplatePath).getParentFile(); + } + String details = null; if (!tmpltParent.exists()) { details = "template parent directory " + tmpltParent.getName() + " doesn't exist"; diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index e14f0dac6c1..fcf9b9fcc6e 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -173,7 +173,7 @@ CREATE VIEW `cloud`.`disk_offering_view` AS DROP VIEW IF EXISTS `cloud`.`service_offering_view`; CREATE VIEW `cloud`.`service_offering_view` AS - select + select service_offering.id, disk_offering.uuid, disk_offering.name, @@ -212,10 +212,10 @@ CREATE VIEW `cloud`.`service_offering_view` AS `cloud`.`domain` ON disk_offering.domain_id = domain.id where disk_offering.state='Active'; - + DROP VIEW IF EXISTS `cloud`.`template_view`; CREATE VIEW `cloud`.`template_view` AS - select + select vm_template.id, vm_template.uuid, vm_template.unique_name, @@ -257,7 +257,7 @@ CREATE VIEW `cloud`.`template_view` AS domain.path domain_path, projects.id project_id, projects.uuid project_uuid, - projects.name project_name, + projects.name project_name, data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, @@ -287,23 +287,23 @@ CREATE VIEW `cloud`.`template_view` AS from `cloud`.`vm_template` inner join - `cloud`.`guest_os` ON guest_os.id = vm_template.guest_os_id + `cloud`.`guest_os` ON guest_os.id = vm_template.guest_os_id inner join `cloud`.`account` ON account.id = vm_template.account_id inner join `cloud`.`domain` ON domain.id = account.domain_id left join - `cloud`.`projects` ON projects.project_account_id = account.id + `cloud`.`projects` ON projects.project_account_id = account.id left join - `cloud`.`vm_template_details` ON vm_template_details.template_id = vm_template.id + `cloud`.`vm_template_details` ON vm_template_details.template_id = vm_template.id left join - `cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id + `cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id left join `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' left join - `cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id + `cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id left join - `cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id AND template_store_ref.store_id is NULL AND template_zone_ref.removed is null + `cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id AND template_store_ref.store_id is NULL AND template_zone_ref.removed is null left join `cloud`.`data_center` ON (image_store.data_center_id = data_center.id OR template_zone_ref.zone_id = data_center.id) left join @@ -420,7 +420,7 @@ CREATE VIEW `cloud`.`volume_view` AS `cloud`.`async_job` ON async_job.instance_id = volumes.id and async_job.instance_type = 'Volume' and async_job.job_status = 0; - + DROP VIEW IF EXISTS `cloud`.`storage_pool_view`; CREATE VIEW `cloud`.`storage_pool_view` AS select @@ -896,3 +896,206 @@ ALTER TABLE `cloud`.`vm_instance` DROP COLUMN `speed`; INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) VALUES (UUID(), 'VMware', '5.5', 128, 0, 13, 32, 1, 1); +ALTER TABLE `cloud`.`network_acl_item` modify `cidr` varchar(2048); + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "api.servlet.endpoint", "http://localhost:8080/client/api?", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", "http://localhost:8080/client/api?", NULL,NULL,0); + +DROP VIEW IF EXISTS `cloud`.`user_vm_view`; +CREATE VIEW `cloud`.`user_vm_view` AS + select + vm_instance.id id, + vm_instance.name name, + user_vm.display_name display_name, + user_vm.user_data user_data, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + instance_group.id instance_group_id, + instance_group.uuid instance_group_uuid, + instance_group.name instance_group_name, + vm_instance.uuid uuid, + vm_instance.last_host_id last_host_id, + vm_instance.vm_type type, + vm_instance.limit_cpu_use limit_cpu_use, + vm_instance.created created, + vm_instance.state state, + vm_instance.removed removed, + vm_instance.ha_enabled ha_enabled, + vm_instance.hypervisor_type hypervisor_type, + vm_instance.instance_name instance_name, + vm_instance.guest_os_id guest_os_id, + vm_instance.display_vm display_vm, + guest_os.uuid guest_os_uuid, + vm_instance.pod_id pod_id, + host_pod_ref.uuid pod_uuid, + vm_instance.private_ip_address private_ip_address, + vm_instance.private_mac_address private_mac_address, + vm_instance.vm_type vm_type, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + data_center.is_security_group_enabled security_group_enabled, + data_center.networktype data_center_type, + host.id host_id, + host.uuid host_uuid, + host.name host_name, + vm_template.id template_id, + vm_template.uuid template_uuid, + vm_template.name template_name, + vm_template.display_text template_display_text, + vm_template.enable_password password_enabled, + iso.id iso_id, + iso.uuid iso_uuid, + iso.name iso_name, + iso.display_text iso_display_text, + service_offering.id service_offering_id, + disk_offering.uuid service_offering_uuid, + Case + When (`cloud`.`service_offering`.`cpu` is null) then (`custom_cpu`.`value`) + Else ( `cloud`.`service_offering`.`cpu`) + End as `cpu`, + Case + When (`cloud`.`service_offering`.`speed` is null) then (`custom_speed`.`value`) + Else ( `cloud`.`service_offering`.`speed`) + End as `speed`, + Case + When (`cloud`.`service_offering`.`ram_size` is null) then (`custom_ram_size`.`value`) + Else ( `cloud`.`service_offering`.`ram_size`) + END as `ram_size`, + disk_offering.name service_offering_name, + storage_pool.id pool_id, + storage_pool.uuid pool_uuid, + storage_pool.pool_type pool_type, + volumes.id volume_id, + volumes.uuid volume_uuid, + volumes.device_id volume_device_id, + volumes.volume_type volume_type, + security_group.id security_group_id, + security_group.uuid security_group_uuid, + security_group.name security_group_name, + security_group.description security_group_description, + nics.id nic_id, + nics.uuid nic_uuid, + nics.network_id network_id, + nics.ip4_address ip_address, + nics.ip6_address ip6_address, + nics.ip6_gateway ip6_gateway, + nics.ip6_cidr ip6_cidr, + nics.default_nic is_default_nic, + nics.gateway gateway, + nics.netmask netmask, + nics.mac_address mac_address, + nics.broadcast_uri broadcast_uri, + nics.isolation_uri isolation_uri, + vpc.id vpc_id, + vpc.uuid vpc_uuid, + networks.uuid network_uuid, + networks.name network_name, + networks.traffic_type traffic_type, + networks.guest_type guest_type, + user_ip_address.id public_ip_id, + user_ip_address.uuid public_ip_uuid, + user_ip_address.public_ip_address public_ip_address, + ssh_keypairs.keypair_name keypair_name, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id, + affinity_group.id affinity_group_id, + affinity_group.uuid affinity_group_uuid, + affinity_group.name affinity_group_name, + affinity_group.description affinity_group_description, + vm_instance.dynamically_scalable dynamically_scalable, + all_details.name detail_name, + all_details.value detail_value + from + `cloud`.`user_vm` + inner join + `cloud`.`vm_instance` ON vm_instance.id = user_vm.id + and vm_instance.removed is NULL + inner join + `cloud`.`account` ON vm_instance.account_id = account.id + inner join + `cloud`.`domain` ON vm_instance.domain_id = domain.id + left join + `cloud`.`guest_os` ON vm_instance.guest_os_id = guest_os.id + left join + `cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`instance_group_vm_map` ON vm_instance.id = instance_group_vm_map.instance_id + left join + `cloud`.`instance_group` ON instance_group_vm_map.group_id = instance_group.id + left join + `cloud`.`data_center` ON vm_instance.data_center_id = data_center.id + left join + `cloud`.`host` ON vm_instance.host_id = host.id + left join + `cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id + left join + `cloud`.`vm_template` iso ON iso.id = user_vm.iso_id + left join + `cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id + left join + `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id + left join + `cloud`.`volumes` ON vm_instance.id = volumes.instance_id + left join + `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id + left join + `cloud`.`security_group_vm_map` ON vm_instance.id = security_group_vm_map.instance_id + left join + `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id + left join + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null + left join + `cloud`.`networks` ON nics.network_id = networks.id + left join + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null + left join + `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` as ssh_details ON ssh_details.vm_id = vm_instance.id + and ssh_details.name = 'SSH.PublicKey' + left join + `cloud`.`ssh_keypairs` ON ssh_keypairs.public_key = ssh_details.value + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = vm_instance.id + and resource_tags.resource_type = 'UserVm' + left join + `cloud`.`async_job` ON async_job.instance_id = vm_instance.id + and async_job.instance_type = 'VirtualMachine' + and async_job.job_status = 0 + left join + `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id + left join + `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id + left join + `cloud`.`user_vm_details` as all_details ON all_details.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_cpu`.`name` = 'CpuNumber'))) + left join + `cloud`.`user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_speed`.`name` = 'CpuSpeed'))) + left join + `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); + + diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 1b6a9ab420f..3fa34029fb7 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -24,6 +24,9 @@ SET foreign_key_checks = 0; ALTER TABLE `cloud`.`disk_offering` ADD `cache_mode` VARCHAR( 16 ) DEFAULT 'none' COMMENT 'The disk cache mode to use for disks created with this offering'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='150' WHERE hypervisor_version='6.1.0'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='500' WHERE hypervisor_version='6.2.0'; + DROP VIEW IF EXISTS `cloud`.`disk_offering_view`; CREATE VIEW `cloud`.`disk_offering_view` AS select @@ -443,4 +446,4 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); - +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; diff --git a/setup/db/templates.simulator.sql b/setup/db/templates.simulator.sql index 5f9b67d1f7e..25e91bd9c5f 100755 --- a/setup/db/templates.simulator.sql +++ b/setup/db/templates.simulator.sql @@ -16,7 +16,7 @@ -- under the License. -INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator'); -INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator'); +INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type, state) + VALUES (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator','Active'); +INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type,state) + VALUES (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator','Active'); diff --git a/setup/db/templates.sql b/setup/db/templates.sql index 20180f575e8..5b46c9aef2f 100755 --- a/setup/db/templates.sql +++ b/setup/db/templates.sql @@ -34,7 +34,7 @@ INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, VALUES (7, UUID(), 'centos53-x64', 'CentOS 5.3(64-bit) no GUI (vSphere)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/CentOS5.3-x86_64.ova', 'f6f881b7f2292948d8494db837fe0f47', 0, 'CentOS 5.3(64-bit) no GUI (vSphere)', 'OVA', 12, 1, 1, 'VMware', 1); INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (8, UUID(), 'routing-8', 'SystemVM Template (vSphere)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/templates/4.2/systemvmtemplate-4.2-vh7.ova', '8fde62b1089e5844a9cd3b9b953f9596', 0, 'SystemVM Template (vSphere)', 'OVA', 15, 0, 1, 'VMware' ); + VALUES (8, UUID(), 'routing-8', 'SystemVM Template (vSphere)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.3/systemvm64template-2014-01-14-master-vmware.ova', 'ef593a061f3b7594ab0bfd9b0ed0a0d4', 0, 'SystemVM Template (vSphere)', 'OVA', 15, 0, 1, 'VMware' ); INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) VALUES (9, UUID(), 'routing-9', 'SystemVM Template (HyperV)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.3/systemvm64template-2013-12-23-hyperv.vhd.bz2', '5df45ee6ebe1b703a8805f4e1f4d0818', 0, 'SystemVM Template (HyperV)', 'VHD', 15, 0, 1, 'Hyperv' ); diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index d6dc8f02031..df80a289c2d 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -135,7 +135,7 @@ get_boot_params() { virtualpc|hyperv) # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon #waiting for the hv_kvp_daemon to start up - #sleep 30 need to fix the race condition of hv_kvp_daemon and cloud-early-config + #sleep need to fix the race condition of hv_kvp_daemon and cloud-early-config sleep 5 cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline cat /dev/null > /var/opt/hyperv/.kvp_pool_0 @@ -1211,6 +1211,10 @@ start() { patch_log4j parse_cmd_line change_password + if [ "$hyp" == "hyperv" ]; then + # eject the systemvm.iso + eject + fi case $TYPE in router) [ "$NAME" == "" ] && NAME=router diff --git a/systemvm/patches/debian/config/root/bumpup_priority.sh b/systemvm/patches/debian/config/opt/cloud/bin/bumpup_priority.sh similarity index 100% rename from systemvm/patches/debian/config/root/bumpup_priority.sh rename to systemvm/patches/debian/config/opt/cloud/bin/bumpup_priority.sh diff --git a/systemvm/patches/debian/config/root/createIpAlias.sh b/systemvm/patches/debian/config/opt/cloud/bin/createIpAlias.sh similarity index 100% rename from systemvm/patches/debian/config/root/createIpAlias.sh rename to systemvm/patches/debian/config/opt/cloud/bin/createIpAlias.sh diff --git a/systemvm/patches/debian/config/root/deleteIpAlias.sh b/systemvm/patches/debian/config/opt/cloud/bin/deleteIpAlias.sh similarity index 100% rename from systemvm/patches/debian/config/root/deleteIpAlias.sh rename to systemvm/patches/debian/config/opt/cloud/bin/deleteIpAlias.sh diff --git a/systemvm/patches/debian/config/root/dnsmasq.sh b/systemvm/patches/debian/config/opt/cloud/bin/dnsmasq.sh similarity index 100% rename from systemvm/patches/debian/config/root/dnsmasq.sh rename to systemvm/patches/debian/config/opt/cloud/bin/dnsmasq.sh diff --git a/systemvm/patches/debian/config/root/edithosts.sh b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh similarity index 100% rename from systemvm/patches/debian/config/root/edithosts.sh rename to systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh diff --git a/systemvm/patches/debian/config/root/firewallRule_egress.sh b/systemvm/patches/debian/config/opt/cloud/bin/firewall_egress.sh similarity index 100% rename from systemvm/patches/debian/config/root/firewallRule_egress.sh rename to systemvm/patches/debian/config/opt/cloud/bin/firewall_egress.sh diff --git a/systemvm/patches/debian/config/root/firewall_rule.sh b/systemvm/patches/debian/config/opt/cloud/bin/firewall_ingress.sh similarity index 100% rename from systemvm/patches/debian/config/root/firewall_rule.sh rename to systemvm/patches/debian/config/opt/cloud/bin/firewall_ingress.sh diff --git a/systemvm/patches/debian/config/root/firewall.sh b/systemvm/patches/debian/config/opt/cloud/bin/firewall_nat.sh similarity index 100% rename from systemvm/patches/debian/config/root/firewall.sh rename to systemvm/patches/debian/config/opt/cloud/bin/firewall_nat.sh diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh index ae2d7e4296c..2a9d7807743 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh @@ -254,10 +254,11 @@ remove_first_ip() { if [ $? -gt 0 -a $? -ne 2 ] then remove_routing $1 + sudo ip link set $ethDev down return 1 fi remove_routing $1 - + sudo ip link set $ethDev down return $? } diff --git a/systemvm/patches/debian/config/root/loadbalancer.sh b/systemvm/patches/debian/config/opt/cloud/bin/loadbalancer.sh similarity index 100% rename from systemvm/patches/debian/config/root/loadbalancer.sh rename to systemvm/patches/debian/config/opt/cloud/bin/loadbalancer.sh diff --git a/systemvm/patches/debian/config/root/userdata.py b/systemvm/patches/debian/config/root/userdata.py deleted file mode 100644 index cc130a55dd7..00000000000 --- a/systemvm/patches/debian/config/root/userdata.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/python -# 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. - - - -import sys -import base64 -import string -import os -import tempfile -from subprocess import call - -def vm_data(args): - - router_ip = args.pop('routerIP') - vm_ip = args.pop('vmIP') - - for pair in args: - pairList = pair.split(',') - vmDataFolder = pairList[0] - vmDataFile = pairList[1] - vmDataValue = args[pair] - cmd = ["/bin/bash", "/root/userdata.sh", "-v", vm_ip, "-F", vmDataFolder, "-f", vmDataFile] - - fd = None - tmp_path = None - - try: - fd,tmp_path = tempfile.mkstemp() - tmpfile = open(tmp_path, 'w') - - if (vmDataFolder == "userdata" and vmDataValue != "none"): - vmDataValue = base64.urlsafe_b64decode(vmDataValue) - - if vmDataValue != "none": - tmpfile.write(vmDataValue) - - tmpfile.close() - cmd.append("-d") - cmd.append(tmp_path) - except: - if fd !=None: - os.close(fd) - os.remove(tmp_path) - return '' - - try: - call(cmd) - txt = 'success' - except: - txt = '' - - if (fd != None): - os.close(fd) - os.remove(tmp_path) - - return txt - -def parseFileData(fileName): - args = {} - fd = open(fileName) - - line = fd.readline() - while (line != ""): - key=string.strip(line[:], '\n') - if (key == ""): - break - - line=fd.readline() - val=string.strip(line[:], '\n') - args[key]=val - line=fd.readline() - return args - -if __name__ == "__main__": - vm_data(parseFileData("/tmp/" + sys.argv[1])) - diff --git a/systemvm/patches/debian/config/root/userdata.sh b/systemvm/patches/debian/config/root/userdata.sh deleted file mode 100644 index 83ecdfd0e6a..00000000000 --- a/systemvm/patches/debian/config/root/userdata.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - - - -source /root/func.sh - -lock="biglock" -#default timeout value is 30 mins as userdata command is not synchronized on agent side any more, -#and multiple commands can be sent to the same VR at a time -locked=$(getLockFile $lock 1800) -if [ "$locked" != "1" ] -then - exit 1 -fi - -usage() { - printf "Usage: %s: -v -F -f -d \n" $(basename $0) >&2 - unlock_exit 2 $lock $locked -} - -set -x - -PORT=3922 - -create_htaccess() { - local vmIp=$1 - local folder=$2 - local file=$3 - - local result=0 - - entry="RewriteRule ^$file$ ../$folder/%{REMOTE_ADDR}/$file [L,NC,QSA]" - htaccessFolder="/var/www/html/latest" - htaccessFile=$htaccessFolder/.htaccess - mkdir -p $htaccessFolder - touch $htaccessFile - -# Fixed the issue with checking if record exists, rewrote the else/if logic, reference issue CLOUDSTACK-2053 - - if ! grep -Fq "$entry" $htaccessFile - then - echo -e $entry >> $htaccessFile; - result=$? - fi - - entry="Options -Indexes\\nOrder Deny,Allow\\nDeny from all\\nAllow from $vmIp" - testentry="Allow from $vmIp" - htaccessFolder="/var/www/html/$folder/$vmIp" - htaccessFile=$htaccessFolder/.htaccess - if ! grep -Fq "$testentry" $htaccessFile - then - mkdir -p $htaccessFolder - echo -e $entry > $htaccessFile - result=$? - fi - - -# Please reference issue CLOUDSTACK-2053, added to fix boto/cloud-init integration - - htaccessFileNoIP="/var/www/html/latest/.htaccess" - metadataentry1='RewriteRule ^meta-data/$ ../metadata/%{REMOTE_ADDR}/meta-data [L,NC,QSA]' - metadataentry2='RewriteRule ^meta-data/(.*)$ ../metadata/%{REMOTE_ADDR}/$1 [L,NC,QSA]' - if ! grep -Fq "$metadataentry1" $htaccessFileNoIP - then - echo -e "$metadataentry1" >> $htaccessFileNoIP; - fi - - if ! grep -Fq "$metadataentry2" $htaccessFileNoIP - then - echo -e "$metadataentry2" >> $htaccessFileNoIP; - fi - - return $result -} - -copy_vm_data_file() { - local vmIp=$1 - local folder=$2 - local file=$3 - local dataFile=$4 - - dest=/var/www/html/$folder/$vmIp/$file - metamanifest=/var/www/html/$folder/$vmIp/meta-data - chmod +r $dataFile - cp $dataFile $dest - chmod 644 $dest - touch $metamanifest - chmod 644 $metamanifest - if [ "$folder" == "metadata" ] || [ "$folder" == "meta-data" ] - then - sed -i '/$file/d' $metamanifest - echo $file >> $metamanifest - fi - return $? -} - -delete_vm_data_file() { - local domrIp=$1 - local vmIp=$2 - local folder=$3 - local file=$4 - - vmDataFilePath="/var/www/html/$folder/$vmIp/$file" - if [ -f $vmDataFilePath ]; then - rm -rf $vmDataFilePath - fi - return $? -} - -vmIp= -folder= -file= -dataFile= - -while getopts 'v:F:f:d:' OPTION -do - case $OPTION in - v) vmIp="$OPTARG" - ;; - F) folder="$OPTARG" - ;; - f) file="$OPTARG" - ;; - d) dataFile="$OPTARG" - ;; - ?) usage - unlock_exit 1 $lock $locked - ;; - esac -done - -[ "$vmIp" == "" ] || [ "$folder" == "" ] || [ "$file" == "" ] && usage -[ "$folder" != "userdata" ] && [ "$folder" != "metadata" ] && usage - -if [ "$dataFile" != "" ] -then - create_htaccess $vmIp $folder $file - - if [ $? -gt 0 ] - then - unlock_exit 1 $lock $locked - fi - - copy_vm_data_file $vmIp $folder $file $dataFile -else - delete_vm_data_file $vmIp $folder $file -fi - -unlock_exit $? $lock $locked diff --git a/systemvm/pom.xml b/systemvm/pom.xml index e8d43efb576..5de6452aa00 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -51,7 +51,6 @@ maven-assembly-plugin - 2.3 systemvm false @@ -71,7 +70,6 @@ maven-resources-plugin - 2.6 copy-resources @@ -102,7 +100,6 @@ maven-antrun-plugin - 1.7 build-cloud-scripts diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 61ee7936e67..2e8bc88d903 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -60,7 +60,7 @@ done vboxmanage modifyhd $hdd_uuid --compact # Start exporting -rm -fr dist *.ova *.vhd *.vdi *.qcow* *.bz2 +rm -fr dist *.ova *.vhd *.vdi *.qcow* *.bz2 *.vmdk *.ovf mkdir dist # Export for Xen @@ -92,14 +92,18 @@ echo "$appliance exported for KVM: dist/$appliance-$build_date-$branch-kvm.qcow2 vboxmanage clonehd $hdd_uuid $appliance-$build_date-$branch-vmware.vmdk --format VMDK bzip2 $appliance-$build_date-$branch-vmware.vmdk echo "$appliance exported for VMWare: dist/$appliance-$build_date-$branch-vmware.vmdk.bz2" -vboxmanage export $machine_uuid --output $appliance-$build_date-$branch-vmware.ova +vboxmanage export $machine_uuid --output $appliance-$build_date-$branch-vmware.ovf +mv $appliance-$build_date-$branch-vmware.ovf $appliance-$build_date-$branch-vmware.ovf-orig +java -cp convert Convert convert_ovf_vbox_to_esx.xslt $appliance-$build_date-$branch-vmware.ovf-orig $appliance-$build_date-$branch-vmware.ovf +tar -cf $appliance-$build_date-$branch-vmware.ova $appliance-$build_date-$branch-vmware.ovf $appliance-$build_date-$branch-vmware-disk1.vmdk +rm -f $appliance-$build_date-$branch-vmware.ovf $appliance-$build_date-$branch-vmware.ovf-orig $appliance-$build_date-$branch-vmware-disk1.vmdk echo "$appliance exported for VMWare: dist/$appliance-$build_date-$branch-vmware.ova" # Export for HyperV vboxmanage clonehd $hdd_uuid $appliance-$build_date-$branch-hyperv.vhd --format VHD -# HyperV doesn't support import a zipped image from S3 -#bzip2 $appliance-$build_date-$branch-hyperv.vhd +# HyperV doesn't support import a zipped image from S3, but we create a zipped version to save space on the jenkins box +zip $appliance-$build_date-$branch-hyperv.vhd.zip $appliance-$build_date-$branch-hyperv.vhd echo "$appliance exported for HyperV: dist/$appliance-$build_date-$branch-hyperv.vhd" -mv *-hyperv.vhd *.bz2 *.ova dist/ +mv *-hyperv.vhd *-hyperv.vhd.zip *.bz2 *.ova dist/ diff --git a/tools/appliance/convert/Convert.class b/tools/appliance/convert/Convert.class new file mode 100644 index 00000000000..3f243418fff Binary files /dev/null and b/tools/appliance/convert/Convert.class differ diff --git a/tools/appliance/convert/Convert.java b/tools/appliance/convert/Convert.java new file mode 100644 index 00000000000..21b20fc47b2 --- /dev/null +++ b/tools/appliance/convert/Convert.java @@ -0,0 +1,36 @@ +// 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. + +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; + +public class Convert { + public static void main(String[] args) throws IOException, URISyntaxException, TransformerException { + TransformerFactory factory = TransformerFactory.newInstance(); + Source xslt = new StreamSource(new File(args[0])); + Transformer transformer = factory.newTransformer(xslt); + + Source text = new StreamSource(new File(args[1])); + transformer.transform(text, new StreamResult(new File(args[2]))); + } +} diff --git a/tools/appliance/convert_ovf_vbox_to_esx.xslt b/tools/appliance/convert_ovf_vbox_to_esx.xslt new file mode 100644 index 00000000000..a6c086d9ae1 --- /dev/null +++ b/tools/appliance/convert_ovf_vbox_to_esx.xslt @@ -0,0 +1,42 @@ + + + + + vmx-07 + + + + + scsiController0 + SCSI Controller + scsiController0 + + lsilogic + 6 + + + + + + + + + + diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 0ab994c8f8f..f36f5e4a7d5 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -193,15 +193,11 @@ ${basedir}/marvin python - deployAndRun.py - -c - ${resolved.userdir}/${marvin.config} - -t - /tmp/t.log - -r - /tmp/r.log - -f - ${resolved.basedir}/marvin/testSetupSuccess.py + deployAndRun.py + -c + ${resolved.userdir}/${marvin.config} + -d + ${resolved.basedir}/marvin/testSetupSuccess.py diff --git a/tools/transifex/.tx/config b/tools/transifex/.tx/config index 102a47e29d4..5e83db3ef0f 100644 --- a/tools/transifex/.tx/config +++ b/tools/transifex/.tx/config @@ -39,9 +39,11 @@ trans.de_DE = work-dir/messages_de_DE.properties trans.es = work-dir/messages_es.properties trans.fr_FR = work-dir/messages_fr_FR.properties trans.it_IT = work-dir/messages_it_IT.properties -trans.ja = work-dir/messages_ja.properties +trans.ja_JP = work-dir/messages_ja_JP.properties trans.ko_KR = work-dir/messages_ko_KR.properties trans.nb_NO = work-dir/messages_nb_NO.properties +trans.nl_NL = work-dir/messages_nl_NL.properties +trans.pl = work-dir/messages_pl.properties trans.pt_BR = work-dir/messages_pt_BR.properties trans.ru_RU = work-dir/messages_ru_RU.properties trans.zh_CN = work-dir/messages_zh_CN.properties diff --git a/tools/transifex/sync-transifex-ui.sh b/tools/transifex/sync-transifex-ui.sh index 9124ed6a633..8f24642413c 100755 --- a/tools/transifex/sync-transifex-ui.sh +++ b/tools/transifex/sync-transifex-ui.sh @@ -17,7 +17,7 @@ # under the License. SRCLANG=en -LIST_LANG="ar ca de_DE es fr_FR it_IT ja ko_KR nb_NO pt_BR ru_RU zh_CN" +LIST_LANG="ar ca de_DE es fr_FR it_IT ja_JP ko_KR nb_NO nl_NL pl pt_BR ru_RU zh_CN" DIRECTORY_RESOURCES="../../client/WEB-INF/classes/resources" WORKDIR="./work-dir" diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 18a88babc3e..993673bbd71 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7624,7 +7624,6 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal .multi-edit .range input { width: 35px; - margin-left: 6px; margin-right: 2px; position: relative; } diff --git a/ui/images/infrastructure-icons.png b/ui/images/infrastructure-icons.png index 5d35a8ed493..a589fc42dc2 100644 Binary files a/ui/images/infrastructure-icons.png and b/ui/images/infrastructure-icons.png differ diff --git a/ui/index.jsp b/ui/index.jsp index 7b8d8257b33..096747b10ac 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -71,7 +71,7 @@ diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index c83080cb0d1..646ffbf5b19 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -613,17 +613,17 @@ if (args.$wizard.find('input[name=compute-cpu-cores]').parent().parent().css('display') != 'none') { if (args.$wizard.find('input[name=compute-cpu-cores]').val().length > 0) { $.extend(deployVmData, { - 'customparameters[0].cpuNumber' : args.$wizard.find('input[name=compute-cpu-cores]').val() + 'details[0].cpuNumber' : args.$wizard.find('input[name=compute-cpu-cores]').val() }); } if (args.$wizard.find('input[name=compute-cpu]').val().length > 0) { $.extend(deployVmData, { - 'customparameters[0].cpuSpeed' : args.$wizard.find('input[name=compute-cpu]').val() + 'details[0].cpuSpeed' : args.$wizard.find('input[name=compute-cpu]').val() }); } if (args.$wizard.find('input[name=compute-memory]').val().length > 0) { $.extend(deployVmData, { - 'customparameters[0].memory' : args.$wizard.find('input[name=compute-memory]').val() + 'details[0].memory' : args.$wizard.find('input[name=compute-memory]').val() }); } } diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index d4a5482d84b..3b1931b862b 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -45,7 +45,16 @@ quiescevm: { label: 'label.quiesce.vm', isBoolean: true, - isChecked: false + isChecked: false, + isHidden: function(args) { + if (args.context.instances[0].hypervisor !== 'VMware') { + return true; + } + + args.form.fields.quiescevm.isChecked = true; + + return false; + } } } }, @@ -355,9 +364,9 @@ label: 'label.affinity.groups' }, { path: '_zone.hosts', - label: 'label.hosts', + label: 'label.host', preFilter: function(args) { - return isAdmin(); + return isAdmin() && args.context.instances[0].hostid; }, updateContext: function(args) { var instance = args.context.instances[0]; @@ -1525,17 +1534,17 @@ if (args.$form.find('.form-item[rel=cpuSpeed]').is(':visible')) { $.extend(data, { - 'customparameters[0].cpuSpeed': args.data.cpuSpeed + 'details[0].cpuSpeed': args.data.cpuSpeed }); } if (args.$form.find('.form-item[rel=cpuNumber]').is(':visible')) { $.extend(data, { - 'customparameters[0].cpuNumber': args.data.cpuNumber + 'details[0].cpuNumber': args.data.cpuNumber }); } if (args.$form.find('.form-item[rel=memory]').is(':visible')) { $.extend(data, { - 'customparameters[0].memory': args.data.memory + 'details[0].memory': args.data.memory }); } @@ -1789,6 +1798,16 @@ serviceofferingname: { label: 'label.compute.offering' }, + cpunumber: { + label: 'label.num.cpu.cores' + }, + cpuspeed: { + label: 'label.cpu.mhz' + }, + memory: { + label: 'label.memory.mb' + }, + haenable: { label: 'label.ha.enabled', converter: cloudStack.converters.toBooleanText diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 610b1bdc2dc..0aa5473117c 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -1615,6 +1615,10 @@ 'add-vm': { label: 'label.add.vms', addButton: true + }, + 'state' : { + edit: 'ignore', + label: 'label.state' } }, @@ -2222,7 +2226,11 @@ } } - if (ipAddress.vpcid || ipAddress.issourcenat) { + if (ipAddress.vpcid != null && ipAddress.issourcenat) { //don't show Configuration(ipRules) tab on VPC sourceNAT IP + disableIpRules = true; + } + + if (('vpc' in args.context) == false && ipAddress.vpcid != null) { //from Guest Network section, don't show Configuration(ipRules) tab on VPC IP disableIpRules = true; } @@ -2374,6 +2382,7 @@ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { + advSearchFields: null, // Not supported in dialogs right now due to display issues filters: false, subselect: { label: 'label.use.vm.ip', @@ -2386,6 +2395,10 @@ listAll: true }; + if (args.filterBy.search.value) { + data.keyword = args.filterBy.search.value; + } + var $tierSelect = $(".ui-dialog-content").find('.tier-select select'); // if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later @@ -2952,6 +2965,10 @@ 'add-rule': { label: 'label.add.rule', addButton: true + }, + 'state' : { + edit: 'ignore', + label: 'label.state' } }, @@ -3431,6 +3448,11 @@ 'add-vm': { label: 'label.add.vms', addButton: true + }, + + 'state' : { + edit: 'ignore', + label: 'label.state' } }, diff --git a/ui/scripts/plugins.js b/ui/scripts/plugins.js index afeae7c7eaf..82d92429a7d 100644 --- a/ui/scripts/plugins.js +++ b/ui/scripts/plugins.js @@ -98,15 +98,37 @@ } // Execute module - cloudStack[type][id]( - $.extend(true, {}, cloudStack.pluginAPI, { - pluginAPI: { - extend: function(api) { - cloudStack.pluginAPI[id] = api; + var target = cloudStack[type][id]; + + if ($.isArray(target)) { // Load additional JS includes + pluginTotal += target[0].length; + require( + $(target[0]).map(function(index, val) { + return basePath + val; + }).toArray(), + function() { + loadedPlugins = loadedPlugins + target[0].length; + target[1]( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } + } + }) + ); + }); + } else { + target( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } } - } - }) - ); + }) + ); + } if (pluginDictionary) { // Callback for extending the dictionary with new entries @@ -133,13 +155,16 @@ loadedPlugins = loadedPlugins + 1; - if (loadedPlugins === pluginTotal) { - $(window).trigger('cloudStack.pluginReady'); - } - loadCSS(css); }); } ); }); + + var loadTimer = setInterval(function() { + if (loadedPlugins === pluginTotal) { + clearInterval(loadTimer); + $(window).trigger('cloudStack.pluginReady'); + } + }, 100); }(jQuery, cloudStack, require)); diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index a6328503301..b9dc2f37767 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -1201,7 +1201,9 @@ var processPropertiesInImagestoreObject = function(jsonObj) { var url = jsonObj.url; //e.g. 'cifs://10.1.1.1/aaa/aaa2/aaa3?user=bbb&password=ccc&domain=ddd' var passwordIndex = url.indexOf('&password='); //38 var domainIndex = url.indexOf('&domain='); //51 - jsonObj.url = url.substring(0, passwordIndex) + url.substring(domainIndex); //remove '&password=ccc' from jsonObj.url + if (passwordIndex >= 0) { + jsonObj.url = url.substring(0, passwordIndex) + url.substring(domainIndex); //remove '&password=ccc' from jsonObj.url + } } } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 64e4f5c959f..870b4338bdd 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -404,7 +404,7 @@ var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, @@ -419,9 +419,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -433,13 +431,13 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); socketCount += returnedHostCpusocketsSum; }) @@ -8419,30 +8417,30 @@ } }, dataProvider: function (args) { - $.ajax({ - url: createURL('listHypervisors'), - success: function (json) { + var array1 = []; + + // ***** non XenServer (begin) ***** + var hypervisors = ["Hyperv", "KVM", "VMware", "BareMetal", "Ovm", "LXC"]; + var supportSocketHypervisors = { "Hyperv": 1, "KVM": 1, - "XenServer": 1, "VMware": 1 }; - args.response.success({ - data: $(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) { + for (var h = 0; h < hypervisors.length; h++) { var totalHostCount = 0; var currentPage = 1; var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, data: { type: 'routing', - hypervisor: hypervisor.name, + hypervisor: hypervisors[h], page: currentPage, pagesize: pageSize //global variable }, @@ -8451,9 +8449,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -8465,27 +8461,100 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); - if ((hypervisor.name in supportSocketHypervisors) == false) { + if ((hypervisors[h] in supportSocketHypervisors) == false) { returnedHostCpusocketsSum = 'N/A'; } - return { - hypervisor: hypervisor.name, + var hypervisorName = hypervisors[h]; + if (hypervisorName == "Hyperv") { + hypervisorName = "Hyper-V"; + } + + array1.push({ + hypervisor: hypervisorName, hosts: totalHostCount, sockets: returnedHostCpusocketsSum - }; - }) }); } + // ***** non XenServer (end) ***** + + + // ***** XenServer (begin) ***** + var totalHostCount = 0; + var currentPage = 1; + var returnedHostCount = 0; + + var returnedHostCountForXenServer = 0; + var returnedHostCountForXenServer620 = 0; + var returnedHostCpusocketsSumForXenServer620 = 0; + + var callListHostsWithPage = function() { + $.ajax({ + url: createURL('listHosts'), + async: false, + data: { + type: 'routing', + hypervisor: 'XenServer', + page: currentPage, + pagesize: pageSize //global variable + }, + success: function(json) { + if (json.listhostsresponse.count == undefined) { + return; + } + + totalHostCount = json.listhostsresponse.count; + returnedHostCount += json.listhostsresponse.host.length; + + var items = json.listhostsresponse.host; + for (var i = 0; i < items.length; i++) { + //"hypervisorversion" == "6.2.0" + if (items[i].hypervisorversion == "6.2.0") { + returnedHostCountForXenServer620 ++; + if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) { + returnedHostCpusocketsSumForXenServer620 += items[i].cpusockets; + } + } else { + returnedHostCountForXenServer++; + } + } + + if (returnedHostCount < totalHostCount) { + currentPage++; + callListHostsWithPage(); + } + } + }); + } + + callListHostsWithPage(); + + array1.push({ + hypervisor: 'XenServer', + hosts: returnedHostCountForXenServer, + sockets: 'N/A' }); + + array1.push({ + hypervisor: 'XenServer 6.2.0', + hosts: returnedHostCountForXenServer620, + sockets: returnedHostCpusocketsSumForXenServer620 + }); + // ***** XenServer (end) ***** + + + args.response.success({ + data: array1 + }); + } }; diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 99aa3b9f20a..4091c035a19 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -723,7 +723,10 @@ }).html('VXLAN'), $('