Skip to content
16 changes: 16 additions & 0 deletions api/src/com/cloud/network/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public enum GuestType {
Shared, Isolated
}

public String updatingInSequence ="updatingInSequence";

public static class Service {
private static List<Service> supportedServices = new ArrayList<Service>();

Expand Down Expand Up @@ -272,12 +274,26 @@ private State(String description) {
public class IpAddresses {
private String ip4Address;
private String ip6Address;
private String macAddress;

public String getMacAddress() {
return macAddress;
}

public void setMacAddress(String macAddress) {
this.macAddress = macAddress;
}

public IpAddresses(String ip4Address, String ip6Address) {
setIp4Address(ip4Address);
setIp6Address(ip6Address);
}

public IpAddresses(String ipAddress, String ip6Address, String macAddress) {
this(ipAddress, ip6Address);
setMacAddress(macAddress);
}

public String getIp4Address() {
return ip4Address;
}
Expand Down
3 changes: 2 additions & 1 deletion api/src/com/cloud/network/NetworkModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.IpAddresses;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.Networks.TrafficType;
Expand Down Expand Up @@ -254,7 +255,7 @@ public interface NetworkModel {

void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException;

void checkRequestedIpAddresses(long networkId, String ip4, String ip6) throws InvalidParameterValueException;
void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws InvalidParameterValueException;

String getStartIpv6Address(long id);

Expand Down
2 changes: 1 addition & 1 deletion api/src/com/cloud/network/NetworkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long ne
IpAddress getIp(long id);

Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId,
Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID);
Boolean changeCidr, String guestVmCidr, Boolean displayNetwork, String newUUID, boolean updateInSequence, boolean forced);

PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String> isolationMethods, String broadcastDomainRange, Long domainId,
List<String> tags, String name);
Expand Down
27 changes: 27 additions & 0 deletions api/src/com/cloud/network/element/RedundantResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.network.element;

import com.cloud.network.Network;

/**
* Created by bharat on 11/08/15.
*/
public interface RedundantResource {
public void configureResource(Network network);
public int getResourceCount(Network network);
}
4 changes: 4 additions & 0 deletions api/src/com/cloud/network/router/VirtualRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public enum Role {
VIRTUAL_ROUTER, LB, INTERNAL_LB_VM
}

public enum UpdateState {
UPDATE_NEEDED, UPDATE_IN_PROGRESS, UPDATE_COMPLETE, UPDATE_FAILED
}

Role getRole();

boolean getIsRedundantRouter();
Expand Down
2 changes: 1 addition & 1 deletion api/src/com/cloud/network/vpn/RemoteAccessVpnService.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface RemoteAccessVpnService {

RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay) throws NetworkRuleConflictException;

boolean destroyRemoteAccessVpnForIp(long ipId, Account caller) throws ResourceUnavailableException;
boolean destroyRemoteAccessVpnForIp(long ipId, Account caller, boolean forceCleanup) throws ResourceUnavailableException;

RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException;

Expand Down
5 changes: 5 additions & 0 deletions api/src/com/cloud/vm/NicProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public NicProfile(String requestedIPv4, String requestedIPv6) {
this.requestedIPv6 = requestedIPv6;
}

public NicProfile(String requestedIPv4, String requestedIPv6, String requestedMacAddress) {
this(requestedIPv4, requestedIPv6);
this.macAddress = requestedMacAddress;
}

public NicProfile(ReservationStrategy strategy, String iPv4Address, String macAddress, String iPv4gateway, String iPv4netmask) {
format = AddressFormat.Ip4;
this.iPv4Address = iPv4Address;
Expand Down
2 changes: 2 additions & 0 deletions api/src/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public class ApiConstants {
public static final String LUN = "lun";
public static final String LBID = "lbruleid";
public static final String MAX = "max";
public static final String MAC_ADDRESS = "macaddress";
public static final String MAX_SNAPS = "maxsnaps";
public static final String MEMORY = "memory";
public static final String MODE = "mode";
Expand Down Expand Up @@ -267,6 +268,7 @@ public class ApiConstants {
public static final String USERNAME = "username";
public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
public static final String Update_IN_SEQUENCE ="updateinsequence";
public static final String VALUE = "value";
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void execute() throws InsufficientCapacityException, ConcurrentOperationE
}

Network result = _networkService.updateGuestNetwork(getId(), getNetworkName(), getDisplayText(), callerAccount,
callerUser, getNetworkDomain(), getNetworkOfferingId(), getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId());
callerUser, getNetworkDomain(), getNetworkOfferingId(), getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId(), getUpdateInSequence(),getForced());


if (result != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,17 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd {
@Parameter(name = ApiConstants.GUEST_VM_CIDR, type = CommandType.STRING, description = "CIDR for guest VMs, CloudStack allocates IPs to guest VMs only from this CIDR")
private String guestVmCidr;

@Parameter(name =ApiConstants.Update_IN_SEQUENCE, type=CommandType.BOOLEAN, description = "if true, we will update the routers one after the other. applicable only for redundant router based networks using virtual router as provider")
private Boolean updateInSequence;

@Parameter(name = ApiConstants.DISPLAY_NETWORK,
type = CommandType.BOOLEAN,
description = "an optional field, whether to the display the network to the end user or not.", authorized = {RoleType.Admin})
private Boolean displayNetwork;

@Parameter(name= ApiConstants.FORCED, type = CommandType.BOOLEAN, description = "Setting this to true will cause a forced network update,", authorized = {RoleType.Admin})
private Boolean forced;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -119,6 +125,19 @@ public Boolean getDisplayNetwork() {
return displayNetwork;
}

public Boolean getUpdateInSequence(){
if(updateInSequence ==null)
return false;
else
return updateInSequence;
}

public boolean getForced(){
if(forced==null){
return false;
}
return forced;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -149,7 +168,7 @@ public void execute() throws InsufficientCapacityException, ConcurrentOperationE

Network result =
_networkService.updateGuestNetwork(getId(), getNetworkName(), getDisplayText(), callerAccount, callerUser, getNetworkDomain(), getNetworkOfferingId(),
getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId());
getChangeCidr(), getGuestVmCidr(), getDisplayNetwork(), getCustomId(), getUpdateInSequence(), getForced());

if (result != null) {
NetworkResponse response = _responseGenerator.createNetworkResponse(ResponseView.Restricted, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
import org.apache.cloudstack.context.CallContext;

import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.VirtualMachine;

@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
Expand All @@ -60,6 +62,9 @@ public class AddNicToVMCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "IP Address for the new network")
private String ipaddr;

@Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "Mac Address for the new network")
private String macaddr;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -76,6 +81,18 @@ public String getIpAddress() {
return ipaddr;
}

public String getMacAddress() {
if (macaddr == null) {
return null;
}
if(!NetUtils.isValidMac(macaddr)) {
throw new InvalidParameterValueException("Mac address is not valid: " + macaddr);
} else if(!NetUtils.isUnicastMac(macaddr)) {
throw new InvalidParameterValueException("Mac address is not unicast: " + macaddr);
}
return NetUtils.standardizeMacAddress(macaddr);
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down
31 changes: 28 additions & 3 deletions api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
private List<String> securityGroupNameList;

@Parameter(name = ApiConstants.IP_NETWORK_LIST, type = CommandType.MAP, description = "ip to network mapping. Can't be specified with networkIds parameter."
+ " Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid - requests to use ip 10.10.10.11 in network id=uuid")
+ " Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid&iptonetworklist[0].mac=aa:bb:cc:dd:ee::ff - requests to use ip 10.10.10.11 in network id=uuid")
private Map ipToNetworkList;

@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "the ip address for default vm's network")
Expand All @@ -161,6 +161,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
@Parameter(name = ApiConstants.IP6_ADDRESS, type = CommandType.STRING, description = "the ipv6 address for default vm's network")
private String ip6Address;

@Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "the mac address for default vm's network")
private String macAddress;

@Parameter(name = ApiConstants.KEYBOARD, type = CommandType.STRING, description = "an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us")
private String keyboard;

Expand Down Expand Up @@ -352,10 +355,19 @@ private Map<Long, IpAddresses> getIpToNetworkMap() {
}
String requestedIp = ips.get("ip");
String requestedIpv6 = ips.get("ipv6");
String requestedMac = ips.get("mac");
if (requestedIpv6 != null) {
requestedIpv6 = NetUtils.standardizeIp6Address(requestedIpv6);
}
IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6);
if (requestedMac != null) {
if(!NetUtils.isValidMac(requestedMac)) {
throw new InvalidParameterValueException("Mac address is not valid: " + requestedMac);
} else if(!NetUtils.isUnicastMac(requestedMac)) {
throw new InvalidParameterValueException("Mac address is not unicast: " + requestedMac);
}
requestedMac = NetUtils.standardizeMacAddress(requestedMac);
}
IpAddresses addrs = new IpAddresses(requestedIp, requestedIpv6, requestedMac);
ipToNetworkMap.put(networkId, addrs);
}
}
Expand All @@ -370,6 +382,19 @@ public String getIp6Address() {
return NetUtils.standardizeIp6Address(ip6Address);
}


public String getMacAddress() {
if (macAddress == null) {
return null;
}
if(!NetUtils.isValidMac(macAddress)) {
throw new InvalidParameterValueException("Mac address is not valid: " + macAddress);
} else if(!NetUtils.isUnicastMac(macAddress)) {
throw new InvalidParameterValueException("Mac address is not unicast: " + macAddress);
}
return NetUtils.standardizeMacAddress(macAddress);
}

public List<Long> getAffinityGroupIdList() {
if (affinityGroupNameList != null && affinityGroupIdList != null) {
throw new InvalidParameterValueException("affinitygroupids parameter is mutually exclusive with affinitygroupnames parameter");
Expand Down Expand Up @@ -577,7 +602,7 @@ public void create() throws ResourceAllocationException {
}

UserVm vm = null;
IpAddresses addrs = new IpAddresses(ipAddress, getIp6Address());
IpAddresses addrs = new IpAddresses(ipAddress, getIp6Address(), getMacAddress());
if (zone.getNetworkType() == NetworkType.Basic) {
if (getNetworkIds() != null) {
throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public String getEventType() {

@Override
public void execute() throws ResourceUnavailableException {
if (! _ravService.destroyRemoteAccessVpnForIp(publicIpId, CallContext.current().getCallingAccount())) {
if (! _ravService.destroyRemoteAccessVpnForIp(publicIpId, CallContext.current().getCallingAccount(), false)) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete remote access vpn");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,14 @@ void implementNetworkElementsAndResources(DeployDestination dest, ReservationCon
boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType);

void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest);

boolean canUpdateInSequence(Network network);

List<String> getServicesNotSupportedInNewOffering(Network network, long newNetworkOfferingId);

void cleanupConfigForServicesInNetwork(List<String> services, Network network);

void configureUpdateInSequence(Network network);

int getResourceCount(Network network);
}
Loading