mirror of https://github.com/apache/cloudstack.git
New feature: give access permission of networks to other accounts in same domain (#5769)
* Enhancement: create Shared networks and VPC private gateways by users * UI bug fix: pass correct domainid in CreateSharedNetworkForm * Update #5730: fix test failure with test_guest_vlan_range.py * Update #5730: fix test failure with test_persistent_network.py * Update #5730: Add since to new API commands and API parameters * Update #5730: Get first physical network for VPC private gateway if other ways do not work * Update #5730: code optimization (return !offering.isSpecifyVlan()) * Update #5730: fix hard-coded network offering id in test_pvlan.py * Update #5730: skip access check on the network owner if the owner is ROOT/system * Update #5730: overlap check on cidr/startip/endip * Update #5730: add methods to get accountid/domainid of shared networks * Update #5730: improve integration tests * Update #5730: update as per GutoVeronezi's comments * Network Sharing: give network access permission to other accounts within a domain * network: update ip in lb/pf/dnat tables when update vm nic ip * Update #5757: create 3 separated methods for DNAT/LB/PF update * travis: install python3-setuptools * Network Sharing: update integration test * Update #5769: Remove NetworkPermission.Ops * Update #5769: Update as per Daan's comments * Update #5769: Update as per Suresh's comments * Update #5769: fix UI bug that accounts/projects are not listed * Update #5769: fix domain admin can deploy vm on L2 network of other users * Update #5769: Remove method listPermittedNetworkIdsByDomains in NetworkPermissionDao * Update #5769: Skip network operation permissions check for root admin * UI: fix create Isolated/L2 network form * Update #5730: fix create Shared network form * Update #5769: fix domain admin can deploy vm on L2 network of other users * test: fix test_storage_policy.py * Update #5769: fix remove_nic in test_network_permissions.py * Update #5769: extract some codes to a method * Update #5769: fix add/remove nic by domain admin * Update #5769: allow domain admin to enable/disable static nat and create port forwarding rules * Update #5769: update integration test * Update #5769: fix unit test AssignLoadBalancerTest.java * Update #5769: allow normal users to share network permission to other users on UI * Update #5769: fix small UI bug with label * Update #5769: Support L2 network as associated network * test: sleep 30s after restarting mgt server in test_kubernetes_supported_versions.py to fix test failures with test_secondary_storage.py * Update #5784: revert part of changes in #2420 * Update #5757: invert if condition to reduce code indentation * Update #5769: fix regular user cannot create L2 network * Update #5769: Add associated nework id and name in private gateway response * Update #5769: list networks by networkfilter=Account on UI * Update #5769: fix ui issue when list private gateways or create shared network if no isolated networks * Update #5769: fix vue ui warnings * Update #5679: add BaseResponseWithAssociatedNetwork and extract method setResponseAssociatedNetworkInformation * Update #5679: extract some methods in VpcManagerImpl.java * Update #5679: Update smoke tests as per Daan's comments * Update #5769: fix vpc with private gateways cannot be removed when remove an acount * Update #5769: fix unit test failures after merging latest main * Update #5769: fix schema-41610to41700.sql * Update #5769: fix Request failed due to empty network offering list on UI * Update #5769: Throw exception when account is not found by name * Update #5769: display a warning message if network offering list is empty * Update #5769: fix an UI bug caused by previous commitb286cb7677* Update #5769: fix UI bugs due to vue3 merge * Update #5769: fix issue due to account type refactoring * Update #5769: fix ui bugs due to vue3 * Update #5769: fix issue due to vue3 upgrade * Update #5769: fix issue due to vue3 upgrade part 2 * Update #5769: fix issue due to vue3 upgrade part 3 * Update #5769: highlight default scope when create shared network on UI * Update #5769: fix domain list is not loaded on UI * Update #5769: fix restart/delete shared network by normal users * Update #5769: fix restart domain-scope shared network by domain admin * Update #5769: fix 3 UI bugs (1) double networks in list; (2) icon of first items in list; (3) account/project autoselect * Update #5769: fix 2 ui bugs; (1) selected project is not changed when change domain; (2) no network should be selected by default * Update #5769: fix update shared networks by domain admin/regular user * Update #5769: fix Flicking warning message about the empty network offerings * Update #5769: display associated network name in shared network info card * Update #5769: fix create private gateway form * Update #5769: fix network lists in project view * Update #5769: fix duplicated networks in network dropdown * Update #5769: fix failed to create shared network if associated L2 network is Setup * Update #5769: check AccessType.OperateEntry on network in its implementation * Revert "Update #5769: check AccessType.OperateEntry on network in its implementation" This reverts commitc42c489e5b. * Update #5769: fix keyword search in list guest vlans
This commit is contained in:
parent
334891a4b9
commit
a5014a28a6
|
|
@ -16,17 +16,26 @@
|
|||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface GuestVlan extends InternalIdentity, Identity {
|
||||
import java.util.Date;
|
||||
|
||||
public interface GuestVlan extends InternalIdentity {
|
||||
|
||||
@Override
|
||||
public long getId();
|
||||
|
||||
public long getAccountId();
|
||||
Date getTakenAt();
|
||||
|
||||
public String getGuestVlanRange();
|
||||
String getVnet();
|
||||
|
||||
public long getPhysicalNetworkId();
|
||||
String getReservationId();
|
||||
|
||||
Long getAccountId();
|
||||
|
||||
long getDataCenterId();
|
||||
|
||||
long getPhysicalNetworkId();
|
||||
|
||||
Long getAccountGuestVlanMapId();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// 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;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface GuestVlanRange extends InternalIdentity, Identity {
|
||||
|
||||
@Override
|
||||
public long getId();
|
||||
|
||||
public long getAccountId();
|
||||
|
||||
public String getGuestVlanRange();
|
||||
|
||||
public long getPhysicalNetworkId();
|
||||
}
|
||||
|
|
@ -332,6 +332,14 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
|
|||
}
|
||||
}
|
||||
|
||||
public enum NetworkFilter {
|
||||
Account, // return account networks that have been registered for or created by the calling user
|
||||
Domain, // return domain networks that have been registered for or created by the calling user
|
||||
AccountDomain, // return account and domain networks that have been registered for or created by the calling user
|
||||
Shared, // including networks that have been granted to the calling user by another user
|
||||
All // all networks (account, domain and shared)
|
||||
}
|
||||
|
||||
public class IpAddresses {
|
||||
private String ip4Address;
|
||||
private String ip6Address;
|
||||
|
|
@ -372,6 +380,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
|
|||
}
|
||||
}
|
||||
|
||||
static final String AssociatedNetworkId = "AssociatedNetworkId";
|
||||
|
||||
String getName();
|
||||
|
||||
Mode getMode();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.cloud.network.Network.Service;
|
|||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.NetworkOffering.Detail;
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -195,6 +196,10 @@ public interface NetworkModel {
|
|||
|
||||
void checkNetworkPermissions(Account owner, Network network);
|
||||
|
||||
void checkNetworkOperatePermissions(Account owner, Network network);
|
||||
|
||||
void checkRouterPermissions(Account owner, VirtualRouter router);
|
||||
|
||||
String getDefaultManagementTrafficLabel(long zoneId, HypervisorType hypervisorType);
|
||||
|
||||
String getDefaultStorageTrafficLabel(long zoneId, HypervisorType hypervisorType);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// 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;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface NetworkPermission extends InternalIdentity {
|
||||
|
||||
long getNetworkId();
|
||||
|
||||
long getAccountId();
|
||||
}
|
||||
|
|
@ -22,9 +22,14 @@ import java.util.Map;
|
|||
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListGuestVlansCmd;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RemoveNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ResetNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
|
|
@ -148,9 +153,9 @@ public interface NetworkService {
|
|||
|
||||
boolean deletePhysicalNetworkTrafficType(Long id);
|
||||
|
||||
GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd);
|
||||
GuestVlanRange dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd);
|
||||
|
||||
Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd);
|
||||
Pair<List<? extends GuestVlanRange>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd);
|
||||
|
||||
boolean releaseDedicatedGuestVlanRange(Long dedicatedGuestVlanRangeId);
|
||||
|
||||
|
|
@ -184,7 +189,7 @@ public interface NetworkService {
|
|||
* @throws ResourceAllocationException
|
||||
*/
|
||||
Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String broadcastUri, String startIp, String endIP, String gateway,
|
||||
String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId, Boolean bypassVlanOverlapCheck) throws ResourceAllocationException, ConcurrentOperationException,
|
||||
String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId, Boolean bypassVlanOverlapCheck, Long associatedNetworkId) throws ResourceAllocationException, ConcurrentOperationException,
|
||||
InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
|
|
@ -210,4 +215,14 @@ public interface NetworkService {
|
|||
AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException;
|
||||
|
||||
boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException;
|
||||
|
||||
Pair<List<? extends GuestVlan>, Integer> listGuestVlans(ListGuestVlansCmd cmd);
|
||||
|
||||
List<? extends NetworkPermission> listNetworkPermissions(ListNetworkPermissionsCmd listNetworkPermissionsCmd);
|
||||
|
||||
boolean createNetworkPermissions(CreateNetworkPermissionsCmd createNetworkPermissionsCmd);
|
||||
|
||||
boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd removeNetworkPermissionsCmd);
|
||||
|
||||
boolean resetNetworkPermissions(ResetNetworkPermissionsCmd resetNetworkPermissionsCmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.cloud.network.vpc;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd;
|
||||
|
|
@ -165,8 +166,7 @@ public interface VpcService {
|
|||
* @throws ConcurrentOperationException
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
public PrivateGateway createVpcPrivateGateway(long vpcId, Long physicalNetworkId, String vlan, String ipAddress, String gateway, String netmask, long gatewayOwnerId,
|
||||
Long networkOfferingId, Boolean isSoruceNat, Long aclId, Boolean bypassVlanOverlapCheck) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
|
||||
public PrivateGateway createVpcPrivateGateway(CreatePrivateGatewayCmd command) throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* Applies VPC private gateway on the backend, so it becomes functional
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
|
|||
public final static String SystemManagementNetwork = "System-Management-Network";
|
||||
public final static String SystemStorageNetwork = "System-Storage-Network";
|
||||
public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
|
||||
public final static String SystemPrivateGatewayNetworkOfferingWithoutVlan = "System-Private-Gateway-Network-Offering-Without-Vlan";
|
||||
|
||||
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
|
||||
public final static String QuickCloudNoServices = "QuickCloudNoServices";
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public class ApiConstants {
|
|||
public static final String ACCOUNTS = "accounts";
|
||||
public static final String ACCOUNT_TYPE = "accounttype";
|
||||
public static final String ACCOUNT_ID = "accountid";
|
||||
public static final String ACCOUNT_IDS = "accountids";
|
||||
public static final String ACCUMULATE = "accumulate";
|
||||
public static final String ACTIVITY = "activity";
|
||||
public static final String ADAPTER_TYPE = "adaptertype";
|
||||
|
|
@ -422,6 +423,8 @@ public class ApiConstants {
|
|||
public static final String ISOLATED_PVLAN = "isolatedpvlan";
|
||||
public static final String ISOLATED_PVLAN_TYPE = "isolatedpvlantype";
|
||||
public static final String ISOLATION_URI = "isolationuri";
|
||||
public static final String IS_DEDICATED = "isdedicated";
|
||||
public static final String TAKEN = "taken";
|
||||
public static final String VM_AVAILABLE = "vmavailable";
|
||||
public static final String VM_LIMIT = "vmlimit";
|
||||
public static final String VM_TOTAL = "vmtotal";
|
||||
|
|
@ -441,6 +444,7 @@ public class ApiConstants {
|
|||
public static final String TIER_NETWORK_OFFERINGS = "tiernetworkofferings";
|
||||
public static final String NETWORK_IDS = "networkids";
|
||||
public static final String NETWORK_ID = "networkid";
|
||||
public static final String NETWORK_FILTER = "networkfilter";
|
||||
public static final String NIC_ID = "nicid";
|
||||
public static final String SPECIFY_VLAN = "specifyvlan";
|
||||
public static final String IS_DEFAULT = "isdefault";
|
||||
|
|
@ -536,6 +540,7 @@ public class ApiConstants {
|
|||
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 PHYSICAL_NETWORK_NAME = "physicalnetworkname";
|
||||
public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid";
|
||||
public static final String ENABLE = "enable";
|
||||
public static final String ENABLED = "enabled";
|
||||
|
|
@ -572,6 +577,7 @@ public class ApiConstants {
|
|||
public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity";
|
||||
public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated";
|
||||
public static final String SERVICE = "service";
|
||||
public static final String ASSOCIATED_NETWORK = "associatednetwork";
|
||||
public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
|
||||
public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
|
||||
public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
|
||||
|
|
|
|||
|
|
@ -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.api;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public abstract class BaseResponseWithAssociatedNetwork extends BaseResponseWithAnnotations {
|
||||
|
||||
@SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID)
|
||||
@Param(description = "the ID of the Network associated with this private gateway")
|
||||
private String associatedNetworkId;
|
||||
|
||||
@SerializedName(ApiConstants.ASSOCIATED_NETWORK)
|
||||
@Param(description = "the name of the Network associated with this private gateway")
|
||||
private String associatedNetworkName;
|
||||
|
||||
public void setAssociatedNetworkId(String associatedNetworkId) {
|
||||
this.associatedNetworkId = associatedNetworkId;
|
||||
}
|
||||
|
||||
public void setAssociatedNetworkName(String associatedNetworkName) {
|
||||
this.associatedNetworkName = associatedNetworkName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,8 @@ import com.cloud.utils.Pair;
|
|||
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceIconResponse;
|
||||
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
|
||||
import org.apache.cloudstack.api.response.GuestVlanResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import com.cloud.resource.RollingMaintenanceManager;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
|
||||
|
|
@ -154,9 +156,11 @@ import com.cloud.event.Event;
|
|||
import com.cloud.host.Host;
|
||||
import com.cloud.hypervisor.HypervisorCapabilities;
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkPermission;
|
||||
import com.cloud.network.Networks.IsolationType;
|
||||
import com.cloud.network.OvsProvider;
|
||||
import com.cloud.network.PhysicalNetwork;
|
||||
|
|
@ -262,7 +266,7 @@ public interface ResponseGenerator {
|
|||
|
||||
IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddress);
|
||||
|
||||
GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result);
|
||||
GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlanRange result);
|
||||
|
||||
GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancerRule globalLoadBalancerRule);
|
||||
|
||||
|
|
@ -497,6 +501,10 @@ public interface ResponseGenerator {
|
|||
|
||||
ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon);
|
||||
|
||||
GuestVlanResponse createGuestVlanResponse(GuestVlan vlan);
|
||||
|
||||
NetworkPermissionsResponse createNetworkPermissionsResponse(NetworkPermission permission);
|
||||
|
||||
DirectDownloadCertificateResponse createDirectDownloadCertificateResponse(DirectDownloadCertificate certificate);
|
||||
|
||||
List<DirectDownloadCertificateHostStatusResponse> createDirectDownloadCertificateHostMapResponse(List<DirectDownloadCertificateHostMap> hostMappings);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import org.apache.cloudstack.api.response.ProjectResponse;
|
|||
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "dedicateGuestVlanRange", description = "Dedicates a guest vlan range to an account", responseObject = GuestVlanRangeResponse.class,
|
||||
|
|
@ -106,7 +106,7 @@ public class DedicateGuestVlanRangeCmd extends BaseCmd {
|
|||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, ResourceAllocationException {
|
||||
GuestVlan result = _networkService.dedicateGuestVlanRange(this);
|
||||
GuestVlanRange result = _networkService.dedicateGuestVlanRange(this);
|
||||
if (result != null) {
|
||||
GuestVlanRangeResponse response = _responseGenerator.createDedicatedGuestVlanRangeResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
|||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
|
|
@ -124,10 +124,10 @@ public class ListDedicatedGuestVlanRangesCmd extends BaseListCmd {
|
|||
|
||||
@Override
|
||||
public void execute() {
|
||||
Pair<List<? extends GuestVlan>, Integer> vlans = _networkService.listDedicatedGuestVlanRanges(this);
|
||||
Pair<List<? extends GuestVlanRange>, Integer> vlans = _networkService.listDedicatedGuestVlanRanges(this);
|
||||
ListResponse<GuestVlanRangeResponse> response = new ListResponse<GuestVlanRangeResponse>();
|
||||
List<GuestVlanRangeResponse> guestVlanResponses = new ArrayList<GuestVlanRangeResponse>();
|
||||
for (GuestVlan vlan : vlans.first()) {
|
||||
for (GuestVlanRange vlan : vlans.first()) {
|
||||
GuestVlanRangeResponse guestVlanResponse = _responseGenerator.createDedicatedGuestVlanRangeResponse(vlan);
|
||||
guestVlanResponse.setObjectName("dedicatedguestvlanrange");
|
||||
guestVlanResponses.add(guestVlanResponse);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
// 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.network;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.GuestVlanResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
@APICommand(name = "listGuestVlans", description = "Lists all guest vlans", responseObject = GuestVlanResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
since = "4.17.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class ListGuestVlansCmd extends BaseListCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListGuestVlansCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listguestvlansresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.LONG, required = false, description = "list guest vlan by id")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = false, description = "list guest vlan by zone")
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, entityType = PhysicalNetworkResponse.class, required = false, description = "list guest vlan by physical network")
|
||||
private Long physicalNetworkId;
|
||||
|
||||
@Parameter(name = ApiConstants.VNET, type = CommandType.STRING, required = false, description = "list guest vlan by vnet")
|
||||
private String vnet;
|
||||
|
||||
@Parameter(name = ApiConstants.ALLOCATED_ONLY, type = CommandType.BOOLEAN, required = false, description = "limits search results to allocated guest vlan. false by default.")
|
||||
private Boolean allocatedOnly;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Long getPhysicalNetworkId() {
|
||||
return physicalNetworkId;
|
||||
}
|
||||
|
||||
public String getVnet() {
|
||||
return vnet;
|
||||
}
|
||||
|
||||
public Boolean getAllocatedOnly() {
|
||||
return allocatedOnly;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Pair<List<? extends GuestVlan>, Integer> vlans = _networkService.listGuestVlans(this);
|
||||
ListResponse<GuestVlanResponse> response = new ListResponse<GuestVlanResponse>();
|
||||
List<GuestVlanResponse> guestVlanResponses = new ArrayList<GuestVlanResponse>();
|
||||
for (GuestVlan vlan : vlans.first()) {
|
||||
GuestVlanResponse guestVlanResponse = _responseGenerator.createGuestVlanResponse(vlan);
|
||||
guestVlanResponse.setObjectName("guestvlan");
|
||||
guestVlanResponses.add(guestVlanResponse);
|
||||
}
|
||||
|
||||
response.setResponses(guestVlanResponses, vlans.second());
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.cloudstack.api.command.admin.network;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.command.admin.AdminCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
|
|
@ -26,4 +28,16 @@ import com.cloud.network.Network;
|
|||
|
||||
@APICommand(name = "listNetworks", description = "Lists all available networks.", responseObject = NetworkResponse.class, responseView = ResponseView.Full, entityType = {Network.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListNetworksCmdByAdmin extends ListNetworksCmd implements AdminCmd {}
|
||||
public class ListNetworksCmdByAdmin extends ListNetworksCmd implements AdminCmd {
|
||||
|
||||
@Parameter(name= ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network", since = "4.17.0")
|
||||
private String vlan;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// 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.vpc;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.command.admin.AdminCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
||||
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
|
||||
|
||||
import com.cloud.network.vpc.VpcGateway;
|
||||
|
||||
@APICommand(name = "createPrivateGateway", description = "Creates a private gateway",
|
||||
responseObject = PrivateGatewayResponse.class,
|
||||
responseView = ResponseView.Full,
|
||||
entityType = {VpcGateway.class},
|
||||
since = "4.17.0",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class CreatePrivateGatewayByAdminCmd extends CreatePrivateGatewayCmd implements AdminCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(CreatePrivateGatewayByAdminCmd.class.getName());
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = PhysicalNetworkResponse.class,
|
||||
description = "the Physical Network ID the network belongs to")
|
||||
private Long physicalNetworkId;
|
||||
|
||||
@Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "the network implementation uri for the private gateway")
|
||||
private String broadcastUri;
|
||||
|
||||
@Parameter(name = ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type = CommandType.BOOLEAN, description = "when true bypasses VLAN id/range overlap check during private gateway creation")
|
||||
private Boolean bypassVlanOverlapCheck;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public String getBroadcastUri() {
|
||||
return broadcastUri;
|
||||
}
|
||||
|
||||
public Long getPhysicalNetworkId() {
|
||||
return physicalNetworkId;
|
||||
}
|
||||
|
||||
public Boolean getBypassVlanOverlapCheck() {
|
||||
return BooleanUtils.toBoolean(bypassVlanOverlapCheck);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.admin.vpc;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
|
@ -37,7 +38,8 @@ import com.cloud.network.vpc.VpcGateway;
|
|||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "deletePrivateGateway", description = "Deletes a Private gateway", responseObject = SuccessResponse.class, entityType = {VpcGateway.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeletePrivateGatewayCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeletePrivateGatewayCmd.class.getName());
|
||||
private static final String s_name = "deleteprivategatewayresponse";
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account that will own the network")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the SSH key")
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "an optional project for the network")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning a network")
|
||||
|
|
@ -150,6 +150,13 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
|
|||
@Parameter(name = ApiConstants.ACL_ID, type = CommandType.UUID, entityType = NetworkACLResponse.class, description = "Network ACL ID associated for the network")
|
||||
private Long aclId;
|
||||
|
||||
@Parameter(name = ApiConstants.ASSOCIATED_NETWORK_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = NetworkResponse.class,
|
||||
since = "4.17.0",
|
||||
description = "The network this network is associated to. only available if create a Shared network")
|
||||
private Long associatedNetworkId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -225,6 +232,10 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
|
|||
return isolatedPvlanType;
|
||||
}
|
||||
|
||||
public Long getAssociatedNetworkId() {
|
||||
return associatedNetworkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
if(displayNetwork == null)
|
||||
|
|
@ -249,11 +260,31 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
|
|||
throw new InvalidParameterValueException("Unable to find network offering by ID " + networkOfferingId);
|
||||
}
|
||||
|
||||
Network associatedNetwork = null;
|
||||
if (associatedNetworkId != null) {
|
||||
associatedNetwork = _entityMgr.findById(Network.class, associatedNetworkId);
|
||||
if (associatedNetwork == null) {
|
||||
throw new InvalidParameterValueException("Unable to find network by ID " + associatedNetworkId);
|
||||
}
|
||||
if (offering.getGuestType() != GuestType.Shared) {
|
||||
throw new InvalidParameterValueException("Associated network ID can be specified for networks of guest IP type " + GuestType.Shared + " only.");
|
||||
}
|
||||
if (zoneId != null && associatedNetwork.getDataCenterId() != zoneId) {
|
||||
throw new InvalidParameterValueException("The network can only be created in the same zone as the associated network");
|
||||
} else if (zoneId == null) {
|
||||
zoneId = associatedNetwork.getDataCenterId();
|
||||
}
|
||||
if (physicalNetworkId != null && !physicalNetworkId.equals(associatedNetwork.getPhysicalNetworkId())) {
|
||||
throw new InvalidParameterValueException("The network can only be created on the same physical network as the associated network");
|
||||
} else if (physicalNetworkId == null) {
|
||||
physicalNetworkId = associatedNetwork.getPhysicalNetworkId();
|
||||
}
|
||||
}
|
||||
if (physicalNetworkId != null) {
|
||||
if (offering.getGuestType() == GuestType.Shared) {
|
||||
return physicalNetworkId;
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Physical network OD can be specified for networks of guest IP type " + GuestType.Shared + " only.");
|
||||
throw new InvalidParameterValueException("Physical network ID can be specified for networks of guest IP type " + GuestType.Shared + " only.");
|
||||
}
|
||||
} else {
|
||||
if (zoneId == null) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = CreateNetworkPermissionsCmd.APINAME, description = "Updates network permissions.",
|
||||
responseObject = SuccessResponse.class,
|
||||
entityType = {Network.class},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
since = "4.17.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateNetworkPermissionsCmd extends BaseCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(CreateNetworkPermissionsCmd.class.getName());
|
||||
|
||||
public static final String APINAME = "createNetworkPermissions";
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ////////////// API parameters /////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNTS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.STRING,
|
||||
description = "a comma delimited list of accounts within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<String> accountNames;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = AccountResponse.class,
|
||||
description = "a comma delimited list of account IDs within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<Long> accountIds;
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the network ID")
|
||||
private Long networkId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
description = "a comma delimited list of projects within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<Long> projectIds;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
|
||||
public List<String> getAccountNames() {
|
||||
return accountNames;
|
||||
}
|
||||
|
||||
public List<Long> getAccountIds() {
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public List<Long> getProjectIds() {
|
||||
return projectIds;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (accountIds != null && accountNames != null) {
|
||||
throw new InvalidParameterValueException("Accounts and accountNames can't be specified together");
|
||||
}
|
||||
boolean result = _networkService.createNetworkPermissions(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network permissions");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network network = _entityMgr.findById(Network.class, getNetworkId());
|
||||
if (network != null) {
|
||||
return network.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
}
|
||||
|
|
@ -16,12 +16,13 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
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.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkPermission;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = ListNetworkPermissionsCmd.APINAME, description = "List network visibility and all accounts that have permissions to view this network.",
|
||||
responseObject = NetworkPermissionsResponse.class,
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
since = "4.17.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListNetworkPermissionsCmd extends BaseCmd implements UserCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(ListNetworkPermissionsCmd.class.getName());
|
||||
|
||||
public static final String APINAME = "listNetworkPermissions";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "Lists network permission by network ID")
|
||||
private Long networkId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network Network = _entityMgr.findById(Network.class, getNetworkId());
|
||||
if (Network != null) {
|
||||
return Network.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 APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<? extends NetworkPermission> permissions = _networkService.listNetworkPermissions(this);
|
||||
ListResponse<NetworkPermissionsResponse> response = new ListResponse<>();
|
||||
List<NetworkPermissionsResponse> networkPermissionResponses = new ArrayList<>();
|
||||
for (NetworkPermission permission : permissions) {
|
||||
NetworkPermissionsResponse networkPermissionResponse = _responseGenerator.createNetworkPermissionsResponse(permission);
|
||||
networkPermissionResponses.add(networkPermissionResponse);
|
||||
}
|
||||
response.setResponses(networkPermissionResponses, permissions.size());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -96,10 +96,28 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
@Parameter(name = ApiConstants.NETWORK_OFFERING_ID, type = CommandType.UUID, entityType = NetworkOfferingResponse.class, description = "list networks by network offering ID")
|
||||
private Long networkOfferingId;
|
||||
|
||||
@Parameter(name = ApiConstants.ASSOCIATED_NETWORK_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = NetworkResponse.class,
|
||||
since = "4.17.0",
|
||||
description = "List networks by associated networks. Only available if create a Shared network.")
|
||||
private Long associatedNetworkId;
|
||||
|
||||
@Parameter(name = ApiConstants.SHOW_RESOURCE_ICON, type = CommandType.BOOLEAN,
|
||||
description = "flag to display the resource icon for networks")
|
||||
private Boolean showIcon;
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_FILTER,
|
||||
type = CommandType.STRING,
|
||||
since = "4.17.0",
|
||||
description = "possible values are \"account\", \"domain\", \"accountdomain\",\"shared\", and \"all\". Default value is \"all\"."
|
||||
+ "* account : account networks that have been registered for or created by the calling user. "
|
||||
+ "* domain : domain networks that have been registered for or created by the calling user. "
|
||||
+ "* accountdomain : account and domain networks that have been registered for or created by the calling user. "
|
||||
+ "* shared : networks that have been granted to the calling user by another user. "
|
||||
+ "* all : all networks (account, domain and shared).")
|
||||
private String networkFilter;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -166,6 +184,10 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
return networkOfferingId;
|
||||
}
|
||||
|
||||
public Long getAssociatedNetworkId() {
|
||||
return associatedNetworkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getDisplay() {
|
||||
if (display != null) {
|
||||
|
|
@ -178,6 +200,10 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd implements UserC
|
|||
return showIcon != null ? showIcon : false;
|
||||
}
|
||||
|
||||
public String getNetworkFilter() {
|
||||
return networkFilter;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = RemoveNetworkPermissionsCmd.APINAME, description = "Removes network permissions.",
|
||||
responseObject = SuccessResponse.class,
|
||||
entityType = {Network.class},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
since = "4.17.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RemoveNetworkPermissionsCmd extends BaseCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(RemoveNetworkPermissionsCmd.class.getName());
|
||||
|
||||
public static final String APINAME = "removeNetworkPermissions";
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ////////////// API parameters /////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNTS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.STRING,
|
||||
description = "a comma delimited list of accounts within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<String> accountNames;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = AccountResponse.class,
|
||||
description = "a comma delimited list of account IDs within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<Long> accountIds;
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the network ID")
|
||||
private Long networkId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_IDS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
description = "a comma delimited list of projects within owner's domain. If specified, \"op\" parameter has to be passed in.")
|
||||
private List<Long> projectIds;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
public List<String> getAccountNames() {
|
||||
return accountNames;
|
||||
}
|
||||
|
||||
public List<Long> getAccountIds() {
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public List<Long> getProjectIds() {
|
||||
return projectIds;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (accountIds != null && accountNames != null) {
|
||||
throw new InvalidParameterValueException("Accounts and accountNames can't be specified together");
|
||||
}
|
||||
boolean result = _networkService.removeNetworkPermissions(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network permissions");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network network = _entityMgr.findById(Network.class, getNetworkId());
|
||||
if (network != null) {
|
||||
return network.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = ResetNetworkPermissionsCmd.APINAME, description = "Resets network permissions.",
|
||||
responseObject = SuccessResponse.class,
|
||||
entityType = {Network.class},
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
since = "4.17.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ResetNetworkPermissionsCmd extends BaseCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(ResetNetworkPermissionsCmd.class.getName());
|
||||
|
||||
public static final String APINAME = "resetNetworkPermissions";
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ////////////// API parameters /////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, required = true, description = "the network ID")
|
||||
private Long networkId;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
boolean result = _networkService.resetNetworkPermissions(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update network permissions");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network network = _entityMgr.findById(Network.class, getNetworkId());
|
||||
if (network != null) {
|
||||
return network.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import org.apache.log4j.Logger;
|
|||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
|
|
@ -124,6 +125,16 @@ public class RestartNetworkCmd extends BaseAsyncCmd {
|
|||
return EventTypes.EVENT_NETWORK_RESTART;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstanceId() {
|
||||
return getNetworkId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandJobType getInstanceType() {
|
||||
return ApiCommandJobType.Network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network network = _networkService.getNetwork(id);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.cloudstack.acl.RoleType;
|
|||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
|
|
@ -144,6 +145,16 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd implements UserCmd {
|
|||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstanceId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandJobType getInstanceType() {
|
||||
return ApiCommandJobType.Network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Network network = _networkService.getNetwork(id);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@
|
|||
// 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.vpc;
|
||||
package org.apache.cloudstack.api.command.user.vpc;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
|
@ -25,10 +26,12 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
|||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.UserCmd;
|
||||
import org.apache.cloudstack.api.response.NetworkACLResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.PrivateGatewayResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
|
||||
|
|
@ -41,11 +44,14 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
import com.cloud.network.vpc.PrivateGateway;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcGateway;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "createPrivateGateway", description = "Creates a private gateway", responseObject = PrivateGatewayResponse.class, entityType = {VpcGateway.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
||||
@APICommand(name = "createPrivateGateway", description = "Creates a private gateway",
|
||||
responseObject = PrivateGatewayResponse.class,
|
||||
responseView = ResponseView.Restricted,
|
||||
entityType = {VpcGateway.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(CreatePrivateGatewayCmd.class.getName());
|
||||
|
||||
private static final String s_name = "createprivategatewayresponse";
|
||||
|
|
@ -54,12 +60,6 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = PhysicalNetworkResponse.class,
|
||||
description = "the Physical Network ID the network belongs to")
|
||||
private Long physicalNetworkId;
|
||||
|
||||
@Parameter(name = ApiConstants.GATEWAY, type = CommandType.STRING, required = true, description = "the gateway of the Private gateway")
|
||||
private String gateway;
|
||||
|
||||
|
|
@ -69,9 +69,6 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true, description = "the IP address of the Private gateaway")
|
||||
private String ipAddress;
|
||||
|
||||
@Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, required = true, description = "the network implementation uri for the private gateway")
|
||||
private String broadcastUri;
|
||||
|
||||
@Parameter(name = ApiConstants.NETWORK_OFFERING_ID,
|
||||
type = CommandType.UUID,
|
||||
required = false,
|
||||
|
|
@ -92,8 +89,12 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
@Parameter(name = ApiConstants.ACL_ID, type = CommandType.UUID, entityType = NetworkACLResponse.class, required = false, description = "the ID of the network ACL")
|
||||
private Long aclId;
|
||||
|
||||
@Parameter(name=ApiConstants.BYPASS_VLAN_OVERLAP_CHECK, type=CommandType.BOOLEAN, description="when true bypasses VLAN id/range overlap check during private gateway creation")
|
||||
private Boolean bypassVlanOverlapCheck;
|
||||
@Parameter(name = ApiConstants.ASSOCIATED_NETWORK_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = NetworkResponse.class,
|
||||
since = "4.17.0",
|
||||
description = "The isolated network this private gateway is associated to.")
|
||||
private Long associatedNetworkId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
|
|
@ -103,23 +104,15 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
return gateway;
|
||||
}
|
||||
|
||||
public String getBroadcastUri() {
|
||||
return broadcastUri;
|
||||
}
|
||||
|
||||
public String getNetmask() {
|
||||
return netmask;
|
||||
}
|
||||
|
||||
public String getStartIp() {
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public Long getPhysicalNetworkId() {
|
||||
return physicalNetworkId;
|
||||
}
|
||||
|
||||
private Long getNetworkOfferingId() {
|
||||
public Long getNetworkOfferingId() {
|
||||
return networkOfferingId;
|
||||
}
|
||||
|
||||
|
|
@ -138,11 +131,8 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
return aclId;
|
||||
}
|
||||
|
||||
public Boolean getBypassVlanOverlapCheck() {
|
||||
if (bypassVlanOverlapCheck != null) {
|
||||
return bypassVlanOverlapCheck;
|
||||
}
|
||||
return false;
|
||||
public Long getAssociatedNetworkId() {
|
||||
return associatedNetworkId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -157,9 +147,7 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
public void create() throws ResourceAllocationException {
|
||||
PrivateGateway result = null;
|
||||
try {
|
||||
result =
|
||||
_vpcService.createVpcPrivateGateway(getVpcId(), getPhysicalNetworkId(), getBroadcastUri(), getStartIp(), getGateway(), getNetmask(), getEntityOwnerId(),
|
||||
getNetworkOfferingId(), getIsSourceNat(), getAclId(), getBypassVlanOverlapCheck());
|
||||
result = _vpcService.createVpcPrivateGateway(this);
|
||||
} catch (InsufficientCapacityException ex) {
|
||||
s_logger.info(ex);
|
||||
s_logger.trace(ex);
|
||||
|
|
@ -191,7 +179,11 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd {
|
|||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Invalid id is specified for the vpc");
|
||||
}
|
||||
return vpc.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -22,10 +22,10 @@ import org.apache.cloudstack.api.ApiConstants;
|
|||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.serializer.Param;
|
||||
|
||||
@EntityReference(value = GuestVlan.class)
|
||||
@EntityReference(value = GuestVlanRange.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class GuestVlanRangeResponse extends BaseResponse implements ControlledEntityResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
// 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 com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class GuestVlanResponse extends BaseResponse implements ControlledEntityResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the guest VLAN id")
|
||||
private long id;
|
||||
|
||||
@SerializedName(ApiConstants.VLAN)
|
||||
@Param(description = "the guest VLAN")
|
||||
private String guestVlan;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "the account of the guest VLAN range")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "the domain ID of the guest VLAN range")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the domain name of the guest VLAN range")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the project id of the guest VLAN range")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT)
|
||||
@Param(description = "the project name of the guest VLAN range")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "the zone ID of the guest VLAN range")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
@Param(description = "the zone name of the guest VLAN range")
|
||||
private String zoneName;
|
||||
|
||||
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID)
|
||||
@Param(description = "the physical network ID of the guest VLAN range")
|
||||
private String physicalNetworkId;
|
||||
|
||||
@SerializedName(ApiConstants.PHYSICAL_NETWORK_NAME)
|
||||
@Param(description = "the physical network name of the guest VLAN range")
|
||||
private String physicalNetworkName;
|
||||
|
||||
@SerializedName(ApiConstants.IS_DEDICATED)
|
||||
@Param(description = "true if the guest VLAN is dedicated to the account")
|
||||
private Boolean isDedicated;
|
||||
|
||||
@SerializedName(ApiConstants.ALLOCATION_STATE)
|
||||
@Param(description = "the allocation state of the guest VLAN")
|
||||
private String allocationState;
|
||||
|
||||
@SerializedName(ApiConstants.TAKEN)
|
||||
@Param(description = "date the guest VLAN was taken")
|
||||
private Date taken;
|
||||
|
||||
@SerializedName(ApiConstants.NETWORK)
|
||||
@Param(description = "the list of networks who use this guest VLAN", responseObject = NetworkResponse.class)
|
||||
private List<NetworkResponse> networks;
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public void setZoneName(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
}
|
||||
|
||||
public void setPhysicalNetworkId(String physicalNetworkId) {
|
||||
this.physicalNetworkId = physicalNetworkId;
|
||||
}
|
||||
|
||||
public void setPhysicalNetworkName(String physicalNetworkName) {
|
||||
this.physicalNetworkName = physicalNetworkName;
|
||||
}
|
||||
|
||||
public void setGuestVlan(String guestVlan) {
|
||||
this.guestVlan = guestVlan;
|
||||
}
|
||||
|
||||
public void setDedicated(Boolean dedicated) {
|
||||
isDedicated = dedicated;
|
||||
}
|
||||
|
||||
public void setAllocationState(String allocationState) {
|
||||
this.allocationState = allocationState;
|
||||
}
|
||||
|
||||
public void setTaken(Date taken) {
|
||||
this.taken = taken;
|
||||
}
|
||||
|
||||
public void setNetworks(List<NetworkResponse> networks) {
|
||||
this.networks = networks;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
// 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 com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.serializer.Param;
|
||||
|
||||
@EntityReference(value = Network.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class NetworkPermissionsResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.NETWORK_ID)
|
||||
@Param(description = "the network ID")
|
||||
private String networkId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "the ID of the domain to which the network belongs")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the name of the domain to which the network belongs")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "the account the network is available for")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_ID)
|
||||
@Param(description = "the ID of account the network is available for")
|
||||
private String accountId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT)
|
||||
@Param(description = "the project the network is available for")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the ID of project the network is available for")
|
||||
private String projectId;
|
||||
|
||||
|
||||
public void setNetworkId(String networkId) {
|
||||
this.networkId = networkId;
|
||||
}
|
||||
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ import java.util.Set;
|
|||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponseWithAnnotations;
|
||||
import org.apache.cloudstack.api.BaseResponseWithAssociatedNetwork;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
|
|
@ -33,7 +33,7 @@ import com.google.gson.annotations.SerializedName;
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = {Network.class, ProjectAccount.class})
|
||||
public class NetworkResponse extends BaseResponseWithAnnotations implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
public class NetworkResponse extends BaseResponseWithAssociatedNetwork implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the id of the network")
|
||||
|
|
@ -195,6 +195,14 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
@Param(description = "Name of the VPC to which this network belongs", since = "4.15")
|
||||
private String vpcName;
|
||||
|
||||
@SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID)
|
||||
@Param(description = "the ID of the Network associated with this network")
|
||||
private String associatedNetworkId;
|
||||
|
||||
@SerializedName(ApiConstants.ASSOCIATED_NETWORK)
|
||||
@Param(description = "the name of the Network associated with this network")
|
||||
private String associatedNetworkName;
|
||||
|
||||
@SerializedName(ApiConstants.CAN_USE_FOR_DEPLOY)
|
||||
@Param(description = "list networks available for vm deployment")
|
||||
private Boolean canUseForDeploy;
|
||||
|
|
@ -512,6 +520,14 @@ public class NetworkResponse extends BaseResponseWithAnnotations implements Cont
|
|||
this.vpcName = vpcName;
|
||||
}
|
||||
|
||||
public void setAssociatedNetworkId(String associatedNetworkId) {
|
||||
this.associatedNetworkId = associatedNetworkId;
|
||||
}
|
||||
|
||||
public void setAssociatedNetworkName(String associatedNetworkName) {
|
||||
this.associatedNetworkName = associatedNetworkName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceIconResponse(ResourceIconResponse icon) {
|
||||
this.icon = icon;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package org.apache.cloudstack.api.response;
|
|||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.BaseResponseWithAssociatedNetwork;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.network.vpc.VpcGateway;
|
||||
|
|
@ -27,7 +27,7 @@ import com.cloud.serializer.Param;
|
|||
|
||||
@EntityReference(value = VpcGateway.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class PrivateGatewayResponse extends BaseResponse implements ControlledEntityResponse {
|
||||
public class PrivateGatewayResponse extends BaseResponseWithAssociatedNetwork implements ControlledEntityResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the id of the private gateway")
|
||||
|
|
@ -190,5 +190,4 @@ public class PrivateGatewayResponse extends BaseResponse implements ControlledEn
|
|||
public void setAclName(String aclName) {
|
||||
this.aclName = aclName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ public interface NetworkOrchestrationService {
|
|||
*/
|
||||
void rollbackNicForMigration(VirtualMachineProfile src, VirtualMachineProfile dst);
|
||||
|
||||
boolean isSharedNetworkWithoutSpecifyVlan(NetworkOffering offering);
|
||||
|
||||
boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements);
|
||||
|
||||
boolean destroyNetwork(long networkId, ReservationContext context, boolean forced);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -318,6 +319,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
ResourceManager resourceManager;
|
||||
@Inject
|
||||
private AnnotationDao annotationDao;
|
||||
@Inject
|
||||
NetworkPermissionDao networkPermissionDao;
|
||||
|
||||
List<NetworkGuru> networkGurus;
|
||||
|
||||
|
|
@ -2530,7 +2533,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
final boolean vlanSpecified = vlanId != null;
|
||||
if (vlanSpecified != ntwkOff.isSpecifyVlan()) {
|
||||
if (vlanSpecified) {
|
||||
throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
|
||||
if (!isSharedNetworkWithoutSpecifyVlan(ntwkOff) && !isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
|
||||
throw new InvalidParameterValueException("Can't specify vlan; corresponding offering says specifyVlan=false");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Vlan has to be specified; corresponding offering says specifyVlan=true");
|
||||
}
|
||||
|
|
@ -2540,8 +2545,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
URI uri = encodeVlanIdIntoBroadcastUri(vlanId, pNtwk);
|
||||
// Aux: generate secondary URI for secondary VLAN ID (if provided) for performing checks
|
||||
URI secondaryUri = StringUtils.isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
|
||||
if (isSharedNetworkWithoutSpecifyVlan(ntwkOff) || isPrivateGatewayWithoutSpecifyVlan(ntwkOff)) {
|
||||
bypassVlanOverlapCheck = true;
|
||||
}
|
||||
//don't allow to specify vlan tag used by physical network for dynamic vlan allocation
|
||||
if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
|
||||
if (!(bypassVlanOverlapCheck && (ntwkOff.getGuestType() == GuestType.Shared || isPrivateNetwork))
|
||||
&& _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
|
||||
throw new InvalidParameterValueException("The VLAN tag to use for new guest network, " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
|
||||
+ zone.getName());
|
||||
}
|
||||
|
|
@ -2764,6 +2773,18 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSharedNetworkWithoutSpecifyVlan(NetworkOffering offering) {
|
||||
if (offering == null || offering.getTrafficType() != TrafficType.Guest || offering.getGuestType() != GuestType.Shared) {
|
||||
return false;
|
||||
}
|
||||
return !offering.isSpecifyVlan();
|
||||
}
|
||||
|
||||
private boolean isPrivateGatewayWithoutSpecifyVlan(NetworkOffering ntwkOff) {
|
||||
return ntwkOff.getId() == _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan).getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes VLAN/VXLAN ID into a Broadcast URI according to the isolation method from the Physical Network.
|
||||
*
|
||||
|
|
@ -3096,7 +3117,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
throw new CloudRuntimeException("Failed to trash network.");
|
||||
}
|
||||
|
||||
if (!deleteVlansInNetwork(networkFinal.getId(), context.getCaller().getId(), callerAccount)) {
|
||||
if (!deleteVlansInNetwork(networkFinal, context.getCaller().getId(), callerAccount)) {
|
||||
s_logger.warn("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
|
||||
throw new CloudRuntimeException("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
|
||||
} else {
|
||||
|
|
@ -3118,6 +3139,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
}
|
||||
|
||||
networkDetailsDao.removeDetails(networkFinal.getId());
|
||||
networkPermissionDao.removeAllPermissions(networkFinal.getId());
|
||||
}
|
||||
|
||||
final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId());
|
||||
|
|
@ -3150,8 +3172,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
return updateResourceCount;
|
||||
}
|
||||
|
||||
protected boolean deleteVlansInNetwork(final long networkId, final long userId, final Account callerAccount) {
|
||||
|
||||
protected boolean deleteVlansInNetwork(final NetworkVO network, final long userId, final Account callerAccount) {
|
||||
final long networkId = network.getId();
|
||||
//cleanup Public vlans
|
||||
final List<VlanVO> publicVlans = _vlanDao.listVlansByNetworkId(networkId);
|
||||
boolean result = true;
|
||||
|
|
@ -3171,6 +3193,13 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
_privateIpDao.deleteByNetworkId(networkId);
|
||||
s_logger.debug("Deleted ip range for private network id=" + networkId);
|
||||
}
|
||||
|
||||
// release vlans of user-shared networks without specifyvlan
|
||||
if (isSharedNetworkWithoutSpecifyVlan(_networkOfferingDao.findById(network.getNetworkOfferingId()))) {
|
||||
s_logger.debug("Releasing vnet for the network id=" + network.getId());
|
||||
_dcDao.releaseVnet(BroadcastDomainType.getValue(network.getBroadcastUri()), network.getDataCenterId(),
|
||||
network.getPhysicalNetworkId(), network.getAccountId(), network.getReservationId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -3206,6 +3235,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!networkDetailsDao.findDetails(Network.AssociatedNetworkId, String.valueOf(networkId), null).isEmpty()) {
|
||||
s_logger.debug(String.format("Network %s is associated to a shared network, skipping", networkId));
|
||||
continue;
|
||||
}
|
||||
|
||||
final Long time = _lastNetworkIdsToFree.remove(networkId);
|
||||
if (time == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ import javax.persistence.Table;
|
|||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import com.cloud.network.GuestVlan;
|
||||
|
||||
@Entity
|
||||
@Table(name = "op_dc_vnet_alloc")
|
||||
public class DataCenterVnetVO implements InternalIdentity {
|
||||
public class DataCenterVnetVO implements GuestVlan {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
@ -84,6 +84,7 @@ public class DataCenterVnetVO implements InternalIdentity {
|
|||
return vnet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReservationId() {
|
||||
return reservationId;
|
||||
}
|
||||
|
|
@ -92,6 +93,7 @@ public class DataCenterVnetVO implements InternalIdentity {
|
|||
this.reservationId = reservationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
|
@ -100,10 +102,12 @@ public class DataCenterVnetVO implements InternalIdentity {
|
|||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDataCenterId() {
|
||||
return dataCenterId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPhysicalNetworkId() {
|
||||
return physicalNetworkId;
|
||||
}
|
||||
|
|
@ -112,6 +116,7 @@ public class DataCenterVnetVO implements InternalIdentity {
|
|||
this.accountGuestVlanMapId = accountGuestVlanMapId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getAccountGuestVlanMapId() {
|
||||
return accountGuestVlanMapId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,8 +205,8 @@ public class VlanVO implements Vlan {
|
|||
.append("|")
|
||||
.append(ipRange)
|
||||
.append("|")
|
||||
.append("|")
|
||||
.append(ip6Range)
|
||||
.append("|")
|
||||
.append(networkId)
|
||||
.append("]")
|
||||
.toString();
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
|
||||
@Entity
|
||||
@Table(name = "account_vnet_map")
|
||||
public class AccountGuestVlanMapVO implements GuestVlan {
|
||||
public class AccountGuestVlanMapVO implements GuestVlanRange {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
|
|||
|
|
@ -402,12 +402,12 @@ public class NetworkOfferingVO implements NetworkOffering {
|
|||
this.state = State.Enabled;
|
||||
}
|
||||
|
||||
public NetworkOfferingVO(String name, Network.GuestType guestType) {
|
||||
public NetworkOfferingVO(String name, Network.GuestType guestType, boolean specifyVlan) {
|
||||
this(name,
|
||||
"System Offering for " + name,
|
||||
TrafficType.Guest,
|
||||
true,
|
||||
true,
|
||||
specifyVlan,
|
||||
0,
|
||||
0,
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import javax.annotation.PostConstruct;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.host.HostVO;
|
||||
|
|
@ -376,7 +377,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
|
|||
public void addRouterToGuestNetwork(final VirtualRouter router, final Network guestNetwork) {
|
||||
if (_routerNetworkDao.findByRouterAndNetwork(router.getId(), guestNetwork.getId()) == null) {
|
||||
final NetworkOffering off = _offDao.findById(guestNetwork.getNetworkOfferingId());
|
||||
if (!off.getName().equalsIgnoreCase(NetworkOffering.SystemPrivateGatewayNetworkOffering)) {
|
||||
if (!StringUtils.equalsAnyIgnoreCase(NetworkOffering.SystemPrivateGatewayNetworkOffering, NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan)) {
|
||||
final TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
//1) add router to network
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// 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;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.network.NetworkPermission;
|
||||
|
||||
@Entity
|
||||
@Table(name = "network_permissions")
|
||||
public class NetworkPermissionVO implements NetworkPermission {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "network_id")
|
||||
private long networkId;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
public NetworkPermissionVO() {
|
||||
}
|
||||
|
||||
public NetworkPermissionVO(long networkId, long accountId) {
|
||||
this.networkId = networkId;
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// 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.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.network.NetworkPermissionVO;
|
||||
|
||||
public interface NetworkPermissionDao extends GenericDao<NetworkPermissionVO, Long> {
|
||||
/**
|
||||
* remove the ability to Network vms from the given network for the given
|
||||
* account names which are valid in the given domain
|
||||
*
|
||||
* @param networkId
|
||||
* id of the network to modify Network permissions
|
||||
* @param accountIds
|
||||
* list of account ids
|
||||
*/
|
||||
void removePermissions(long networkId, List<Long> accountIds);
|
||||
|
||||
/**
|
||||
* remove all Network permissions associated with a network
|
||||
*
|
||||
* @param networkId
|
||||
*/
|
||||
void removeAllPermissions(long networkId);
|
||||
|
||||
/**
|
||||
* Find a Network permission by networkId, accountName, and domainId
|
||||
*
|
||||
* @param networkId
|
||||
* the id of the network to search for
|
||||
* @param accountId
|
||||
* the id of the account for which permission is being searched
|
||||
* @return Network permission if found, null otherwise
|
||||
*/
|
||||
NetworkPermissionVO findByNetworkAndAccount(long networkId, long accountId);
|
||||
|
||||
/**
|
||||
* List all Network permissions for the given network
|
||||
*
|
||||
* @param networkId
|
||||
* id of the network for which Network permissions will be
|
||||
* queried
|
||||
* @return list of Network permissions
|
||||
*/
|
||||
List<NetworkPermissionVO> findByNetwork(long networkId);
|
||||
|
||||
List<Long> listPermittedNetworkIdsByAccounts(List<Long> permittedAccounts);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
// 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.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.network.NetworkPermissionVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@Component
|
||||
public class NetworkPermissionDaoImpl extends GenericDaoBase<NetworkPermissionVO, Long> implements NetworkPermissionDao {
|
||||
private static final Logger s_logger = Logger.getLogger(NetworkPermissionDaoImpl.class);
|
||||
|
||||
private SearchBuilder<NetworkPermissionVO> NetworkAndAccountSearch;
|
||||
private SearchBuilder<NetworkPermissionVO> NetworkIdSearch;
|
||||
private GenericSearchBuilder<NetworkPermissionVO, Long> FindNetworkIdsByAccount;
|
||||
|
||||
protected NetworkPermissionDaoImpl() {
|
||||
NetworkAndAccountSearch = createSearchBuilder();
|
||||
NetworkAndAccountSearch.and("networkId", NetworkAndAccountSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
|
||||
NetworkAndAccountSearch.and("accountId", NetworkAndAccountSearch.entity().getAccountId(), SearchCriteria.Op.IN);
|
||||
NetworkAndAccountSearch.done();
|
||||
|
||||
NetworkIdSearch = createSearchBuilder();
|
||||
NetworkIdSearch.and("networkId", NetworkIdSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
|
||||
NetworkIdSearch.done();
|
||||
|
||||
FindNetworkIdsByAccount = createSearchBuilder(Long.class);
|
||||
FindNetworkIdsByAccount.select(null, SearchCriteria.Func.DISTINCT, FindNetworkIdsByAccount.entity().getNetworkId());
|
||||
FindNetworkIdsByAccount.and("account", FindNetworkIdsByAccount.entity().getAccountId(), SearchCriteria.Op.IN);
|
||||
FindNetworkIdsByAccount.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermissions(long networkId, List<Long> accountIds) {
|
||||
if (accountIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SearchCriteria<NetworkPermissionVO> sc = NetworkAndAccountSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
sc.setParameters("accountId", accountIds.toArray());
|
||||
expunge(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllPermissions(long networkId) {
|
||||
SearchCriteria<NetworkPermissionVO> sc = NetworkIdSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
expunge(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkPermissionVO findByNetworkAndAccount(long networkId, long accountId) {
|
||||
SearchCriteria<NetworkPermissionVO> sc = NetworkAndAccountSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
sc.setParameters("accountId", accountId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkPermissionVO> findByNetwork(long networkId) {
|
||||
SearchCriteria<NetworkPermissionVO> sc = NetworkIdSearch.create();
|
||||
sc.setParameters("networkId", networkId);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listPermittedNetworkIdsByAccounts(List<Long> permittedAccounts) {
|
||||
SearchCriteria<Long> sc = FindNetworkIdsByAccount.create();
|
||||
if (permittedAccounts != null && !permittedAccounts.isEmpty()) {
|
||||
sc.setParameters("account", permittedAccounts.toArray());
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
return new ArrayList<Long>();
|
||||
}
|
||||
}
|
||||
|
|
@ -296,4 +296,5 @@
|
|||
<bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" />
|
||||
<bean id="TemplateDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDaoImpl" />
|
||||
<bean id="UserVmDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDaoImpl" />
|
||||
<bean id="NetworkPermissionDaoImpl" class="org.apache.cloudstack.network.dao.NetworkPermissionDaoImpl" />
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -645,6 +645,15 @@ CREATE VIEW `cloud`.`domain_router_view` AS
|
|||
INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) SELECT UUID(), 3, 'listConfigurations', 'ALLOW', (SELECT MAX(`sort_order`)+1 FROM `cloud`.`role_permissions`) ON DUPLICATE KEY UPDATE rule=rule;
|
||||
INSERT INTO `cloud`.`role_permissions` (`uuid`, `role_id`, `rule`, `permission`, `sort_order`) SELECT UUID(), 3, 'updateConfiguration', 'ALLOW', (SELECT MAX(`sort_order`)+1 FROM `cloud`.`role_permissions`) ON DUPLICATE KEY UPDATE rule=rule;
|
||||
|
||||
-- table for network permissions
|
||||
CREATE TABLE `cloud`.`network_permissions` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`network_id` bigint unsigned NOT NULL,
|
||||
`account_id` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `i_network_permission_network_id`(`network_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO `cloud`.`user_vm_details`(`vm_id`, `name`, `value`)
|
||||
SELECT `user_vm_details`.`vm_id`, 'SSH.KeyPairNames', `ssh_keypairs`.`keypair_name`
|
||||
FROM `cloud`.`user_vm_details`
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.cloud.exception.PermissionDeniedException;
|
|||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.vpc.VpcOffering;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingDetailsDao;
|
||||
import com.cloud.offering.DiskOffering;
|
||||
|
|
@ -173,6 +174,10 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
|||
return true;
|
||||
} else if (entity instanceof Network && accessType != null && accessType == AccessType.UseEntry) {
|
||||
_networkMgr.checkNetworkPermissions(caller, (Network)entity);
|
||||
} else if (entity instanceof Network && accessType != null && accessType == AccessType.OperateEntry) {
|
||||
_networkMgr.checkNetworkOperatePermissions(caller, (Network)entity);
|
||||
} else if (entity instanceof VirtualRouter) {
|
||||
_networkMgr.checkRouterPermissions(caller, (VirtualRouter)entity);
|
||||
} else if (entity instanceof AffinityGroup) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
|||
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
|
||||
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
||||
import org.apache.cloudstack.api.ApiConstants.VMDetails;
|
||||
import org.apache.cloudstack.api.BaseResponseWithAssociatedNetwork;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.ResponseObject.ResponseView;
|
||||
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
||||
|
|
@ -82,6 +83,7 @@ import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
|
|||
import org.apache.cloudstack.api.response.GuestOSResponse;
|
||||
import org.apache.cloudstack.api.response.GuestOsMappingResponse;
|
||||
import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
|
||||
import org.apache.cloudstack.api.response.GuestVlanResponse;
|
||||
import org.apache.cloudstack.api.response.HostForMigrationResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
|
||||
|
|
@ -102,6 +104,7 @@ import org.apache.cloudstack.api.response.ManagementServerResponse;
|
|||
import org.apache.cloudstack.api.response.NetworkACLItemResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkACLResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
|
||||
import org.apache.cloudstack.api.response.NetworkResponse;
|
||||
import org.apache.cloudstack.api.response.NicExtraDhcpOptionResponse;
|
||||
import org.apache.cloudstack.api.response.NicResponse;
|
||||
|
|
@ -245,12 +248,14 @@ import com.cloud.host.Host;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.hypervisor.HypervisorCapabilities;
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.NetworkPermission;
|
||||
import com.cloud.network.NetworkProfile;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.IsolationType;
|
||||
|
|
@ -277,6 +282,7 @@ import com.cloud.network.as.Counter;
|
|||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkDetailVO;
|
||||
import com.cloud.network.dao.NetworkDetailsDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
|
|
@ -423,6 +429,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
private AnnotationDao annotationDao;
|
||||
@Inject
|
||||
private UserStatisticsDao userStatsDao;
|
||||
@Inject
|
||||
private NetworkDao networkDao;
|
||||
|
||||
@Override
|
||||
public UserResponse createUserResponse(User user) {
|
||||
|
|
@ -2437,6 +2445,9 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
response.setVpcName(vpc.getName());
|
||||
}
|
||||
}
|
||||
|
||||
setResponseAssociatedNetworkInformation(response, network.getId());
|
||||
|
||||
response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network));
|
||||
|
||||
// set tag information
|
||||
|
|
@ -2491,6 +2502,18 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
return response;
|
||||
}
|
||||
|
||||
private void setResponseAssociatedNetworkInformation(BaseResponseWithAssociatedNetwork response, Long networkId) {
|
||||
final NetworkDetailVO detail = networkDetailsDao.findDetail(networkId, Network.AssociatedNetworkId);
|
||||
if (detail != null) {
|
||||
Long associatedNetworkId = Long.valueOf(detail.getValue());
|
||||
NetworkVO associatedNetwork = ApiDBUtils.findNetworkById(associatedNetworkId);
|
||||
if (associatedNetwork != null) {
|
||||
response.setAssociatedNetworkId(associatedNetwork.getUuid());
|
||||
response.setAssociatedNetworkName(associatedNetwork.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSecurityGroupId(String groupName, long accountId) {
|
||||
SecurityGroup sg = ApiDBUtils.getSecurityGroup(groupName, accountId);
|
||||
|
|
@ -2762,7 +2785,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan vlan) {
|
||||
public GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlanRange vlan) {
|
||||
GuestVlanRangeResponse guestVlanRangeResponse = new GuestVlanRangeResponse();
|
||||
|
||||
guestVlanRangeResponse.setId(vlan.getUuid());
|
||||
|
|
@ -3202,6 +3225,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
response.setAclName(acl.getName());
|
||||
}
|
||||
|
||||
setResponseAssociatedNetworkInformation(response, result.getNetworkId());
|
||||
|
||||
response.setObjectName("privategateway");
|
||||
|
||||
return response;
|
||||
|
|
@ -4558,6 +4583,95 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
return ApiDBUtils.newResourceIconResponse(resourceIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuestVlanResponse createGuestVlanResponse(GuestVlan guestVlan) {
|
||||
GuestVlanResponse guestVlanResponse = new GuestVlanResponse();
|
||||
|
||||
Account owner = null;
|
||||
if (guestVlan.getAccountId() != null) {
|
||||
owner = ApiDBUtils.findAccountById(guestVlan.getAccountId());
|
||||
} else if (guestVlan.getAccountGuestVlanMapId() != null) {
|
||||
Long accountId = ApiDBUtils.getAccountIdForGuestVlan(guestVlan.getAccountGuestVlanMapId());
|
||||
owner = ApiDBUtils.findAccountById(accountId);
|
||||
}
|
||||
if (owner != null) {
|
||||
populateAccount(guestVlanResponse, owner.getId());
|
||||
populateDomain(guestVlanResponse, owner.getDomainId());
|
||||
}
|
||||
guestVlanResponse.setId(guestVlan.getId());
|
||||
guestVlanResponse.setGuestVlan(guestVlan.getVnet());
|
||||
DataCenterVO zone = ApiDBUtils.findZoneById(guestVlan.getDataCenterId());
|
||||
if (zone != null) {
|
||||
guestVlanResponse.setZoneId(zone.getUuid());
|
||||
guestVlanResponse.setZoneName(zone.getName());
|
||||
}
|
||||
PhysicalNetworkVO pnw = ApiDBUtils.findPhysicalNetworkById(guestVlan.getPhysicalNetworkId());
|
||||
if (pnw != null) {
|
||||
guestVlanResponse.setPhysicalNetworkId(pnw.getUuid());
|
||||
guestVlanResponse.setPhysicalNetworkName(pnw.getName());
|
||||
}
|
||||
if (guestVlan.getAccountGuestVlanMapId() != null) {
|
||||
guestVlanResponse.setDedicated(true);
|
||||
} else {
|
||||
guestVlanResponse.setDedicated(false);
|
||||
}
|
||||
if (guestVlan.getTakenAt() != null) {
|
||||
guestVlanResponse.setAllocationState("Allocated");
|
||||
guestVlanResponse.setTaken(guestVlan.getTakenAt());
|
||||
} else {
|
||||
guestVlanResponse.setAllocationState("Free");
|
||||
}
|
||||
|
||||
List<NetworkVO> networks = networkDao.listByZoneAndUriAndGuestType(guestVlan.getDataCenterId(), guestVlan.getVnet(), null);
|
||||
List<NetworkResponse> networkResponses = new ArrayList<NetworkResponse>();
|
||||
for (Network network : networks) {
|
||||
NetworkResponse ntwkRsp = createNetworkResponse(ResponseView.Full, network);
|
||||
networkResponses.add(ntwkRsp);
|
||||
}
|
||||
guestVlanResponse.setNetworks(networkResponses);
|
||||
|
||||
return guestVlanResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkPermissionsResponse createNetworkPermissionsResponse(NetworkPermission permission) {
|
||||
Long networkOwnerDomain = null;
|
||||
Network network = ApiDBUtils.findNetworkById(permission.getNetworkId());
|
||||
|
||||
NetworkPermissionsResponse response = new NetworkPermissionsResponse();
|
||||
response.setNetworkId(network.getUuid());
|
||||
|
||||
Account networkOwner = ApiDBUtils.findAccountById(network.getAccountId());
|
||||
if (networkOwner != null) {
|
||||
networkOwnerDomain = networkOwner.getDomainId();
|
||||
if (networkOwnerDomain != null) {
|
||||
Domain domain = ApiDBUtils.findDomainById(networkOwnerDomain);
|
||||
if (domain != null) {
|
||||
response.setDomainId(domain.getUuid());
|
||||
response.setDomainName(domain.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Account account = ApiDBUtils.findAccountById(permission.getAccountId());
|
||||
response.setAccountName(account.getName());
|
||||
response.setAccountId(account.getUuid());
|
||||
if (account.getType() == Account.Type.PROJECT) {
|
||||
// convert account to projectIds
|
||||
Project project = ApiDBUtils.findProjectByProjectAccountId(account.getId());
|
||||
|
||||
if (project.getUuid() != null && !project.getUuid().isEmpty()) {
|
||||
response.setProjectId(project.getUuid());
|
||||
} else {
|
||||
response.setProjectId(String.valueOf(project.getId()));
|
||||
}
|
||||
response.setProjectName(project.getName());
|
||||
}
|
||||
|
||||
response.setObjectName("networkpermission");
|
||||
return response;
|
||||
}
|
||||
|
||||
protected void handleCertificateResponse(String certStr, DirectDownloadCertificateResponse response) {
|
||||
try {
|
||||
Certificate cert = CertificateHelper.buildCertificate(certStr);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,9 @@ import org.apache.cloudstack.acl.SecurityChecker;
|
|||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd.CommandType;
|
||||
|
|
@ -291,7 +293,14 @@ public class ParamProcessWorker implements DispatchWorker {
|
|||
if (entityOwners != null) {
|
||||
owners = entityOwners.stream().map(id -> _accountMgr.getAccount(id)).toArray(Account[]::new);
|
||||
} else {
|
||||
owners = new Account[]{_accountMgr.getAccount(cmd.getEntityOwnerId())};
|
||||
if (cmd.getEntityOwnerId() == Account.ACCOUNT_ID_SYSTEM && cmd instanceof BaseAsyncCmd && ((BaseAsyncCmd)cmd).getInstanceType() == ApiCommandJobType.Network) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Skipping access check on the network owner if the owner is ROOT/system.");
|
||||
}
|
||||
owners = new Account[]{};
|
||||
} else {
|
||||
owners = new Account[]{_accountMgr.getAccount(cmd.getEntityOwnerId())};
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd instanceof BaseAsyncCreateCmd) {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
|||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
|
|
@ -4494,6 +4495,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
}
|
||||
}
|
||||
|
||||
boolean isSharedNetworkWithoutSpecifyVlan = _networkMgr.isSharedNetworkWithoutSpecifyVlan(_networkOfferingDao.findById(network.getNetworkOfferingId()));
|
||||
if (ipv4) {
|
||||
final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask);
|
||||
|
||||
|
|
@ -4518,69 +4520,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
|
||||
checkConflictsWithPortableIpRange(zoneId, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
|
||||
|
||||
// Throw an exception if this subnet overlaps with subnet on other VLAN,
|
||||
// if this is ip range extension, gateway, network mask should be same and ip range should not overlap
|
||||
|
||||
final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
|
||||
for (final VlanVO vlan : vlans) {
|
||||
final String otherVlanGateway = vlan.getVlanGateway();
|
||||
final String otherVlanNetmask = vlan.getVlanNetmask();
|
||||
// Continue if it's not IPv4
|
||||
if ( otherVlanGateway == null || otherVlanNetmask == null ) {
|
||||
continue;
|
||||
}
|
||||
if ( vlan.getNetworkId() == null ) {
|
||||
continue;
|
||||
}
|
||||
final String otherCidr = NetUtils.getCidrFromGatewayAndNetmask(otherVlanGateway, otherVlanNetmask);
|
||||
if( !NetUtils.isNetworksOverlap(newCidr, otherCidr)) {
|
||||
continue;
|
||||
}
|
||||
// from here, subnet overlaps
|
||||
if (vlanId.toLowerCase().contains(Vlan.UNTAGGED) || UriUtils.checkVlanUriOverlap(
|
||||
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
|
||||
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
|
||||
// For untagged VLAN Id and overlapping URIs we need to expand and verify IP ranges
|
||||
final String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
|
||||
final String otherVlanStartIP = otherVlanIpRange[0];
|
||||
String otherVlanEndIP = null;
|
||||
if (otherVlanIpRange.length > 1) {
|
||||
otherVlanEndIP = otherVlanIpRange[1];
|
||||
}
|
||||
|
||||
// extend IP range
|
||||
if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
|
||||
throw new InvalidParameterValueException("The IP range has already been added with gateway "
|
||||
+ otherVlanGateway + " ,and netmask " + otherVlanNetmask
|
||||
+ ", Please specify the gateway/netmask if you want to extend ip range" );
|
||||
}
|
||||
if (!NetUtils.is31PrefixCidr(newCidr)) {
|
||||
if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
|
||||
throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
|
||||
" Please specify a different start IP/end IP.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For tagged or non-overlapping URIs we need to ensure there is no Public traffic type
|
||||
boolean overlapped = false;
|
||||
if (network.getTrafficType() == TrafficType.Public) {
|
||||
overlapped = true;
|
||||
} else {
|
||||
final Long nwId = vlan.getNetworkId();
|
||||
if (nwId != null) {
|
||||
final Network nw = _networkModel.getNetwork(nwId);
|
||||
if (nw != null && nw.getTrafficType() == TrafficType.Public) {
|
||||
overlapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (overlapped) {
|
||||
throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag()
|
||||
+ " in zone " + zone.getName()
|
||||
+ " has overlapped with the subnet. Please specify a different gateway/netmask.");
|
||||
}
|
||||
}
|
||||
if (!isSharedNetworkWithoutSpecifyVlan) {
|
||||
checkZoneVlanIpOverlap(zone, network, newCidr, vlanId, vlanGateway, vlanNetmask, startIP, endIP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4611,6 +4552,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
}
|
||||
|
||||
// Check if the vlan is being used
|
||||
if (isSharedNetworkWithoutSpecifyVlan) {
|
||||
bypassVlanOverlapCheck = true;
|
||||
}
|
||||
if (!bypassVlanOverlapCheck && _zoneDao.findVnet(zoneId, physicalNetworkId, BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId))).size() > 0) {
|
||||
throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
|
||||
+ zone.getName());
|
||||
|
|
@ -4632,6 +4576,68 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
return vlan;
|
||||
}
|
||||
|
||||
private void checkZoneVlanIpOverlap(DataCenterVO zone, Network network, String newCidr, String vlanId, String vlanGateway, String vlanNetmask, String startIP, String endIP) {
|
||||
// Throw an exception if this subnet overlaps with subnet on other VLAN,
|
||||
// if this is ip range extension, gateway, network mask should be same and ip range should not overlap
|
||||
|
||||
final List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
|
||||
for (final VlanVO vlan : vlans) {
|
||||
final String otherVlanGateway = vlan.getVlanGateway();
|
||||
final String otherVlanNetmask = vlan.getVlanNetmask();
|
||||
// Continue if it's not IPv4
|
||||
if (ObjectUtils.anyNull(otherVlanGateway, otherVlanNetmask, vlan.getNetworkId())) {
|
||||
continue;
|
||||
}
|
||||
final String otherCidr = NetUtils.getCidrFromGatewayAndNetmask(otherVlanGateway, otherVlanNetmask);
|
||||
if( !NetUtils.isNetworksOverlap(newCidr, otherCidr)) {
|
||||
continue;
|
||||
}
|
||||
// from here, subnet overlaps
|
||||
if (vlanId.toLowerCase().contains(Vlan.UNTAGGED) || UriUtils.checkVlanUriOverlap(
|
||||
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlanId)),
|
||||
BroadcastDomainType.getValue(BroadcastDomainType.fromString(vlan.getVlanTag())))) {
|
||||
// For untagged VLAN Id and overlapping URIs we need to expand and verify IP ranges
|
||||
final String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
|
||||
final String otherVlanStartIP = otherVlanIpRange[0];
|
||||
String otherVlanEndIP = null;
|
||||
if (otherVlanIpRange.length > 1) {
|
||||
otherVlanEndIP = otherVlanIpRange[1];
|
||||
}
|
||||
|
||||
// extend IP range
|
||||
if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
|
||||
throw new InvalidParameterValueException("The IP range has already been added with gateway "
|
||||
+ otherVlanGateway + " ,and netmask " + otherVlanNetmask
|
||||
+ ", Please specify the gateway/netmask if you want to extend ip range" );
|
||||
}
|
||||
if (!NetUtils.is31PrefixCidr(newCidr) && NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
|
||||
throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
|
||||
" Please specify a different start IP/end IP.");
|
||||
}
|
||||
} else {
|
||||
// For tagged or non-overlapping URIs we need to ensure there is no Public traffic type
|
||||
boolean overlapped = false;
|
||||
if (network.getTrafficType() == TrafficType.Public) {
|
||||
overlapped = true;
|
||||
} else {
|
||||
final Long nwId = vlan.getNetworkId();
|
||||
if (nwId != null) {
|
||||
final Network nw = _networkModel.getNetwork(nwId);
|
||||
if (nw != null && nw.getTrafficType() == TrafficType.Public) {
|
||||
overlapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (overlapped) {
|
||||
throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag()
|
||||
+ " in zone " + zone.getName()
|
||||
+ " has overlapped with the subnet. Please specify a different gateway/netmask.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VlanVO commitVlanAndIpRange(final long zoneId, final long networkId, final long physicalNetworkId, final Long podId, final String startIP, final String endIP,
|
||||
final String vlanGateway, final String vlanNetmask, final String vlanId, final Domain domain, final Account vlanOwner, final String vlanIp6Gateway, final String vlanIp6Cidr,
|
||||
final boolean ipv4, final DataCenterVO zone, final VlanType vlanType, final String ipv6Range, final String ipRange, final boolean forSystemVms) {
|
||||
|
|
@ -5025,7 +5031,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
@Override
|
||||
public void doInTransactionWithoutResult(final TransactionStatus status) {
|
||||
_publicIpAddressDao.deletePublicIPRange(vlanDbId);
|
||||
s_logger.debug(String.format("Delete Public IP Range (from user_ip_address, where vlan_db_d=%s)", vlanDbId));
|
||||
s_logger.debug(String.format("Delete Public IP Range (from user_ip_address, where vlan_db_id=%s)", vlanDbId));
|
||||
|
||||
_vlanDao.remove(vlanDbId);
|
||||
s_logger.debug(String.format("Mark vlan as Remove vlan (vlan_db_id=%s)", vlanDbId));
|
||||
|
|
@ -6037,14 +6043,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
final int multicastRate = multicastRateStr == null ? 10 : Integer.parseInt(multicastRateStr);
|
||||
tags = com.cloud.utils.StringUtils.cleanupTags(tags);
|
||||
|
||||
// specifyVlan should always be true for Shared network offerings
|
||||
if (!specifyVlan && type == GuestType.Shared) {
|
||||
Set<Provider> connectivityProviders = serviceProviderMap != null ? serviceProviderMap.get(Service.Connectivity) : null;
|
||||
if (CollectionUtils.isEmpty(connectivityProviders) || !_networkModel.providerSupportsCapability(connectivityProviders, Service.Connectivity, Capability.NoVlan)) {
|
||||
throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type);
|
||||
}
|
||||
}
|
||||
|
||||
// specifyIpRanges should always be true for Shared networks
|
||||
// specifyIpRanges can only be true for Isolated networks with no Source
|
||||
// Nat service
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ 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.lb.dao.ApplicationLoadBalancerRuleDao;
|
||||
import org.apache.cloudstack.network.NetworkPermissionVO;
|
||||
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -74,6 +76,8 @@ import com.cloud.network.addr.PublicIp;
|
|||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.NetworkAccountDao;
|
||||
import com.cloud.network.dao.NetworkAccountVO;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkDomainDao;
|
||||
import com.cloud.network.dao.NetworkDomainVO;
|
||||
|
|
@ -91,6 +95,7 @@ import com.cloud.network.element.IpDeployer;
|
|||
import com.cloud.network.element.IpDeployingRequester;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||
|
|
@ -168,6 +173,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
VpcGatewayDao _vpcGatewayDao;
|
||||
@Inject
|
||||
ProjectDao projectDao;
|
||||
@Inject
|
||||
NetworkPermissionDao _networkPermissionDao;
|
||||
|
||||
private List<NetworkElement> networkElements;
|
||||
|
||||
|
|
@ -179,6 +186,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
this.networkElements = networkElements;
|
||||
}
|
||||
|
||||
@Inject
|
||||
NetworkAccountDao _networkAccountDao;
|
||||
@Inject
|
||||
NetworkDomainDao _networkDomainDao;
|
||||
@Inject
|
||||
|
|
@ -217,7 +226,6 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
private NetworkService _networkService;
|
||||
|
||||
private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String, NetworkOfferingVO>(5);
|
||||
static Long s_privateOfferingId = null;
|
||||
|
||||
SearchBuilder<IPAddressVO> IpAddressSearch;
|
||||
SearchBuilder<NicVO> NicForTrafficTypeSearch;
|
||||
|
|
@ -1665,26 +1673,11 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", network does not have an owner");
|
||||
if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) {
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Project project = projectDao.findByProjectAccountId(network.getAccountId());
|
||||
if (project == null) {
|
||||
throw new CloudRuntimeException("Unable to find project to which the network belongs to");
|
||||
}
|
||||
ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
if (projectAccountUser != null) {
|
||||
if (!_projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
} else {
|
||||
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO) network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
}
|
||||
checkProjectNetworkPermissions(owner, networkOwner, network);
|
||||
} else {
|
||||
List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
|
||||
if (networkMap == null || networkMap.isEmpty()) {
|
||||
NetworkPermissionVO networkPermission = _networkPermissionDao.findByNetworkAndAccount(network.getId(), owner.getId());
|
||||
if (CollectionUtils.isEmpty(networkMap) && networkPermission == null) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
|
|
@ -1702,6 +1695,131 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
}
|
||||
}
|
||||
|
||||
private void checkProjectNetworkPermissions(Account owner, Account networkOwner, Network network){
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Project project = projectDao.findByProjectAccountId(networkOwner.getId());
|
||||
if (project == null) {
|
||||
throw new CloudRuntimeException("Unable to find project to which the network belongs to");
|
||||
}
|
||||
ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
if (projectAccountUser != null) {
|
||||
if (!_projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), networkOwner.getId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
} else {
|
||||
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), networkOwner.getId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO) network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkNetworkOperatePermissions(Account owner, Network network) {
|
||||
if (network == null) {
|
||||
throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
|
||||
}
|
||||
if (owner.getType() == Account.Type.ADMIN) {
|
||||
return;
|
||||
}
|
||||
if (network.getGuestType() == GuestType.Shared) {
|
||||
checkSharedNetworkOperatePermissions(owner, network);
|
||||
} else {
|
||||
checkNonSharedNetworkOperatePermissions(owner, network);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkRouterPermissions(Account owner, VirtualRouter router) {
|
||||
Account account = _accountMgr.getAccount(router.getAccountId());
|
||||
try {
|
||||
_accountMgr.checkAccess(owner, null, true, account);
|
||||
return;
|
||||
} catch (PermissionDeniedException ex) {
|
||||
s_logger.info("Account " + owner + " do not have permission on router owner " + account);
|
||||
}
|
||||
List<NicVO> routerNics = _nicDao.listByVmId(router.getId());
|
||||
for (final Nic routerNic : routerNics) {
|
||||
final NetworkVO network = _networksDao.findById(routerNic.getNetworkId());
|
||||
if (TrafficType.Guest.equals(network.getTrafficType())) {
|
||||
checkNetworkOperatePermissions(owner, network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNonSharedNetworkOperatePermissions(Account owner, Network network) {
|
||||
// check on isolated/L2 networks
|
||||
Account networkOwner = _accountDao.findByIdIncludingRemoved(network.getAccountId());
|
||||
if (owner.getType() == Account.Type.DOMAIN_ADMIN) {
|
||||
if (!_domainDao.isChildDomain(owner.getDomainId(), networkOwner.getDomainId())) {
|
||||
throw new PermissionDeniedException(String.format("network %s cannot be operated by domain admin %s", network, owner));
|
||||
}
|
||||
} else if (owner.getType() == Account.Type.NORMAL) {
|
||||
if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) {
|
||||
checkProjectNetworkPermissions(owner, networkOwner, network);
|
||||
} else if (networkOwner.getAccountId() != owner.getAccountId()) {
|
||||
throw new PermissionDeniedException(String.format("network %s cannot be operated by normal user %s", network, owner));
|
||||
}
|
||||
} else {
|
||||
throw new PermissionDeniedException(String.format("network %s cannot be operated by this account %s", network, owner));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSharedNetworkOperatePermissions(Account owner, Network network) {
|
||||
NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
if (networkOffering.isSpecifyVlan() && owner.getType() != Account.Type.ADMIN) {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s with specifyvlan=true can only be operated by root admin", network));
|
||||
}
|
||||
if (owner.getType() == Account.Type.DOMAIN_ADMIN) {
|
||||
if (network.getAclType() == ACLType.Domain) {
|
||||
// Allow domain admins to operate shared network for their domain.
|
||||
Long networkDomainId = getDomainIdForSharedNetwork(network);
|
||||
if (!_domainDao.isChildDomain(owner.getDomainId(), networkDomainId)) {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s belongs to another domain cannot be operated by domain admin %s", network, owner));
|
||||
}
|
||||
} else if (network.getAclType() == ACLType.Account) {
|
||||
// Allow domain admins to operate shared network for an account in their domain.
|
||||
Long networkAccountId = getAccountIdForSharedNetwork(network);
|
||||
if (!_domainDao.isChildDomain(owner.getDomainId(), _accountDao.findByIdIncludingRemoved(networkAccountId).getDomainId())) {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s belongs to an account in another domain cannot be operated by domain admin %s", network, owner));
|
||||
}
|
||||
}
|
||||
} else if (owner.getType() == Account.Type.NORMAL) {
|
||||
// Allow normal users to operate shared network for themselves.
|
||||
if (network.getAclType() == ACLType.Account) {
|
||||
// Allow domain admin to operate shared network for an account in its domain.
|
||||
Long networkAccountId = getAccountIdForSharedNetwork(network);
|
||||
Account networkOwner = _accountDao.findByIdIncludingRemoved(networkAccountId);
|
||||
if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) {
|
||||
checkProjectNetworkPermissions(owner, networkOwner, network);
|
||||
} else if (networkOwner.getAccountId() != owner.getAccountId()) {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s belongs to another account cannot be operated by normal user %s", network, owner));
|
||||
}
|
||||
} else {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s belongs to domain cannot be operated by normal user %s", network, owner));
|
||||
}
|
||||
} else if (owner.getType() != Account.Type.ADMIN) {
|
||||
throw new PermissionDeniedException(String.format("Shared network %s cannot be operated by account %s with type = %d", network, owner, owner.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
private Long getAccountIdForSharedNetwork(Network network) {
|
||||
NetworkAccountVO networkAccountMap = _networkAccountDao.getAccountNetworkMapByNetworkId(network.getId());
|
||||
if (networkAccountMap == null) {
|
||||
throw new CloudRuntimeException(String.format("Cannot find account info for Shared network %s with aclType=Account", network));
|
||||
}
|
||||
return networkAccountMap.getAccountId();
|
||||
}
|
||||
|
||||
private Long getDomainIdForSharedNetwork(Network network) {
|
||||
NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(network.getId());
|
||||
if (networkDomainMap == null) {
|
||||
throw new CloudRuntimeException(String.format("Cannot find domain info for Shared network %s with aclType=Domain", network));
|
||||
}
|
||||
return networkDomainMap.getDomainId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultPublicTrafficLabel(long dcId, HypervisorType hypervisorType) {
|
||||
try {
|
||||
|
|
@ -2089,10 +2207,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
|
||||
storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
|
||||
_systemNetworks.put(NetworkOffering.SystemStorageNetwork, storageNetworkOffering);
|
||||
NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
|
||||
NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated, true);
|
||||
privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
|
||||
_systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering);
|
||||
s_privateOfferingId = privateGatewayNetworkOffering.getId();
|
||||
NetworkOfferingVO privateGatewayNetworkOfferingWithoutVlan = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan, GuestType.Isolated, false);
|
||||
privateGatewayNetworkOfferingWithoutVlan = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOfferingWithoutVlan);
|
||||
_systemNetworks.put(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan, privateGatewayNetworkOfferingWithoutVlan);
|
||||
|
||||
IpAddressSearch = _ipAddressDao.createSearchBuilder();
|
||||
IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
|
|
@ -25,6 +27,7 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
|
@ -35,6 +38,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
|
@ -46,10 +50,16 @@ import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
|
|||
import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListGuestVlansCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListNetworksCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RemoveNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ResetNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
|
|
@ -61,6 +71,8 @@ import org.apache.cloudstack.framework.config.Configurable;
|
|||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
import org.apache.cloudstack.network.NetworkPermissionVO;
|
||||
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
|
||||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -139,6 +151,7 @@ import com.cloud.network.element.NetworkElement;
|
|||
import com.cloud.network.element.OvsProviderVO;
|
||||
import com.cloud.network.element.VirtualRouterElement;
|
||||
import com.cloud.network.element.VpcVirtualRouterElement;
|
||||
import com.cloud.network.guru.GuestNetworkGuru;
|
||||
import com.cloud.network.guru.NetworkGuru;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
|
|
@ -181,6 +194,7 @@ import com.cloud.utils.component.ManagerBase;
|
|||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
|
|
@ -259,6 +273,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
@Inject
|
||||
NetworkDao _networksDao = null;
|
||||
@Inject
|
||||
NetworkPermissionDao _networkPermissionDao = null;
|
||||
@Inject
|
||||
NicDao _nicDao = null;
|
||||
@Inject
|
||||
RulesManager _rulesMgr;
|
||||
|
|
@ -306,7 +322,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
@Inject
|
||||
InternalLoadBalancerElementService _internalLbElementSvc;
|
||||
@Inject
|
||||
DataCenterVnetDao _datacneterVnet;
|
||||
DataCenterVnetDao _dcVnetDao;
|
||||
@Inject
|
||||
AccountGuestVlanMapDao _accountGuestVlanMapDao;
|
||||
@Inject
|
||||
|
|
@ -1228,6 +1244,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
String isolatedPvlan = cmd.getIsolatedPvlan();
|
||||
String externalId = cmd.getExternalId();
|
||||
String isolatedPvlanType = cmd.getIsolatedPvlanType();
|
||||
Long associatedNetworkId = cmd.getAssociatedNetworkId();
|
||||
|
||||
// Validate network offering
|
||||
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||
|
|
@ -1302,15 +1319,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
if (ntwkOff.getGuestType() == GuestType.Isolated || ntwkOff.getGuestType() == GuestType.L2) {
|
||||
aclType = ACLType.Account;
|
||||
} else if (ntwkOff.getGuestType() == GuestType.Shared) {
|
||||
aclType = ACLType.Domain;
|
||||
if (_accountMgr.isRootAdmin(caller.getId())) {
|
||||
aclType = ACLType.Domain;
|
||||
} else if (_accountMgr.isNormalUser(caller.getId())) {
|
||||
aclType = ACLType.Account;
|
||||
} else {
|
||||
throw new InvalidParameterValueException("AclType must be specified for shared network created by domain admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only Admin can create Shared networks
|
||||
if ((ntwkOff.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
|
||||
}
|
||||
|
||||
if (ntwkOff.getGuestType() != GuestType.Shared && (!StringUtils.isAllBlank(routerIp, routerIpv6))) {
|
||||
throw new InvalidParameterValueException("Router IP can be specified only for Shared networks");
|
||||
}
|
||||
|
|
@ -1451,12 +1469,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
validateRouterIps(routerIp, routerIpv6, startIP, endIP, gateway, netmask, startIPv6, endIPv6, ip6Cidr);
|
||||
|
||||
if (StringUtils.isNotBlank(isolatedPvlan) && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() == GuestType.Isolated)) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with advanced shared or L2 network!");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(isolatedPvlan) && ipv6) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
|
||||
if (StringUtils.isNotBlank(isolatedPvlan)) {
|
||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Only ROOT admin is allowed to create Private VLAN network");
|
||||
}
|
||||
if (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() == GuestType.Isolated) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with advanced shared or L2 network!");
|
||||
}
|
||||
if (ipv6) {
|
||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with IPv4!");
|
||||
}
|
||||
}
|
||||
|
||||
Pair<String, PVlanType> pvlanPair = getPrivateVlanPair(isolatedPvlan, isolatedPvlanType, vlanId);
|
||||
|
|
@ -1473,6 +1495,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
validateNetworkOfferingForNonRootAdminUser(ntwkOff);
|
||||
}
|
||||
|
||||
// Ignore vlanId if it is passed but specifyvlan=false in network offering
|
||||
if (ntwkOff.getGuestType() == GuestType.Shared && ! ntwkOff.isSpecifyVlan() && vlanId != null) {
|
||||
throw new InvalidParameterValueException("Cannot specify vlanId when create a network from network offering with specifyvlan=false");
|
||||
}
|
||||
|
||||
// Don't allow to specify vlan if the caller is not ROOT admin
|
||||
if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.isSpecifyVlan() || vlanId != null || bypassVlanOverlapCheck)) {
|
||||
throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
|
||||
|
|
@ -1531,9 +1558,23 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
throwInvalidIdException("Network offering with specified id doesn't support adding multiple ip ranges", ntwkOff.getUuid(), "networkOfferingId");
|
||||
}
|
||||
|
||||
Network associatedNetwork = null;
|
||||
if (associatedNetworkId != null) {
|
||||
if (vlanId != null) {
|
||||
throw new InvalidParameterValueException("Associated network and vlanId are mutually exclusive");
|
||||
}
|
||||
if (!_networkMgr.isSharedNetworkWithoutSpecifyVlan(ntwkOff)) {
|
||||
throw new InvalidParameterValueException("Can only create Shared network with associated network if specifyVlan is false");
|
||||
}
|
||||
associatedNetwork = implementAssociatedNetwork(associatedNetworkId, caller, owner, zone,
|
||||
aclType == ACLType.Domain ? domainId : null,
|
||||
aclType == ACLType.Account ? owner.getAccountId() : null,
|
||||
cidr, startIP, endIP);
|
||||
}
|
||||
|
||||
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId,
|
||||
domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, secondaryVlanId, privateVlanType, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
|
||||
externalId, routerIp, routerIpv6);
|
||||
externalId, routerIp, routerIpv6, associatedNetwork);
|
||||
|
||||
if (hideIpAddressUsage) {
|
||||
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
|
||||
|
|
@ -1541,27 +1582,72 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
// if the network offering has persistent set to true, implement the network
|
||||
if (ntwkOff.isPersistent()) {
|
||||
try {
|
||||
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
||||
UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
|
||||
Journal journal = new Journal.LogJournal("Implementing " + network, s_logger);
|
||||
ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
|
||||
s_logger.debug("Implementing network " + network + " as a part of network provision for persistent network");
|
||||
Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(network.getId(), dest, context);
|
||||
if (implementedNetwork == null || implementedNetwork.first() == null) {
|
||||
s_logger.warn("Failed to provision the network " + network);
|
||||
}
|
||||
network = implementedNetwork.second();
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
|
||||
CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
|
||||
e.addProxyObject(network.getUuid(), "networkId");
|
||||
throw e;
|
||||
}
|
||||
return implementedNetworkInCreation(caller, zone, network);
|
||||
}
|
||||
return network;
|
||||
}
|
||||
|
||||
private Network implementAssociatedNetwork(Long associatedNetworkId, Account caller, Account owner, DataCenter zone, Long domainId, Long accountId,
|
||||
String cidr, String startIp, String endIp) throws InsufficientCapacityException {
|
||||
Network associatedNetwork = _networksDao.findById(associatedNetworkId);
|
||||
if (associatedNetwork == null) {
|
||||
throw new InvalidParameterValueException("Cannot find associated network with id = " + associatedNetworkId);
|
||||
}
|
||||
if (associatedNetwork.getGuestType() != GuestType.Isolated && associatedNetwork.getGuestType() != GuestType.L2) {
|
||||
throw new InvalidParameterValueException("Associated network MUST be an Isolated or L2 network");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, associatedNetwork);
|
||||
if (accountId != null && associatedNetwork.getAccountId() != accountId) {
|
||||
throw new InvalidParameterValueException("The new network and associated network MUST be owned by same account");
|
||||
}
|
||||
if (domainId != null && associatedNetwork.getDomainId() != domainId) {
|
||||
throw new InvalidParameterValueException("The new network and associated network MUST be in same domain");
|
||||
}
|
||||
if (cidr != null && associatedNetwork.getCidr() != null && NetUtils.isNetworksOverlap(cidr, associatedNetwork.getCidr())) {
|
||||
throw new InvalidParameterValueException("The cidr overlaps with associated network: " + associatedNetwork.getName());
|
||||
}
|
||||
List<NetworkDetailVO> associatedNetworks = _networkDetailsDao.findDetails(Network.AssociatedNetworkId, String.valueOf(associatedNetworkId), null);
|
||||
for (NetworkDetailVO networkDetailVO : associatedNetworks) {
|
||||
NetworkVO associatedNetwork2 = _networksDao.findById(networkDetailVO.getResourceId());
|
||||
if (associatedNetwork2 != null) {
|
||||
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(associatedNetwork2.getId());
|
||||
if (vlans.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String startIP2 = vlans.get(0).getIpRange().split("-")[0];
|
||||
String endIP2 = vlans.get(0).getIpRange().split("-")[1];
|
||||
if (StringUtils.isNoneBlank(startIp, startIP2) && NetUtils.ipRangesOverlap(startIp, endIp, startIP2, endIP2)) {
|
||||
throw new InvalidParameterValueException("The startIp/endIp overlaps with network: " + associatedNetwork2.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
associatedNetwork = implementedNetworkInCreation(caller, zone, associatedNetwork);
|
||||
if (associatedNetwork == null || (associatedNetwork.getState() != Network.State.Implemented && associatedNetwork.getState() != Network.State.Setup)) {
|
||||
throw new InvalidParameterValueException("Unable to implement associated network " + associatedNetwork);
|
||||
}
|
||||
return associatedNetwork;
|
||||
}
|
||||
|
||||
private Network implementedNetworkInCreation(final Account caller, final DataCenter zone, final Network network) throws InsufficientCapacityException {
|
||||
try {
|
||||
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
||||
UserVO callerUser = _userDao.findById(CallContext.current().getCallingUserId());
|
||||
Journal journal = new Journal.LogJournal("Implementing " + network, s_logger);
|
||||
ReservationContext context = new ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, caller);
|
||||
s_logger.debug("Implementing network " + network + " as a part of network provision for persistent network");
|
||||
Pair<? extends NetworkGuru, ? extends Network> implementedNetwork = _networkMgr.implementNetwork(network.getId(), dest, context);
|
||||
if (implementedNetwork == null || implementedNetwork.first() == null) {
|
||||
s_logger.warn("Failed to provision the network " + network);
|
||||
}
|
||||
return implementedNetwork.second();
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to implement persistent guest network " + network + "due to ", ex);
|
||||
CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network");
|
||||
e.addProxyObject(network.getUuid(), "networkId");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void validateNetworkOfferingForNonRootAdminUser(NetworkOfferingVO ntwkOff) {
|
||||
if (ntwkOff.getTrafficType() != TrafficType.Guest) {
|
||||
throw new InvalidParameterValueException("This user can only create a Guest network");
|
||||
|
|
@ -1569,9 +1655,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
if (ntwkOff.getGuestType() == GuestType.L2 || ntwkOff.getGuestType() == GuestType.Isolated) {
|
||||
s_logger.debug(String.format("Creating a network from network offerings having traffic type [%s] and network type [%s].",
|
||||
TrafficType.Guest, ntwkOff.getGuestType()));
|
||||
} else if (ntwkOff.getGuestType() == GuestType.Shared && ! ntwkOff.isSpecifyVlan()) {
|
||||
s_logger.debug(String.format("Creating a network from network offerings having traffic type [%s] and network type [%s] with specifyVlan=%s.",
|
||||
TrafficType.Guest, GuestType.Shared, ntwkOff.isSpecifyVlan()));
|
||||
} else {
|
||||
throw new InvalidParameterValueException(
|
||||
String.format("This user can only create an %s network or a %s network.", GuestType.Isolated, GuestType.L2));
|
||||
String.format("This user can only create an %s network, a %s network or a %s network with specifyVlan=false.", GuestType.Isolated, GuestType.L2, GuestType.Shared));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1618,11 +1707,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
}
|
||||
}
|
||||
|
||||
private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain, final String vlanId,
|
||||
private Network commitNetwork(final Long networkOfferingId, final String gateway, final String startIP, final String endIP, final String netmask, final String networkDomain, final String vlanIdFinal,
|
||||
final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
|
||||
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr,
|
||||
final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final PVlanType isolatedPvlanType, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, final Account ownerFinal,
|
||||
final String cidr, final boolean createVlan, final String externalId, String routerIp, String routerIpv6) throws InsufficientCapacityException, ResourceAllocationException {
|
||||
final String cidr, final boolean createVlan, final String externalId, String routerIp, String routerIpv6,
|
||||
final Network associatedNetwork) throws InsufficientCapacityException, ResourceAllocationException {
|
||||
try {
|
||||
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
|
||||
@Override
|
||||
|
|
@ -1645,6 +1735,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
|
||||
}
|
||||
|
||||
String vlanId = vlanIdFinal;
|
||||
if (createVlan && vlanId == null && ntwkOff.getGuestType() == Network.GuestType.Shared && ! ntwkOff.isSpecifyVlan()) {
|
||||
if (associatedNetwork != null) {
|
||||
// Get vlanId from associated network
|
||||
vlanId = associatedNetwork.getBroadcastUri().toString();
|
||||
} else {
|
||||
// Allocate a vnet to shared network with specifyvlan=false
|
||||
vlanId = _dcDao.allocateVnet(zoneId, physicalNetworkId, owner.getAccountId(), null, GuestNetworkGuru.UseSystemGuestVlans.valueIn(owner.getAccountId()));
|
||||
if (vlanId == null) {
|
||||
throw new InvalidParameterValueException("Cannot allocate a vnet for this Shared network");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create guest network
|
||||
Network network = null;
|
||||
if (vpcId != null) {
|
||||
|
|
@ -1680,11 +1784,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6);
|
||||
}
|
||||
|
||||
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
|
||||
if (createVlan && network != null) {
|
||||
// Create vlan ip range
|
||||
_configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, false, null, startIP, endIP, gateway, netmask, vlanId,
|
||||
bypassVlanOverlapCheck, null, null, startIPv6, endIPv6, ip6Gateway, ip6Cidr);
|
||||
}
|
||||
if (associatedNetwork != null) {
|
||||
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.AssociatedNetworkId, String.valueOf(associatedNetwork.getId()), true));
|
||||
}
|
||||
return network;
|
||||
}
|
||||
});
|
||||
|
|
@ -1733,6 +1840,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
Boolean forVpc = cmd.getForVpc();
|
||||
Boolean display = cmd.getDisplay();
|
||||
Long networkOfferingId = cmd.getNetworkOfferingId();
|
||||
Long associatedNetworkId = cmd.getAssociatedNetworkId();
|
||||
String networkFilterStr = cmd.getNetworkFilter();
|
||||
|
||||
String vlanId = null;
|
||||
if (cmd instanceof ListNetworksCmdByAdmin) {
|
||||
vlanId = ((ListNetworksCmdByAdmin)cmd).getVlan();
|
||||
}
|
||||
|
||||
// 1) default is system to false if not specified
|
||||
// 2) reset parameter to false if it's specified by a non-ROOT user
|
||||
|
|
@ -1740,6 +1854,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
isSystem = false;
|
||||
}
|
||||
|
||||
// check network filter
|
||||
if (networkFilterStr != null && !EnumUtils.isValidEnumIgnoreCase(Network.NetworkFilter.class, networkFilterStr)) {
|
||||
throw new InvalidParameterValueException("Invalid value of networkfilter: " + networkFilterStr);
|
||||
}
|
||||
Network.NetworkFilter networkFilter = networkFilterStr != null ? EnumUtils.getEnumIgnoreCase(Network.NetworkFilter.class, networkFilterStr) : Network.NetworkFilter.All;
|
||||
|
||||
// Account/domainId parameters and isSystem are mutually exclusive
|
||||
if (isSystem != null && isSystem && (accountName != null || domainId != null)) {
|
||||
throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified");
|
||||
|
|
@ -1856,34 +1976,60 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
|
||||
|
||||
if (associatedNetworkId != null) {
|
||||
SearchBuilder<NetworkDetailVO> associatedNetworkSearch = _networkDetailsDao.createSearchBuilder();
|
||||
associatedNetworkSearch.and("name", associatedNetworkSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
associatedNetworkSearch.and("value", associatedNetworkSearch.entity().getValue(), SearchCriteria.Op.EQ);
|
||||
sb.join("associatedNetworkSearch", associatedNetworkSearch, sb.entity().getId(), associatedNetworkSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
|
||||
}
|
||||
|
||||
List<NetworkVO> networksToReturn = new ArrayList<NetworkVO>();
|
||||
|
||||
if (isSystem == null || !isSystem) {
|
||||
if (!permittedAccounts.isEmpty()) {
|
||||
//get account level networks
|
||||
networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, permittedAccounts));
|
||||
//get domain level networks
|
||||
if (domainId != null) {
|
||||
if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
//get account level networks
|
||||
networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts));
|
||||
}
|
||||
if (domainId != null && Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
//get domain level networks
|
||||
networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, domainId, false));
|
||||
aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, domainId, false));
|
||||
}
|
||||
if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
// get shared networks
|
||||
List<NetworkVO> sharedNetworks = listSharedNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts);
|
||||
addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks);
|
||||
|
||||
}
|
||||
} else {
|
||||
//add account specific networks
|
||||
networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
|
||||
//add domain specific networks of domain + parent domains
|
||||
networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, path, isRecursive));
|
||||
//add networks of subdomains
|
||||
if (domainId == null) {
|
||||
networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter, caller.getDomainId(), true));
|
||||
if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
//add account specific networks
|
||||
networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive));
|
||||
}
|
||||
if (Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
//add domain specific networks of domain + parent domains
|
||||
networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive));
|
||||
//add networks of subdomains
|
||||
if (domainId == null) {
|
||||
networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, caller.getDomainId(), true));
|
||||
}
|
||||
}
|
||||
if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) {
|
||||
// get shared networks
|
||||
List<NetworkVO> sharedNetworks = listSharedNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive);
|
||||
addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId,
|
||||
null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display), searchFilter);
|
||||
null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter);
|
||||
}
|
||||
|
||||
if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) {
|
||||
|
|
@ -1930,10 +2076,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
return new Pair<List<? extends Network>, Integer>(networksToReturn, networksToReturn.size());
|
||||
}
|
||||
|
||||
private void addNetworksToReturnIfNotExist(final List<NetworkVO> networksToReturn, final List<NetworkVO> sharedNetworks) {
|
||||
Set<Long> networkIds = networksToReturn.stream()
|
||||
.map(NetworkVO::getId)
|
||||
.collect(Collectors.toSet());
|
||||
List<NetworkVO> sharedNetworksToReturn = sharedNetworks.stream()
|
||||
.filter(network -> ! networkIds.contains(network.getId()))
|
||||
.collect(Collectors.toList());
|
||||
networksToReturn.addAll(sharedNetworksToReturn);
|
||||
}
|
||||
|
||||
private SearchCriteria<NetworkVO> buildNetworkSearchCriteria(SearchBuilder<NetworkVO> sb, String keyword, Long id,
|
||||
Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId,
|
||||
Long networkOfferingId, String aclType, boolean skipProjectNetworks, Boolean restartRequired,
|
||||
Boolean specifyIpRanges, Long vpcId, Map<String, String> tags, Boolean display) {
|
||||
Boolean specifyIpRanges, Long vpcId, Map<String, String> tags, Boolean display, String vlanId, Long associatedNetworkId) {
|
||||
|
||||
SearchCriteria<NetworkVO> sc = sb.create();
|
||||
|
||||
|
|
@ -2007,6 +2163,17 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
sc.addAnd("networkOfferingId", SearchCriteria.Op.EQ, networkOfferingId);
|
||||
}
|
||||
|
||||
if (associatedNetworkId != null) {
|
||||
sc.setJoinParameters("associatedNetworkSearch", "name", Network.AssociatedNetworkId);
|
||||
sc.setJoinParameters("associatedNetworkSearch", "value", String.valueOf(associatedNetworkId));
|
||||
}
|
||||
|
||||
if (vlanId != null) {
|
||||
SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
|
||||
ssc.addOr("broadcastUri", SearchCriteria.Op.EQ, vlanId);
|
||||
ssc.addOr("broadcastUri", SearchCriteria.Op.LIKE, "%://" + vlanId);
|
||||
sc.addAnd("broadcastUri", SearchCriteria.Op.SC, ssc);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
|
|
@ -2097,6 +2264,49 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
}
|
||||
}
|
||||
|
||||
private List<NetworkVO> listSharedNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, List<Long> permittedAccounts) {
|
||||
List<Long> sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(permittedAccounts);
|
||||
if (!sharedNetworkIds.isEmpty()) {
|
||||
SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
|
||||
ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray());
|
||||
sc.addAnd("id", SearchCriteria.Op.SC, ssc);
|
||||
return _networksDao.search(sc, searchFilter);
|
||||
}
|
||||
return new ArrayList<NetworkVO>();
|
||||
}
|
||||
|
||||
private List<NetworkVO> listSharedNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
|
||||
Set<Long> allowedDomains = new HashSet<Long>();
|
||||
if (path != null) {
|
||||
if (isRecursive) {
|
||||
allowedDomains = _domainMgr.getDomainChildrenIds(path);
|
||||
} else {
|
||||
Domain domain = _domainDao.findDomainByPath(path);
|
||||
allowedDomains.add(domain.getId());
|
||||
}
|
||||
}
|
||||
List<Long> allowedDomainsList = new ArrayList<Long>(allowedDomains);
|
||||
|
||||
if (!allowedDomainsList.isEmpty()) {
|
||||
GenericSearchBuilder<AccountVO, Long> accountIdSearch = _accountDao.createSearchBuilder(Long.class);
|
||||
accountIdSearch.and("domainId", accountIdSearch.entity().getDomainId(), SearchCriteria.Op.IN);
|
||||
accountIdSearch.selectFields(accountIdSearch.entity().getId());
|
||||
accountIdSearch.done();
|
||||
SearchCriteria<Long> scAccount = accountIdSearch.create();
|
||||
scAccount.setParameters("domainId", allowedDomainsList.toArray());
|
||||
List<Long> allowedAccountsList = _accountDao.customSearch(scAccount, null);
|
||||
|
||||
List<Long> sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(allowedAccountsList);
|
||||
if (!sharedNetworkIds.isEmpty()) {
|
||||
SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
|
||||
ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray());
|
||||
sc.addAnd("id", SearchCriteria.Op.SC, ssc);
|
||||
return _networksDao.search(sc, searchFilter);
|
||||
}
|
||||
}
|
||||
return new ArrayList<NetworkVO>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_DELETE, eventDescription = "deleting network", async = true)
|
||||
public boolean deleteNetwork(long networkId, boolean forced) {
|
||||
|
|
@ -2111,15 +2321,17 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
throwInvalidIdException("Network with specified id is system and can't be removed", network.getUuid(), "networkId");
|
||||
}
|
||||
|
||||
Account owner = _accountMgr.getAccount(network.getAccountId());
|
||||
|
||||
// Only Admin can delete Shared networks
|
||||
if ((network.getGuestType() == GuestType.Shared) && !_accountMgr.isAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Only Admins can delete network with guest type " + network.getGuestType());
|
||||
List<NetworkDetailVO> associatedNetworks = _networkDetailsDao.findDetails(Network.AssociatedNetworkId, String.valueOf(networkId), null);
|
||||
for (NetworkDetailVO networkDetailVO : associatedNetworks) {
|
||||
NetworkVO associatedNetwork = _networksDao.findById(networkDetailVO.getResourceId());
|
||||
if (associatedNetwork != null) {
|
||||
String msg = String.format("Cannot delete network %s which is associated to another network %s", network.getUuid(), associatedNetwork.getUuid());
|
||||
s_logger.debug(msg);
|
||||
throw new InvalidParameterValueException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform permission check
|
||||
_accountMgr.checkAccess(caller, null, true, network);
|
||||
Account owner = _accountMgr.getAccount(network.getAccountId());
|
||||
|
||||
if (forced && !_accountMgr.isRootAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Delete network with 'forced' option can only be called by root admins");
|
||||
|
|
@ -2164,7 +2376,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
}
|
||||
|
||||
Account callerAccount = _accountMgr.getActiveAccountById(user.getAccountId());
|
||||
_accountMgr.checkAccess(callerAccount, null, true, network);
|
||||
_accountMgr.checkAccess(callerAccount, AccessType.OperateEntry, true, network);
|
||||
if (!network.isRedundant() && makeRedundant) {
|
||||
network.setRedundant(true);
|
||||
if (!_networksDao.update(network.getId(), network)) {
|
||||
|
|
@ -2356,7 +2568,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(callerAccount, null, true, network);
|
||||
_accountMgr.checkAccess(callerAccount, AccessType.OperateEntry, true, network);
|
||||
_accountMgr.checkAccess(_accountMgr.getActiveAccountById(network.getAccountId()), offering, _dcDao.findById(network.getDataCenterId()));
|
||||
|
||||
if (cmd instanceof UpdateNetworkCmdByAdmin) {
|
||||
|
|
@ -3367,7 +3579,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
removeVnets = getVnetsToremove(network, vnetranges);
|
||||
|
||||
//computing vnets to add
|
||||
vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
|
||||
vnetsInDb.addAll(_dcVnetDao.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
|
||||
tempVnets.addAll(vnetsInDb);
|
||||
for (Pair<Integer, Integer> vlan : vnetranges) {
|
||||
for (i = vlan.first(); i <= vlan.second(); i++) {
|
||||
|
|
@ -3409,7 +3621,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
s_logger.debug("removing vnet range " + removeVnetsFinal.toString() + " for the physicalNetwork id= " + network.getId() + " and zone id=" + network.getDataCenterId()
|
||||
+ " as a part of updatePhysicalNetwork call");
|
||||
//deleteVnets takes a list of strings to be removed. each string is a vnet.
|
||||
_datacneterVnet.deleteVnets(TransactionLegacy.currentTxn(), network.getDataCenterId(), network.getId(), removeVnetsFinal);
|
||||
_dcVnetDao.deleteVnets(TransactionLegacy.currentTxn(), network.getDataCenterId(), network.getId(), removeVnetsFinal);
|
||||
}
|
||||
_physicalNetworkDao.update(network.getId(), network);
|
||||
}
|
||||
|
|
@ -3445,7 +3657,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
// since adding a range adds each VNI to the database, need only check min/max
|
||||
for (String vnet : VnetRange) {
|
||||
s_logger.debug("Looking to see if VNI " + vnet + " already exists on another network in zone " + network.getDataCenterId());
|
||||
List<DataCenterVnetVO> vnis = _datacneterVnet.findVnet(network.getDataCenterId(), vnet);
|
||||
List<DataCenterVnetVO> vnis = _dcVnetDao.findVnet(network.getDataCenterId(), vnet);
|
||||
if (vnis != null && !vnis.isEmpty()) {
|
||||
for (DataCenterVnetVO vni : vnis) {
|
||||
if (vni.getPhysicalNetworkId() != network.getId()) {
|
||||
|
|
@ -3517,13 +3729,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
int i;
|
||||
List<String> removeVnets = new ArrayList<String>();
|
||||
HashSet<String> vnetsInDb = new HashSet<String>();
|
||||
vnetsInDb.addAll(_datacneterVnet.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
|
||||
vnetsInDb.addAll(_dcVnetDao.listVnetsByPhysicalNetworkAndDataCenter(network.getDataCenterId(), network.getId()));
|
||||
//remove all the vnets from vnets in db to check if there are any vnets that are not there in given list.
|
||||
//remove all the vnets not in the list of vnets passed by the user.
|
||||
if (vnetRanges.size() == 0) {
|
||||
//this implies remove all vlans.
|
||||
removeVnets.addAll(vnetsInDb);
|
||||
int allocated_vnets = _datacneterVnet.countAllocatedVnets(network.getId());
|
||||
int allocated_vnets = _dcVnetDao.countAllocatedVnets(network.getId());
|
||||
if (allocated_vnets > 0) {
|
||||
throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has " + allocated_vnets + " vnets in use");
|
||||
}
|
||||
|
|
@ -3546,8 +3758,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
String[] range = vnet.split("-");
|
||||
Integer start = Integer.parseInt(range[0]);
|
||||
Integer end = Integer.parseInt(range[1]);
|
||||
_datacneterVnet.lockRange(network.getDataCenterId(), network.getId(), start, end);
|
||||
List<DataCenterVnetVO> result = _datacneterVnet.listAllocatedVnetsInRange(network.getDataCenterId(), network.getId(), start, end);
|
||||
_dcVnetDao.lockRange(network.getDataCenterId(), network.getId(), start, end);
|
||||
List<DataCenterVnetVO> result = _dcVnetDao.listAllocatedVnetsInRange(network.getDataCenterId(), network.getId(), start, end);
|
||||
if (!result.isEmpty()) {
|
||||
throw new InvalidParameterValueException("physicalnetwork " + network.getId() + " has allocated vnets in the range " + start + "-" + end);
|
||||
|
||||
|
|
@ -3696,7 +3908,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_GUEST_VLAN_RANGE_DEDICATE, eventDescription = "dedicating guest vlan range", async = false)
|
||||
public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
|
||||
public GuestVlanRange dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
|
||||
String vlan = cmd.getVlan();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
|
|
@ -3771,7 +3983,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
// Verify guest vlans in the range don't belong to a network of a different account
|
||||
for (int i = startVlan; i <= endVlan; i++) {
|
||||
List<DataCenterVnetVO> allocatedVlans = _datacneterVnet.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
|
||||
List<DataCenterVnetVO> allocatedVlans = _dcVnetDao.listAllocatedVnetsInRange(physicalNetwork.getDataCenterId(), physicalNetwork.getId(), startVlan, endVlan);
|
||||
if (allocatedVlans != null && !allocatedVlans.isEmpty()) {
|
||||
for (DataCenterVnetVO allocatedVlan : allocatedVlans) {
|
||||
if (allocatedVlan.getAccountId() != vlanOwner.getAccountId()) {
|
||||
|
|
@ -3821,7 +4033,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
List<Integer> vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i + 1).getGuestVlanRange());
|
||||
// Range extends 2 vlan ranges, both to the right and left
|
||||
if (endVlan == (vlanTokens2.get(0).intValue() - 1) && guestVlanMaps.get(i + 1).getAccountId() == vlanOwnerId) {
|
||||
_datacneterVnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i + 1).getId());
|
||||
_dcVnetDao.releaseDedicatedGuestVlans(guestVlanMaps.get(i + 1).getId());
|
||||
_accountGuestVlanMapDao.remove(guestVlanMaps.get(i + 1).getId());
|
||||
updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue();
|
||||
break;
|
||||
|
|
@ -3845,9 +4057,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
// For every guest vlan set the corresponding account guest vlan map id
|
||||
List<Integer> finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange());
|
||||
for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) {
|
||||
List<DataCenterVnetVO> dataCenterVnet = _datacneterVnet.findVnet(physicalNetwork.getDataCenterId(), physicalNetworkId, Integer.toString(i));
|
||||
List<DataCenterVnetVO> dataCenterVnet = _dcVnetDao.findVnet(physicalNetwork.getDataCenterId(), physicalNetworkId, Integer.toString(i));
|
||||
dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId());
|
||||
_datacneterVnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
|
||||
_dcVnetDao.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0));
|
||||
}
|
||||
return accountGuestVlanMapVO;
|
||||
}
|
||||
|
|
@ -3869,7 +4081,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
|
||||
public Pair<List<? extends GuestVlanRange>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
|
||||
Long id = cmd.getId();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
|
|
@ -3942,7 +4154,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
Filter searchFilter = new Filter(AccountGuestVlanMapVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
Pair<List<AccountGuestVlanMapVO>, Integer> result = _accountGuestVlanMapDao.searchAndCount(sc, searchFilter);
|
||||
return new Pair<List<? extends GuestVlan>, Integer>(result.first(), result.second());
|
||||
return new Pair<List<? extends GuestVlanRange>, Integer>(result.first(), result.second());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -3956,7 +4168,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
}
|
||||
|
||||
// Remove dedication for the guest vlan
|
||||
_datacneterVnet.releaseDedicatedGuestVlans(dedicatedGuestVlan.getId());
|
||||
_dcVnetDao.releaseDedicatedGuestVlans(dedicatedGuestVlan.getId());
|
||||
if (_accountGuestVlanMapDao.remove(dedicatedGuestVlanRangeId)) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -4646,9 +4858,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
@Override
|
||||
@DB
|
||||
public Network createPrivateNetwork(final String networkName, final String displayText, long physicalNetworkId, String broadcastUriString, final String startIp, String endIp, final String gateway,
|
||||
String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId, final Boolean bypassVlanOverlapCheck)
|
||||
String netmask, final long networkOwnerId, final Long vpcId, final Boolean sourceNat, final Long networkOfferingId, final Boolean bypassVlanOverlapCheck, final Long associatedNetworkId)
|
||||
throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException {
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
final Account owner = _accountMgr.getAccount(networkOwnerId);
|
||||
|
||||
// Get system network offering
|
||||
|
|
@ -4686,13 +4899,22 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
|
||||
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
|
||||
|
||||
URI uri = BroadcastDomainType.fromString(broadcastUriString);
|
||||
final String uriString = uri.toString();
|
||||
BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri);
|
||||
// numeric vlan or vlan uri are ok for now
|
||||
// TODO make a test for any supported scheme
|
||||
if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) {
|
||||
throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString);
|
||||
final String uriString;
|
||||
if (broadcastUriString != null) {
|
||||
URI uri = BroadcastDomainType.fromString(broadcastUriString);
|
||||
uriString = uri.toString();
|
||||
BroadcastDomainType tiep = BroadcastDomainType.getSchemeValue(uri);
|
||||
// numeric vlan or vlan uri are ok for now
|
||||
// TODO make a test for any supported scheme
|
||||
if (!(tiep == BroadcastDomainType.Vlan || tiep == BroadcastDomainType.Lswitch)) {
|
||||
throw new InvalidParameterValueException("unsupported type of broadcastUri specified: " + broadcastUriString);
|
||||
}
|
||||
} else if (associatedNetworkId != null) {
|
||||
DataCenter zone = _dcDao.findById(pNtwk.getDataCenterId());
|
||||
Network associatedNetwork = implementAssociatedNetwork(associatedNetworkId, caller, owner, zone, null, owner.getAccountId(), cidr, startIp, endIp);
|
||||
uriString = associatedNetwork.getBroadcastUri().toString();
|
||||
} else {
|
||||
throw new InvalidParameterValueException("One of uri and associatedNetworkId must be passed");
|
||||
}
|
||||
|
||||
final NetworkOfferingVO ntwkOffFinal = ntwkOff;
|
||||
|
|
@ -4710,6 +4932,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
privateNetwork = _networkMgr.createPrivateNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, bypassVlanOverlapCheck, owner, pNtwk, vpcId);
|
||||
if (privateNetwork != null) {
|
||||
s_logger.debug("Successfully created guest network " + privateNetwork);
|
||||
if (associatedNetworkId != null) {
|
||||
_networkDetailsDao.persist(new NetworkDetailVO(privateNetwork.getId(), Network.AssociatedNetworkId, String.valueOf(associatedNetworkId), true));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException("Creating guest network failed");
|
||||
}
|
||||
|
|
@ -4858,6 +5083,210 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends GuestVlan>, Integer> listGuestVlans(ListGuestVlansCmd cmd) {
|
||||
Long id = cmd.getId();
|
||||
Long zoneId = cmd.getZoneId();
|
||||
Long physicalNetworkId = cmd.getPhysicalNetworkId();
|
||||
String vnet = cmd.getVnet();
|
||||
Boolean allocatedOnly = cmd.getAllocatedOnly();
|
||||
String keyword = cmd.getKeyword();
|
||||
|
||||
SearchCriteria<DataCenterVnetVO> vlanSearch = _dcVnetDao.createSearchCriteria();
|
||||
if (id != null) {
|
||||
vlanSearch.addAnd("id", Op.EQ, id);
|
||||
}
|
||||
if (zoneId != null) {
|
||||
vlanSearch.addAnd("dataCenterId", Op.EQ, zoneId);
|
||||
}
|
||||
if (physicalNetworkId != null) {
|
||||
vlanSearch.addAnd("physicalNetworkId", Op.EQ, physicalNetworkId);
|
||||
}
|
||||
if (vnet != null) {
|
||||
vlanSearch.addAnd("vnet", Op.EQ, vnet);
|
||||
}
|
||||
if (allocatedOnly != null && allocatedOnly) {
|
||||
vlanSearch.addAnd("takenAt", Op.NNULL);
|
||||
}
|
||||
if (keyword != null) {
|
||||
vlanSearch.addAnd("vnet", Op.LIKE, "%" + keyword + "%");
|
||||
}
|
||||
Long pageSizeVal = cmd.getPageSizeVal();
|
||||
Long startIndex = cmd.getStartIndex();
|
||||
Filter searchFilter = new Filter(DataCenterVnetVO.class, "vnet", true, startIndex, pageSizeVal);
|
||||
|
||||
Pair<List<DataCenterVnetVO>, Integer> vlans = _dcVnetDao.searchAndCount(vlanSearch, searchFilter);
|
||||
return new Pair<List<? extends GuestVlan>, Integer>(vlans.first(), vlans.second());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends NetworkPermission> listNetworkPermissions(ListNetworkPermissionsCmd cmd) {
|
||||
final Long networkId = cmd.getNetworkId();
|
||||
NetworkVO network = _networksDao.findById(networkId);
|
||||
if (network == null) {
|
||||
throw new InvalidParameterValueException("unable to find network with id " + networkId);
|
||||
}
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, network);
|
||||
|
||||
List<String> accountNames = new ArrayList<String>();
|
||||
List<NetworkPermissionVO> permissions = _networkPermissionDao.findByNetwork(networkId);
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createNetworkPermissions(CreateNetworkPermissionsCmd cmd) {
|
||||
final Long id = cmd.getNetworkId();
|
||||
List<String> accountNames = cmd.getAccountNames();
|
||||
List<Long> accountIds = cmd.getAccountIds();
|
||||
List<Long> projectIds = cmd.getProjectIds();
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
NetworkVO network = validateNetworkPermissionParameters(caller, id);
|
||||
|
||||
accountIds = populateAccounts(caller, accountIds, network.getDomainId(), accountNames, projectIds);
|
||||
|
||||
final List<Long> accountIdsFinal = accountIds;
|
||||
final Account owner = _accountMgr.getAccount(network.getAccountId());
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
for (Long accountId : accountIdsFinal) {
|
||||
Account permittedAccount = _accountDao.findActiveAccountById(accountId, network.getDomainId());
|
||||
if (permittedAccount != null) {
|
||||
if (permittedAccount.getId() == owner.getId()) {
|
||||
continue; // don't grant permission to the network owner, they implicitly have permission
|
||||
}
|
||||
NetworkPermissionVO existingPermission = _networkPermissionDao.findByNetworkAndAccount(id, permittedAccount.getId());
|
||||
if (existingPermission == null) {
|
||||
NetworkPermissionVO networkPermission = new NetworkPermissionVO(id, permittedAccount.getId());
|
||||
_networkPermissionDao.persist(networkPermission);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Unable to find account " + accountId + " in the domain of network " + network + ". No permissions is added");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd cmd) {
|
||||
final Long id = cmd.getNetworkId();
|
||||
List<String> accountNames = cmd.getAccountNames();
|
||||
List<Long> accountIds = cmd.getAccountIds();
|
||||
List<Long> projectIds = cmd.getProjectIds();
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
NetworkVO network = validateNetworkPermissionParameters(caller, id);
|
||||
|
||||
accountIds = populateAccounts(caller, accountIds, network.getDomainId(), accountNames, projectIds);
|
||||
|
||||
_networkPermissionDao.removePermissions(id, accountIds);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetNetworkPermissions(ResetNetworkPermissionsCmd cmd) {
|
||||
|
||||
final Long id = cmd.getNetworkId();
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
NetworkVO network = validateNetworkPermissionParameters(caller, id);
|
||||
|
||||
_networkPermissionDao.removeAllPermissions(id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private NetworkVO validateNetworkPermissionParameters(Account caller, Long id) {
|
||||
|
||||
final NetworkVO network = _networksDao.findById(id);
|
||||
|
||||
if (network == null) {
|
||||
throw new InvalidParameterValueException("unable to find network with id " + id);
|
||||
}
|
||||
|
||||
if (network.getAclType() == ACLType.Domain) {
|
||||
throw new InvalidParameterValueException("network is already shared in domain");
|
||||
}
|
||||
|
||||
if (network.getVpcId() != null) {
|
||||
throw new InvalidParameterValueException("VPC tiers cannot be shared");
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, network);
|
||||
|
||||
final Account owner = _accountMgr.getAccount(network.getAccountId());
|
||||
if (owner.getType() == Account.Type.PROJECT) {
|
||||
// Currently project owned networks cannot be shared outside project but is available to all users within project by default.
|
||||
throw new InvalidParameterValueException("Update network permissions is an invalid operation on network " + network.getName()
|
||||
+ ". Project owned networks cannot be shared outside network.");
|
||||
}
|
||||
|
||||
//Only admin or owner of the network should be able to change its permissions
|
||||
if (caller.getId() != owner.getId() && !_accountMgr.isAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Unable to grant permission to account " + caller.getAccountName() + " as it is neither admin nor owner or the network");
|
||||
}
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
private List<Long> populateAccounts(Account caller, List<Long> accountIds, Long domainId, List<String> accountNames, List<Long> projectIds) {
|
||||
if (accountIds == null) {
|
||||
accountIds = new ArrayList<Long>();
|
||||
}
|
||||
// convert projectIds to accountIds
|
||||
if (projectIds != null) {
|
||||
accountIds.addAll(convertProjectIdsToAccountIds(caller, projectIds));
|
||||
}
|
||||
// convert accountNames to accountIds
|
||||
if (accountNames != null) {
|
||||
accountIds.addAll(convertAccountNamesToAccountIds(caller, domainId, accountNames));
|
||||
}
|
||||
final Domain domain = _domainDao.findById(domainId);
|
||||
for (Long accountId : accountIds) {
|
||||
Account permittedAccount = _accountDao.findActiveAccountById(accountId, domain.getId());
|
||||
if (permittedAccount == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account " + accountId + " in domain id=" + domain.getUuid() + ". No permissions is removed");
|
||||
}
|
||||
}
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
private List<Long> convertProjectIdsToAccountIds(final Account caller, final List<Long> projectIds) {
|
||||
List<Long> accountIds = new ArrayList<Long>();
|
||||
for (Long projectId : projectIds) {
|
||||
Project project = _projectMgr.getProject(projectId);
|
||||
if (project == null) {
|
||||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
}
|
||||
|
||||
if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
|
||||
throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
|
||||
}
|
||||
accountIds.add(project.getProjectAccountId());
|
||||
}
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
private List<Long> convertAccountNamesToAccountIds(final Account caller, final Long domainId, final List<String> accountNames) {
|
||||
List<Long> accountIds = new ArrayList<Long>();
|
||||
for (String accountName : accountNames) {
|
||||
Account permittedAccount = _accountDao.findActiveAccount(accountName, domainId);
|
||||
if (permittedAccount == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account by name " + accountName);
|
||||
}
|
||||
if (permittedAccount.getId() != caller.getId()) {
|
||||
accountIds.add(permittedAccount.getId());
|
||||
}
|
||||
}
|
||||
return accountIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return NetworkService.class.getSimpleName();
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
|
|||
IpAddressManager _ipAddrMgr;
|
||||
Random _rand = new Random(System.currentTimeMillis());
|
||||
|
||||
static final ConfigKey<Boolean> UseSystemGuestVlans =
|
||||
public static final ConfigKey<Boolean> UseSystemGuestVlans =
|
||||
new ConfigKey<Boolean>(
|
||||
"Advanced",
|
||||
Boolean.class,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||
throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in");
|
||||
}
|
||||
|
||||
if (offering.isSpecifyVlan()) {
|
||||
if (userSpecified.getBroadcastUri() != null) {
|
||||
network.setBroadcastUri(userSpecified.getBroadcastUri());
|
||||
network.setState(State.Setup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import javax.inject.Inject;
|
|||
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd;
|
||||
import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd;
|
||||
|
|
@ -1011,9 +1012,9 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
|
||||
_rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller);
|
||||
|
||||
if (vm.getAccountId() != loadBalancer.getAccountId()) {
|
||||
throw new PermissionDeniedException("Cannot add virtual machines that do not belong to the same owner.");
|
||||
}
|
||||
Account vmOwner = _accountDao.findById(vm.getAccountId());
|
||||
Network network = _networkDao.findById(loadBalancer.getNetworkId());
|
||||
_accountMgr.checkAccess(vmOwner, SecurityChecker.AccessType.UseEntry, false, network);
|
||||
|
||||
// Let's check to make sure the vm has a nic in the same network as
|
||||
// the load balancing rule.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import com.cloud.storage.dao.VMTemplateDao;
|
|||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.api.command.user.firewall.ListPortForwardingRulesCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
|
|
@ -170,13 +171,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
}
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, ipAddress, userVm);
|
||||
|
||||
// validate that IP address and userVM belong to the same account
|
||||
if (ipAddress.getAllocatedToAccountId().longValue() != userVm.getAccountId()) {
|
||||
throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress +
|
||||
" owner is not the same as owner of virtual machine " + userVm.toString());
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, false, ipAddress, userVm);
|
||||
|
||||
// validate that userVM is in the same availability zone as the IP address
|
||||
if (ipAddress.getDataCenterId() != userVm.getDataCenterId()) {
|
||||
|
|
@ -195,16 +190,11 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
return;
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, rule, userVm);
|
||||
_accountMgr.checkAccess(caller, null, false, rule, userVm);
|
||||
|
||||
if (userVm.getState() == VirtualMachine.State.Destroyed || userVm.getState() == VirtualMachine.State.Expunging) {
|
||||
throw new InvalidParameterValueException("Invalid user vm: " + userVm.getId());
|
||||
}
|
||||
|
||||
// This same owner check is actually not needed, since multiple entities OperateEntry trick guarantee that
|
||||
if (rule.getAccountId() != userVm.getAccountId()) {
|
||||
throw new InvalidParameterValueException("New rule " + rule + " and vm id=" + userVm.getId() + " belong to different accounts");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -571,6 +561,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
} else {
|
||||
checkIpAndUserVm(ipAddress, vm, caller, false);
|
||||
}
|
||||
Account vmOwner = _accountMgr.getAccount(vm.getAccountId());
|
||||
_accountMgr.checkAccess(vmOwner, SecurityChecker.AccessType.UseEntry, false, network);
|
||||
|
||||
//is static nat is for vm secondary ip
|
||||
//dstIp = guestNic.getIp4Address();
|
||||
|
|
|
|||
|
|
@ -43,8 +43,10 @@ import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
|||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayByAdminCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
|
||||
|
|
@ -115,6 +117,8 @@ import com.cloud.network.vpc.dao.VpcServiceMapDao;
|
|||
import com.cloud.network.vpn.Site2SiteVpnManager;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||
|
|
@ -225,6 +229,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
DomainDao domainDao;
|
||||
@Inject
|
||||
private AnnotationDao annotationDao;
|
||||
@Inject
|
||||
NetworkOfferingDao _networkOfferingDao;
|
||||
|
||||
@Inject
|
||||
private VpcPrivateGatewayTransactionCallable vpcTxCallable;
|
||||
|
|
@ -1821,8 +1827,29 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "creating VPC private gateway", create = true)
|
||||
public PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway,
|
||||
final String netmask, final long gatewayOwnerId, final Long networkOfferingId, final Boolean isSourceNat, final Long aclId, final Boolean bypassVlanOverlapCheck) throws ResourceAllocationException,
|
||||
public PrivateGateway createVpcPrivateGateway(CreatePrivateGatewayCmd command) throws ResourceAllocationException,
|
||||
ConcurrentOperationException, InsufficientCapacityException {
|
||||
long vpcId = command.getVpcId();
|
||||
String ipAddress = command.getIpAddress();
|
||||
String gateway = command.getGateway();
|
||||
String netmask = command.getNetmask();
|
||||
long gatewayOwnerId = command.getEntityOwnerId();
|
||||
Long networkOfferingId = command.getNetworkOfferingId();
|
||||
Boolean isSourceNat = command.getIsSourceNat();
|
||||
Long aclId = command.getAclId();
|
||||
Long associatedNetworkId = command.getAssociatedNetworkId();
|
||||
|
||||
if (command instanceof CreatePrivateGatewayByAdminCmd) {
|
||||
Long physicalNetworkId = ((CreatePrivateGatewayByAdminCmd)command).getPhysicalNetworkId();
|
||||
String broadcastUri = ((CreatePrivateGatewayByAdminCmd)command).getBroadcastUri();
|
||||
Boolean bypassVlanOverlapCheck = ((CreatePrivateGatewayByAdminCmd)command).getBypassVlanOverlapCheck();
|
||||
return createVpcPrivateGateway(vpcId, physicalNetworkId, broadcastUri, ipAddress, gateway, netmask, gatewayOwnerId, networkOfferingId, isSourceNat, aclId, bypassVlanOverlapCheck, associatedNetworkId);
|
||||
}
|
||||
return createVpcPrivateGateway(vpcId, null, null, ipAddress, gateway, netmask, gatewayOwnerId, networkOfferingId, isSourceNat, aclId, false, associatedNetworkId);
|
||||
}
|
||||
|
||||
private PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway,
|
||||
final String netmask, final long gatewayOwnerId, final Long networkOfferingIdPassed, final Boolean isSourceNat, final Long aclId, final Boolean bypassVlanOverlapCheck, final Long associatedNetworkId) throws ResourceAllocationException,
|
||||
ConcurrentOperationException, InsufficientCapacityException {
|
||||
|
||||
// Validate parameters
|
||||
|
|
@ -1833,105 +1860,91 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
throw ex;
|
||||
}
|
||||
|
||||
PhysicalNetwork physNet = null;
|
||||
// Validate physical network
|
||||
if (physicalNetworkId == null) {
|
||||
final List<? extends PhysicalNetwork> pNtwks = _ntwkModel.getPhysicalNtwksSupportingTrafficType(vpc.getZoneId(), TrafficType.Guest);
|
||||
if (pNtwks.isEmpty() || pNtwks.size() != 1) {
|
||||
throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id");
|
||||
}
|
||||
physNet = pNtwks.get(0);
|
||||
physicalNetworkId = physNet.getId();
|
||||
}
|
||||
NetworkOfferingVO ntwkOff = getVpcPrivateGatewayNetworkOffering(networkOfferingIdPassed, broadcastUri);
|
||||
final Long networkOfferingId = ntwkOff.getId();
|
||||
|
||||
if (physNet == null) {
|
||||
physNet = _entityMgr.findById(PhysicalNetwork.class, physicalNetworkId);
|
||||
}
|
||||
final Long dcId = physNet.getDataCenterId();
|
||||
validateVpcPrivateGatewayAssociateNetworkId(ntwkOff, broadcastUri, associatedNetworkId, bypassVlanOverlapCheck);
|
||||
|
||||
final Long dcId = vpc.getZoneId();
|
||||
physicalNetworkId = validateVpcPrivateGatewayPhysicalNetworkId(dcId, physicalNetworkId, associatedNetworkId, ntwkOff);
|
||||
PhysicalNetwork physNet = _entityMgr.findById(PhysicalNetwork.class, physicalNetworkId);;
|
||||
|
||||
final Long physicalNetworkIdFinal = physicalNetworkId;
|
||||
final PhysicalNetwork physNetFinal = physNet;
|
||||
VpcGatewayVO gatewayVO = null;
|
||||
try {
|
||||
gatewayVO = Transaction.execute(new TransactionCallbackWithException<VpcGatewayVO, Exception>() {
|
||||
@Override
|
||||
public VpcGatewayVO doInTransaction(final TransactionStatus status) throws ResourceAllocationException, ConcurrentOperationException,
|
||||
InsufficientCapacityException {
|
||||
s_logger.debug("Creating Private gateway for VPC " + vpc);
|
||||
// 1) create private network unless it is existing and
|
||||
// lswitch'd
|
||||
Network privateNtwk = null;
|
||||
if (BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
|
||||
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
|
||||
privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, gatewayOwnerId, dcId, networkOfferingId, vpcId);
|
||||
// if the dcid is different we get no network so next we
|
||||
// try to create it
|
||||
}
|
||||
if (privateNtwk == null) {
|
||||
s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri);
|
||||
final String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
|
||||
privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, broadcastUri, ipAddress, null, gateway, netmask,
|
||||
gatewayOwnerId, vpcId, isSourceNat, networkOfferingId, bypassVlanOverlapCheck);
|
||||
} else { // create the nic/ip as createPrivateNetwork
|
||||
// doesn''t do that work for us now
|
||||
s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
|
||||
final DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
|
||||
s_logger.debug("Creating Private gateway for VPC " + vpc);
|
||||
// 1) create private network unless it is existing and
|
||||
// lswitch'd
|
||||
Network privateNtwk = null;
|
||||
if (broadcastUri != null
|
||||
&& BroadcastDomainType.getSchemeValue(BroadcastDomainType.fromString(broadcastUri)) == BroadcastDomainType.Lswitch) {
|
||||
final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
|
||||
privateNtwk = _ntwkDao.getPrivateNetwork(broadcastUri, cidr, gatewayOwnerId, dcId, networkOfferingId, vpcId);
|
||||
// if the dcid is different we get no network so next we
|
||||
// try to create it
|
||||
}
|
||||
if (privateNtwk == null) {
|
||||
s_logger.info("creating new network for vpc " + vpc + " using broadcast uri: " + broadcastUri + " and associated network id: " + associatedNetworkId);
|
||||
final String networkName = "vpc-" + vpc.getName() + "-privateNetwork";
|
||||
privateNtwk = _ntwkSvc.createPrivateNetwork(networkName, networkName, physicalNetworkIdFinal, broadcastUri, ipAddress, null, gateway, netmask,
|
||||
gatewayOwnerId, vpcId, isSourceNat, networkOfferingId, bypassVlanOverlapCheck, associatedNetworkId);
|
||||
} else { // create the nic/ip as createPrivateNetwork
|
||||
// doesn''t do that work for us now
|
||||
s_logger.info("found and using existing network for vpc " + vpc + ": " + broadcastUri);
|
||||
final DataCenterVO dc = _dcDao.lockRow(physNetFinal.getDataCenterId(), true);
|
||||
|
||||
// add entry to private_ip_address table
|
||||
PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
|
||||
if (privateIp != null) {
|
||||
throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + " in zone "
|
||||
+ _entityMgr.findById(DataCenter.class, dcId).getName());
|
||||
}
|
||||
|
||||
final Long mac = dc.getMacAddress();
|
||||
final Long nextMac = mac + 1;
|
||||
dc.setMacAddress(nextMac);
|
||||
|
||||
s_logger.info("creating private ip address for vpc (" + ipAddress + ", " + privateNtwk.getId() + ", " + nextMac + ", " + vpcId + ", " + isSourceNat + ")");
|
||||
privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, isSourceNat);
|
||||
_privateIpDao.persist(privateIp);
|
||||
|
||||
_dcDao.update(dc.getId(), dc);
|
||||
}
|
||||
|
||||
long networkAclId = NetworkACL.DEFAULT_DENY;
|
||||
if (aclId != null) {
|
||||
final NetworkACLVO aclVO = _networkAclDao.findById(aclId);
|
||||
if (aclVO == null) {
|
||||
throw new InvalidParameterValueException("Invalid network acl id passed ");
|
||||
}
|
||||
if (aclVO.getVpcId() != vpcId && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
|
||||
throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
|
||||
}
|
||||
|
||||
networkAclId = aclId;
|
||||
}
|
||||
|
||||
{ // experimental block, this is a hack
|
||||
// set vpc id in network to null
|
||||
// might be needed for all types of broadcast domains
|
||||
// the ugly hack is that vpc gateway nets are created as
|
||||
// guest network
|
||||
// while they are not.
|
||||
// A more permanent solution would be to define a type of
|
||||
// 'gatewaynetwork'
|
||||
// so that handling code is not mixed between the two
|
||||
final NetworkVO gatewaynet = _ntwkDao.findById(privateNtwk.getId());
|
||||
gatewaynet.setVpcId(null);
|
||||
_ntwkDao.persist(gatewaynet);
|
||||
}
|
||||
|
||||
// 2) create gateway entry
|
||||
final VpcGatewayVO gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), privateNtwk.getId(), broadcastUri,
|
||||
gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
|
||||
_vpcGatewayDao.persist(gatewayVO);
|
||||
|
||||
s_logger.debug("Created vpc gateway entry " + gatewayVO);
|
||||
|
||||
return gatewayVO;
|
||||
// add entry to private_ip_address table
|
||||
PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNtwk.getId(), ipAddress);
|
||||
if (privateIp != null) {
|
||||
throw new InvalidParameterValueException("Private ip address " + ipAddress + " already used for private gateway" + " in zone "
|
||||
+ _entityMgr.findById(DataCenter.class, dcId).getName());
|
||||
}
|
||||
});
|
||||
|
||||
final Long mac = dc.getMacAddress();
|
||||
final Long nextMac = mac + 1;
|
||||
dc.setMacAddress(nextMac);
|
||||
|
||||
s_logger.info("creating private ip address for vpc (" + ipAddress + ", " + privateNtwk.getId() + ", " + nextMac + ", " + vpcId + ", " + isSourceNat + ")");
|
||||
privateIp = new PrivateIpVO(ipAddress, privateNtwk.getId(), nextMac, vpcId, isSourceNat);
|
||||
_privateIpDao.persist(privateIp);
|
||||
|
||||
_dcDao.update(dc.getId(), dc);
|
||||
}
|
||||
|
||||
long networkAclId = NetworkACL.DEFAULT_DENY;
|
||||
if (aclId != null) {
|
||||
final NetworkACLVO aclVO = _networkAclDao.findById(aclId);
|
||||
if (aclVO == null) {
|
||||
throw new InvalidParameterValueException("Invalid network acl id passed ");
|
||||
}
|
||||
if (aclVO.getVpcId() != vpcId && !(aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW)) {
|
||||
throw new InvalidParameterValueException("Private gateway and network acl are not in the same vpc");
|
||||
}
|
||||
|
||||
networkAclId = aclId;
|
||||
}
|
||||
|
||||
{ // experimental block, this is a hack
|
||||
// set vpc id in network to null
|
||||
// might be needed for all types of broadcast domains
|
||||
// the ugly hack is that vpc gateway nets are created as
|
||||
// guest network
|
||||
// while they are not.
|
||||
// A more permanent solution would be to define a type of
|
||||
// 'gatewaynetwork'
|
||||
// so that handling code is not mixed between the two
|
||||
final NetworkVO gatewaynet = _ntwkDao.findById(privateNtwk.getId());
|
||||
gatewaynet.setVpcId(null);
|
||||
_ntwkDao.persist(gatewaynet);
|
||||
}
|
||||
|
||||
// 2) create gateway entry
|
||||
gatewayVO = new VpcGatewayVO(ipAddress, VpcGateway.Type.Private, vpcId, privateNtwk.getDataCenterId(), privateNtwk.getId(), privateNtwk.getBroadcastUri().toString(),
|
||||
gateway, netmask, vpc.getAccountId(), vpc.getDomainId(), isSourceNat, networkAclId);
|
||||
_vpcGatewayDao.persist(gatewayVO);
|
||||
|
||||
s_logger.debug("Created vpc gateway entry " + gatewayVO);
|
||||
} catch (final Exception e) {
|
||||
ExceptionUtil.rethrowRuntime(e);
|
||||
ExceptionUtil.rethrow(e, InsufficientCapacityException.class);
|
||||
|
|
@ -1943,6 +1956,75 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
return getVpcPrivateGateway(gatewayVO.getId());
|
||||
}
|
||||
|
||||
private void validateVpcPrivateGatewayAssociateNetworkId(NetworkOfferingVO ntwkOff, String broadcastUri, Long associatedNetworkId, Boolean bypassVlanOverlapCheck) {
|
||||
// Validate vlanId and associatedNetworkId
|
||||
if (broadcastUri == null && associatedNetworkId == null) {
|
||||
throw new InvalidParameterValueException("One of vlanId and associatedNetworkId must be specified");
|
||||
}
|
||||
if (broadcastUri != null && associatedNetworkId != null) {
|
||||
throw new InvalidParameterValueException("vlanId and associatedNetworkId are mutually exclusive");
|
||||
}
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
if (!_accountMgr.isRootAdmin(caller.getId()) && (ntwkOff.isSpecifyVlan() || broadcastUri != null || bypassVlanOverlapCheck)) {
|
||||
throw new InvalidParameterValueException("Only ROOT admin is allowed to specify vlanId or bypass vlan overlap check");
|
||||
}
|
||||
if (ntwkOff.isSpecifyVlan() && broadcastUri == null) {
|
||||
throw new InvalidParameterValueException("vlanId must be specified for this network offering");
|
||||
}
|
||||
if (! ntwkOff.isSpecifyVlan() && associatedNetworkId == null) {
|
||||
throw new InvalidParameterValueException("associatedNetworkId must be specified for this network offering");
|
||||
}
|
||||
}
|
||||
|
||||
private NetworkOfferingVO getVpcPrivateGatewayNetworkOffering(Long networkOfferingIdPassed, String broadcastUri) {
|
||||
// Validate network offering
|
||||
NetworkOfferingVO ntwkOff = null;
|
||||
if (networkOfferingIdPassed != null) {
|
||||
ntwkOff = _networkOfferingDao.findById(networkOfferingIdPassed);
|
||||
if (ntwkOff == null) {
|
||||
throw new InvalidParameterValueException("Unable to find network offering by id specified");
|
||||
}
|
||||
if (! TrafficType.Guest.equals(ntwkOff.getTrafficType())) {
|
||||
throw new InvalidParameterValueException("The network offering cannot be used to create Guest network");
|
||||
}
|
||||
if (! GuestType.Isolated.equals(ntwkOff.getGuestType())) {
|
||||
throw new InvalidParameterValueException("The network offering cannot be used to create Isolated network");
|
||||
}
|
||||
} else if (broadcastUri != null) {
|
||||
ntwkOff = _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOffering);
|
||||
} else {
|
||||
ntwkOff = _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan);
|
||||
}
|
||||
return ntwkOff;
|
||||
}
|
||||
|
||||
private Long validateVpcPrivateGatewayPhysicalNetworkId(Long dcId, Long physicalNetworkId, Long associatedNetworkId, NetworkOfferingVO ntwkOff) {
|
||||
// Validate physical network
|
||||
if (associatedNetworkId != null) {
|
||||
Network associatedNetwork = _entityMgr.findById(Network.class, associatedNetworkId);
|
||||
if (associatedNetwork == null) {
|
||||
throw new InvalidParameterValueException("Unable to find network by ID " + associatedNetworkId);
|
||||
}
|
||||
if (physicalNetworkId != null && !physicalNetworkId.equals(associatedNetwork.getPhysicalNetworkId())) {
|
||||
throw new InvalidParameterValueException("The network can only be created on the same physical network as the associated network");
|
||||
} else if (physicalNetworkId == null) {
|
||||
physicalNetworkId = associatedNetwork.getPhysicalNetworkId();
|
||||
}
|
||||
}
|
||||
if (physicalNetworkId == null) {
|
||||
// Determine the physical network by network offering tags
|
||||
physicalNetworkId = _ntwkSvc.findPhysicalNetworkId(dcId, ntwkOff.getTags(), ntwkOff.getTrafficType());
|
||||
}
|
||||
if (physicalNetworkId == null) {
|
||||
final List<? extends PhysicalNetwork> pNtwks = _ntwkModel.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Guest);
|
||||
if (pNtwks.isEmpty() || pNtwks.size() != 1) {
|
||||
throw new InvalidParameterValueException("Physical network can't be determined; pass physical network id");
|
||||
}
|
||||
physicalNetworkId = pNtwks.get(0).getId();
|
||||
}
|
||||
return physicalNetworkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PRIVATE_GATEWAY_CREATE, eventDescription = "Applying VPC private gateway", async = true)
|
||||
public PrivateGateway applyVpcPrivateGateway(final long gatewayId, final boolean destroyOnFailure) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
|
|
@ -2005,6 +2087,17 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
throw new ConcurrentOperationException("Unable to lock gateway " + gatewayId);
|
||||
}
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||
_accountMgr.checkAccess(caller, null, false, gatewayVO);
|
||||
final NetworkVO networkVO = _ntwkDao.findById(gatewayVO.getNetworkId());
|
||||
if (networkVO != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, networkVO);
|
||||
if (_networkOfferingDao.findById(networkVO.getNetworkOfferingId()).isSpecifyVlan()) {
|
||||
throw new InvalidParameterValueException("Unable to delete private gateway with specified vlan by non-ROOT accounts");
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -966,8 +966,10 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
|||
controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering);
|
||||
NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemStorageNetwork, TrafficType.Storage, true);
|
||||
storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering);
|
||||
NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated);
|
||||
NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOffering, GuestType.Isolated, true);
|
||||
privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering);
|
||||
NetworkOfferingVO privateGatewayNetworkOfferingWithoutVlan = new NetworkOfferingVO(NetworkOffering.SystemPrivateGatewayNetworkOfferingWithoutVlan, GuestType.Isolated, false);
|
||||
privateGatewayNetworkOfferingWithoutVlan = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOfferingWithoutVlan);
|
||||
|
||||
//populate providers
|
||||
final Map<Network.Service, Network.Provider> defaultSharedNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>();
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import javax.inject.Inject;
|
|||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
|
|
@ -134,6 +135,7 @@ import org.apache.cloudstack.api.command.admin.network.DeleteNetworkServiceProvi
|
|||
import org.apache.cloudstack.api.command.admin.network.DeletePhysicalNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.DeleteStorageNetworkIpRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListGuestVlansCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListNetworkDeviceCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListNetworkIsolationMethodsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListNetworkServiceProvidersCmd;
|
||||
|
|
@ -296,7 +298,7 @@ import org.apache.cloudstack.api.command.admin.volume.RecoverVolumeCmdByAdmin;
|
|||
import org.apache.cloudstack.api.command.admin.volume.ResizeVolumeCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.volume.UpdateVolumeCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.volume.UploadVolumeCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayByAdminCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.DeletePrivateGatewayCmd;
|
||||
|
|
@ -408,15 +410,19 @@ import org.apache.cloudstack.api.command.user.nat.ListIpForwardingRulesCmd;
|
|||
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.DeleteNetworkACLListCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.DeleteNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RemoveNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ReplaceNetworkACLListCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ResetNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
|
||||
|
|
@ -525,6 +531,7 @@ import org.apache.cloudstack.api.command.user.volume.RemoveResourceDetailCmd;
|
|||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreateStaticRouteCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.DeleteStaticRouteCmd;
|
||||
|
|
@ -2201,7 +2208,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
if (networkMap == null) {
|
||||
return new Pair<>(addrs, 0);
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, false, _accountDao.findById(networkMap.getAccountId()));
|
||||
try {
|
||||
_accountMgr.checkAccess(caller, null, false, _accountDao.findById(networkMap.getAccountId()));
|
||||
} catch (PermissionDeniedException ex) {
|
||||
s_logger.info("Account " + caller + " do not have permission to access account of network " + network);
|
||||
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, false, network);
|
||||
isAllocated = Boolean.TRUE;
|
||||
}
|
||||
} else { // Domain level
|
||||
NetworkDomainVO networkMap = _networkDomainDao.getDomainNetworkMapByNetworkId(network.getId());
|
||||
if (networkMap == null) {
|
||||
|
|
@ -3296,6 +3309,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(ListNetworksCmd.class);
|
||||
cmdList.add(RestartNetworkCmd.class);
|
||||
cmdList.add(UpdateNetworkCmd.class);
|
||||
cmdList.add(CreateNetworkPermissionsCmd.class);
|
||||
cmdList.add(ListNetworkPermissionsCmd.class);
|
||||
cmdList.add(RemoveNetworkPermissionsCmd.class);
|
||||
cmdList.add(ResetNetworkPermissionsCmd.class);
|
||||
cmdList.add(ListDiskOfferingsCmd.class);
|
||||
cmdList.add(ListServiceOfferingsCmd.class);
|
||||
cmdList.add(ActivateProjectCmd.class);
|
||||
|
|
@ -3537,6 +3554,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(CreateVPCCmdByAdmin.class);
|
||||
cmdList.add(ListVPCsCmdByAdmin.class);
|
||||
cmdList.add(UpdateVPCCmdByAdmin.class);
|
||||
cmdList.add(CreatePrivateGatewayByAdminCmd.class);
|
||||
cmdList.add(UpdateLBStickinessPolicyCmd.class);
|
||||
cmdList.add(UpdateLBHealthCheckPolicyCmd.class);
|
||||
cmdList.add(GetUploadParamsForTemplateCmd.class);
|
||||
|
|
@ -3559,6 +3577,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(UploadResourceIconCmd.class);
|
||||
cmdList.add(DeleteResourceIconCmd.class);
|
||||
cmdList.add(ListResourceIconCmd.class);
|
||||
cmdList.add(ListGuestVlansCmd.class);
|
||||
|
||||
// Out-of-band management APIs for admins
|
||||
cmdList.add(EnableOutOfBandManagementForHostCmd.class);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.net.URLEncoder;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
|
|
@ -106,6 +107,7 @@ import com.cloud.exception.ResourceUnavailableException;
|
|||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.IpAddressManager;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.VpnUserVO;
|
||||
import com.cloud.network.as.AutoScaleManager;
|
||||
import com.cloud.network.dao.AccountGuestVlanMapDao;
|
||||
|
|
@ -117,6 +119,7 @@ import com.cloud.network.dao.NetworkVO;
|
|||
import com.cloud.network.dao.RemoteAccessVpnDao;
|
||||
import com.cloud.network.dao.RemoteAccessVpnVO;
|
||||
import com.cloud.network.dao.VpnUserDao;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.network.security.SecurityGroupManager;
|
||||
import com.cloud.network.security.dao.SecurityGroupDao;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
|
|
@ -255,6 +258,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Inject
|
||||
private VpcManager _vpcMgr;
|
||||
@Inject
|
||||
private NetworkModel _networkModel;
|
||||
@Inject
|
||||
private Site2SiteVpnManager _vpnMgr;
|
||||
@Inject
|
||||
private AutoScaleManager _autoscaleMgr;
|
||||
|
|
@ -602,8 +607,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
Account account = ApiDBUtils.findAccountById(entity.getAccountId());
|
||||
domainId = account != null ? account.getDomainId() : -1;
|
||||
}
|
||||
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate) && !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry)
|
||||
&& !(entity instanceof AffinityGroup)) {
|
||||
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate)
|
||||
&& !(entity instanceof Network && accessType != null && (accessType == AccessType.UseEntry || accessType == AccessType.OperateEntry))
|
||||
&& !(entity instanceof AffinityGroup) && !(entity instanceof VirtualRouter)) {
|
||||
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
||||
// for templates, we don't have to do cross domains check
|
||||
if (toBeChecked == null) {
|
||||
|
|
@ -886,7 +892,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
s_logger.debug("Deleting networks for account " + account.getId());
|
||||
List<NetworkVO> networks = _networkDao.listByOwner(accountId);
|
||||
if (networks != null) {
|
||||
Collections.sort(networks, new Comparator<NetworkVO>() {
|
||||
@Override
|
||||
public int compare(NetworkVO network1, NetworkVO network2) {
|
||||
if (network1.getGuestType() != network2.getGuestType() && Network.GuestType.Isolated.equals(network2.getGuestType())) {
|
||||
return -1;
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
for (NetworkVO network : networks) {
|
||||
if (_networkModel.isPrivateGateway(network.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReservationContext context = new ReservationContextImpl(null, null, getActiveUser(callerUserId), caller);
|
||||
|
||||
|
|
|
|||
|
|
@ -1466,9 +1466,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
throw new InvalidParameterValueException(nic + " is not a nic on " + vmInstance);
|
||||
}
|
||||
|
||||
// Perform account permission check on network
|
||||
_accountMgr.checkAccess(caller, AccessType.UseEntry, false, network);
|
||||
|
||||
// don't delete default NIC on a user VM
|
||||
if (nic.isDefaultNic() && vmInstance.getType() == VirtualMachine.Type.User) {
|
||||
throw new InvalidParameterValueException("Unable to remove nic from " + vmInstance + " in " + network + ", nic is default.");
|
||||
|
|
@ -4000,13 +3997,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
}
|
||||
|
||||
//relax the check if the caller is admin account
|
||||
if (caller.getType() != 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");
|
||||
}
|
||||
}
|
||||
_accountMgr.checkAccess(owner, AccessType.UseEntry, false, network);
|
||||
|
||||
IpAddresses requestedIpPair = null;
|
||||
if (requestedIps != null && !requestedIps.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Before;
|
||||
|
|
@ -58,6 +59,8 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
|
|||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
|
@ -101,6 +104,9 @@ public class CreatePrivateNetworkTest {
|
|||
Account account = new AccountVO("testaccount", 1, "networkdomain", Account.Type.NORMAL, UUID.randomUUID().toString());
|
||||
when(networkService._accountMgr.getAccount(anyLong())).thenReturn(account);
|
||||
|
||||
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
|
||||
CallContext.register(user, account);
|
||||
|
||||
NetworkOfferingVO ntwkOff =
|
||||
new NetworkOfferingVO("offer", "fakeOffer", TrafficType.Guest, true, true, null, null, false, null, null, GuestType.Isolated, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false, false, false);
|
||||
|
|
@ -139,21 +145,21 @@ public class CreatePrivateNetworkTest {
|
|||
/* Network nw; */
|
||||
try {
|
||||
/* nw = */
|
||||
networkService.createPrivateNetwork("bla", "fake", 1L, "vlan:1", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, true, 1L, false);
|
||||
networkService.createPrivateNetwork("bla", "fake", 1L, "vlan:1", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, true, 1L, false, null);
|
||||
/* nw = */
|
||||
networkService.createPrivateNetwork("bla", "fake", 1L, "lswitch:3", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, false, 1L, false);
|
||||
networkService.createPrivateNetwork("bla", "fake", 1L, "lswitch:3", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1L, 1L, false, 1L, false, null);
|
||||
boolean invalid = false;
|
||||
boolean unsupported = false;
|
||||
try {
|
||||
/* nw = */
|
||||
networkService.createPrivateNetwork("bla", "fake", 1, "bla:2", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, true, 1L, false);
|
||||
networkService.createPrivateNetwork("bla", "fake", 1, "bla:2", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, true, 1L, false, null);
|
||||
} catch (CloudRuntimeException e) {
|
||||
Assert.assertEquals("unexpected parameter exception", "string 'bla:2' has an unknown BroadcastDomainType.", e.getMessage());
|
||||
invalid = true;
|
||||
}
|
||||
try {
|
||||
/* nw = */
|
||||
networkService.createPrivateNetwork("bla", "fake", 1, "mido://4", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, false, 1L, false);
|
||||
networkService.createPrivateNetwork("bla", "fake", 1, "mido://4", "10.1.1.2", null, "10.1.1.1", "255.255.255.0", 1, 1L, false, 1L, false, null);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
Assert.assertEquals("unexpected parameter exception", "unsupported type of broadcastUri specified: mido://4", e.getMessage());
|
||||
unsupported = true;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class DedicateGuestVlanRangesTest {
|
|||
networkService._accountDao = _accountDao;
|
||||
networkService._projectMgr = _projectMgr;
|
||||
networkService._physicalNetworkDao = _physicalNetworkDao;
|
||||
networkService._datacneterVnet = _dataCenterVnetDao;
|
||||
networkService._dcVnetDao = _dataCenterVnetDao;
|
||||
networkService._accountGuestVlanMapDao = _accountGuestVlanMapDao;
|
||||
|
||||
Account account = new AccountVO("testaccount", 1, "networkdomain", Account.Type.NORMAL, UUID.randomUUID().toString());
|
||||
|
|
@ -195,21 +195,21 @@ public class DedicateGuestVlanRangesTest {
|
|||
|
||||
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
|
||||
|
||||
when(networkService._datacneterVnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
when(networkService._dcVnetDao.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
|
||||
when(networkService._accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(anyLong())).thenReturn(null);
|
||||
|
||||
when(networkService._accountGuestVlanMapDao.persist(any(AccountGuestVlanMapVO.class))).thenReturn(accountGuestVlanMapVO);
|
||||
|
||||
when(networkService._datacneterVnet.update(anyLong(), any(DataCenterVnetVO.class))).thenReturn(true);
|
||||
when(networkService._dcVnetDao.update(anyLong(), any(DataCenterVnetVO.class))).thenReturn(true);
|
||||
|
||||
List<DataCenterVnetVO> dataCenterVnetList = new ArrayList<DataCenterVnetVO>();
|
||||
DataCenterVnetVO dataCenterVnetVO = new DataCenterVnetVO("2-5", 1L, 1L);
|
||||
dataCenterVnetList.add(dataCenterVnetVO);
|
||||
when(networkService._datacneterVnet.findVnet(anyLong(), anyString())).thenReturn(dataCenterVnetList);
|
||||
when(networkService._dcVnetDao.findVnet(anyLong(), anyString())).thenReturn(dataCenterVnetList);
|
||||
|
||||
try {
|
||||
GuestVlan result = networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
|
||||
GuestVlanRange result = networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
|
||||
Assert.assertNotNull(result);
|
||||
} catch (Exception e) {
|
||||
s_logger.info("exception in testing runDedicateGuestVlanRangePostiveTest message: " + e.toString());
|
||||
|
|
@ -275,7 +275,7 @@ public class DedicateGuestVlanRangesTest {
|
|||
DataCenterVnetVO dataCenter = new DataCenterVnetVO("2-5", 1L, 1L);
|
||||
dataCenter.setAccountId(1L);
|
||||
dataCenterList.add(dataCenter);
|
||||
when(networkService._datacneterVnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(dataCenterList);
|
||||
when(networkService._dcVnetDao.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(dataCenterList);
|
||||
|
||||
try {
|
||||
networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd);
|
||||
|
|
@ -298,7 +298,7 @@ public class DedicateGuestVlanRangesTest {
|
|||
|
||||
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
|
||||
|
||||
when(networkService._datacneterVnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
when(networkService._dcVnetDao.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
|
||||
List<AccountGuestVlanMapVO> guestVlanMaps = new ArrayList<AccountGuestVlanMapVO>();
|
||||
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(1L, 1L);
|
||||
|
|
@ -327,7 +327,7 @@ public class DedicateGuestVlanRangesTest {
|
|||
|
||||
when(networkService._physicalNetworkDao.findById(anyLong())).thenReturn(physicalNetwork);
|
||||
|
||||
when(networkService._datacneterVnet.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
when(networkService._dcVnetDao.listAllocatedVnetsInRange(anyLong(), anyLong(), anyInt(), anyInt())).thenReturn(null);
|
||||
|
||||
List<AccountGuestVlanMapVO> guestVlanMaps = new ArrayList<AccountGuestVlanMapVO>();
|
||||
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(2L, 1L);
|
||||
|
|
@ -349,7 +349,7 @@ public class DedicateGuestVlanRangesTest {
|
|||
|
||||
AccountGuestVlanMapVO accountGuestVlanMap = new AccountGuestVlanMapVO(1L, 1L);
|
||||
when(networkService._accountGuestVlanMapDao.findById(anyLong())).thenReturn(accountGuestVlanMap);
|
||||
doNothing().when(networkService._datacneterVnet).releaseDedicatedGuestVlans(anyLong());
|
||||
doNothing().when(networkService._dcVnetDao).releaseDedicatedGuestVlans(anyLong());
|
||||
when(networkService._accountGuestVlanMapDao.remove(anyLong())).thenReturn(true);
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import com.cloud.network.dao.IPAddressVO;
|
|||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.NetworkOffering.Detail;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
|
|
@ -524,6 +525,16 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkNetworkOperatePermissions(Account owner, Network network) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkRouterPermissions(Account owner, VirtualRouter router) {
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class UpdatePhysicalNetworkTest {
|
|||
NetworkServiceImpl networkService = new NetworkServiceImpl();
|
||||
networkService._dcDao = _datacenterDao;
|
||||
networkService._physicalNetworkDao = _physicalNetworkDao;
|
||||
networkService._datacneterVnet = _datacenterVnetDao;
|
||||
networkService._dcVnetDao = _datacenterVnetDao;
|
||||
return networkService;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,16 +17,18 @@
|
|||
package com.cloud.network.lb;
|
||||
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModelImpl;
|
||||
import com.cloud.network.dao.LoadBalancerDao;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapDao;
|
||||
import com.cloud.network.dao.LoadBalancerVMMapVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.RulesManagerImpl;
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -41,6 +43,7 @@ import com.cloud.vm.NicVO;
|
|||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.command.user.loadbalancer.AssignToLoadBalancerRuleCmd;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
|
|
@ -54,8 +57,6 @@ import org.mockito.Mock;
|
|||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -65,31 +66,17 @@ import java.util.ArrayList;
|
|||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class AssignLoadBalancerTest {
|
||||
|
||||
@Inject
|
||||
AccountManager _accountMgr;
|
||||
|
||||
@Inject
|
||||
AccountManager _acctMgr;
|
||||
|
||||
@Inject
|
||||
AccountDao _accountDao;
|
||||
|
||||
@Inject
|
||||
DomainDao _domainDao;
|
||||
|
||||
@Mock
|
||||
List<LoadBalancerVMMapVO> _lbvmMapList;
|
||||
|
||||
@Mock
|
||||
List<Nic> nic;
|
||||
|
||||
@Mock
|
||||
UserVmDao userDao;
|
||||
|
||||
@Spy
|
||||
RulesManagerImpl _rulesMgr = new RulesManagerImpl() {
|
||||
@Override
|
||||
|
|
@ -169,20 +156,31 @@ public class AssignLoadBalancerTest {
|
|||
List<Long> vmIds = new ArrayList<Long>();
|
||||
vmIds.add(2L);
|
||||
|
||||
LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp");
|
||||
UserVmVO vm = new UserVmVO(2L, "test", "test", 101L, Hypervisor.HypervisorType.Any, 21L, false, false, domainId, 200L, 1, 5L, "", "test");
|
||||
|
||||
LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
|
||||
LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
|
||||
UserVmDao userVmDao = Mockito.mock(UserVmDao.class);
|
||||
AccountDao accountDao = Mockito.mock(AccountDao.class);
|
||||
NetworkDao networkDao = Mockito.mock(NetworkDao.class);
|
||||
AccountManager accountMgr = Mockito.mock(AccountManager.class);
|
||||
|
||||
_lbMgr._lbDao = lbDao;
|
||||
_lbMgr._lb2VmMapDao = lb2VmMapDao;
|
||||
_lbMgr._vmDao = userVmDao;
|
||||
_lbMgr._accountDao = accountDao;
|
||||
_lbMgr._accountMgr = accountMgr;
|
||||
_lbMgr._networkDao = networkDao;
|
||||
_lbvmMapList = new ArrayList<>();
|
||||
_lbMgr._rulesMgr = _rulesMgr;
|
||||
_lbMgr._networkModel = _networkModel;
|
||||
|
||||
when(lbDao.findById(anyLong())).thenReturn(Mockito.mock(LoadBalancerVO.class));
|
||||
when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
|
||||
when(userVmDao.findById(anyLong())).thenReturn(vm);
|
||||
when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);
|
||||
when(accountDao.findById(anyLong())).thenReturn(Mockito.mock(AccountVO.class));
|
||||
Mockito.doNothing().when(accountMgr).checkAccess(any(Account.class), any(SecurityChecker.AccessType.class), any(Boolean.class), any(Network.class));
|
||||
|
||||
_lbMgr.assignToLoadBalancer(1L, null, vmIdIpMap);
|
||||
}
|
||||
|
|
@ -202,22 +200,29 @@ public class AssignLoadBalancerTest {
|
|||
vmIds.add(2L);
|
||||
|
||||
LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp");
|
||||
UserVmVO vm = new UserVmVO(2L, "test", "test", 101L, Hypervisor.HypervisorType.Any, 21L, false, false, domainId, 200L, 1, 5L, "", "test");
|
||||
|
||||
LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
|
||||
LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
|
||||
UserVmDao userVmDao = Mockito.mock(UserVmDao.class);
|
||||
AccountDao accountDao = Mockito.mock(AccountDao.class);
|
||||
NetworkDao networkDao = Mockito.mock(NetworkDao.class);
|
||||
AccountManager accountMgr = Mockito.mock(AccountManager.class);
|
||||
NicSecondaryIpDao nicSecIpDao = Mockito.mock(NicSecondaryIpDao.class);
|
||||
|
||||
_lbMgr._lbDao = lbDao;
|
||||
_lbMgr._lb2VmMapDao = lb2VmMapDao;
|
||||
_lbMgr._vmDao = userVmDao;
|
||||
_lbMgr._accountDao = accountDao;
|
||||
_lbMgr._accountMgr = accountMgr;
|
||||
_lbMgr._networkDao = networkDao;
|
||||
_lbMgr._nicSecondaryIpDao = nicSecIpDao;
|
||||
_lbvmMapList = new ArrayList<>();
|
||||
_lbMgr._rulesMgr = _rulesMgr;
|
||||
_lbMgr._networkModel = _networkModel;
|
||||
|
||||
when(lbDao.findById(anyLong())).thenReturn(lbVO);
|
||||
when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
|
||||
when(userVmDao.findById(anyLong())).thenReturn(vm);
|
||||
when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);
|
||||
when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null);
|
||||
|
||||
|
|
@ -240,16 +245,23 @@ public class AssignLoadBalancerTest {
|
|||
vmIds.add(2L);
|
||||
|
||||
LoadBalancerVO lbVO = new LoadBalancerVO("1", "L1", "Lbrule", 1, 22, 22, "rb", 204, 0, 0, "tcp");
|
||||
UserVmVO vm = new UserVmVO(2L, "test", "test", 101L, Hypervisor.HypervisorType.Any, 21L, false, false, domainId, 200L, 1, 5L, "", "test");
|
||||
|
||||
LoadBalancerDao lbDao = Mockito.mock(LoadBalancerDao.class);
|
||||
LoadBalancerVMMapDao lb2VmMapDao = Mockito.mock(LoadBalancerVMMapDao.class);
|
||||
UserVmDao userVmDao = Mockito.mock(UserVmDao.class);
|
||||
AccountDao accountDao = Mockito.mock(AccountDao.class);
|
||||
AccountManager accountMgr = Mockito.mock(AccountManager.class);
|
||||
NetworkDao networkDao = Mockito.mock(NetworkDao.class);
|
||||
NicSecondaryIpDao nicSecIpDao = Mockito.mock(NicSecondaryIpDao.class);
|
||||
LoadBalancerVMMapVO lbVmMapVO = new LoadBalancerVMMapVO(1L, 1L, "10.1.1.175", false);
|
||||
|
||||
_lbMgr._lbDao = lbDao;
|
||||
_lbMgr._lb2VmMapDao = lb2VmMapDao;
|
||||
_lbMgr._vmDao = userVmDao;
|
||||
_lbMgr._accountDao = accountDao;
|
||||
_lbMgr._accountMgr = accountMgr;
|
||||
_lbMgr._networkDao = networkDao;
|
||||
_lbMgr._nicSecondaryIpDao = nicSecIpDao;
|
||||
_lbvmMapList = new ArrayList<>();
|
||||
_lbvmMapList.add(lbVmMapVO);
|
||||
|
|
@ -257,7 +269,7 @@ public class AssignLoadBalancerTest {
|
|||
_lbMgr._networkModel = _networkModel;
|
||||
|
||||
when(lbDao.findById(anyLong())).thenReturn(lbVO);
|
||||
when(userVmDao.findById(anyLong())).thenReturn(Mockito.mock(UserVmVO.class));
|
||||
when(userVmDao.findById(anyLong())).thenReturn(vm);
|
||||
when(lb2VmMapDao.listByLoadBalancerId(anyLong(), anyBoolean())).thenReturn(_lbvmMapList);
|
||||
when (nicSecIpDao.findByIp4AddressAndNicId(anyString(), anyLong())).thenReturn(null);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,14 @@ import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
|||
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
|
||||
import org.apache.cloudstack.api.command.admin.network.ListGuestVlansCmd;
|
||||
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RemoveNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ResetNetworkPermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
|
||||
|
|
@ -49,11 +54,13 @@ import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
|
|||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.GuestVlan;
|
||||
import com.cloud.network.GuestVlanRange;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.IpAddresses;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkPermission;
|
||||
import com.cloud.network.NetworkProfile;
|
||||
import com.cloud.network.NetworkService;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
|
|
@ -318,13 +325,13 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||
}
|
||||
|
||||
@Override
|
||||
public GuestVlan dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
|
||||
public GuestVlanRange dedicateGuestVlanRange(DedicateGuestVlanRangeCmd cmd) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends GuestVlan>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
|
||||
public Pair<List<? extends GuestVlanRange>, Integer> listDedicatedGuestVlanRanges(ListDedicatedGuestVlanRangesCmd cmd) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
|
@ -516,7 +523,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||
*/
|
||||
@Override
|
||||
public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIP, String gateway,
|
||||
String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId, Boolean bypassVlanOverlapCheck) throws ResourceAllocationException, ConcurrentOperationException,
|
||||
String netmask, long networkOwnerId, Long vpcId, Boolean sourceNat, Long networkOfferingId, Boolean bypassVlanOverlapCheck, Long associatedNetworkId) throws ResourceAllocationException, ConcurrentOperationException,
|
||||
InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
@ -973,6 +980,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSharedNetworkWithoutSpecifyVlan(NetworkOffering offering) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpAddress updateIP(Long id, String customId, Boolean displayIp) {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
@ -1007,4 +1019,29 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||
@Override
|
||||
public void unmanageNics(VirtualMachineProfile vm) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends GuestVlan>, Integer> listGuestVlans(ListGuestVlansCmd cmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends NetworkPermission> listNetworkPermissions(ListNetworkPermissionsCmd listNetworkPermissionsCmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createNetworkPermissions(CreateNetworkPermissionsCmd createNetworkPermissionsCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeNetworkPermissions(RemoveNetworkPermissionsCmd removeNetworkPermissionsCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetNetworkPermissions(ResetNetworkPermissionsCmd resetNetworkPermissionsCmd) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import com.cloud.network.dao.IPAddressVO;
|
|||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.NetworkOffering.Detail;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
|
|
@ -541,6 +542,16 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkNetworkOperatePermissions(Account owner, Network network) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkRouterPermissions(Account owner, VirtualRouter router) {
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.network.NetworkModel#getDefaultManagementTrafficLabel(long, com.cloud.hypervisor.Hypervisor.HypervisorType)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -136,12 +136,12 @@ public class CreateNetworkOfferingTest extends TestCase {
|
|||
assertNotNull("Shared network offering with specifyVlan=true failed to create ", off);
|
||||
}
|
||||
|
||||
@Test(expected=InvalidParameterValueException.class)
|
||||
@Test
|
||||
public void createSharedNtwkOffWithNoVlan() {
|
||||
NetworkOfferingVO off =
|
||||
configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, false, Availability.Optional, 200, null, false, Network.GuestType.Shared,
|
||||
false, null, false, null, true, false, null, false, null, true, false, null, null, false);
|
||||
assertNull("Shared network offering with specifyVlan=false was created", off);
|
||||
assertNotNull("Shared network offering with specifyVlan=false was created", off);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,760 @@
|
|||
# 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.
|
||||
|
||||
"""
|
||||
Tests of network permissions
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
|
||||
from marvin.lib.base import (Account,
|
||||
Configurations,
|
||||
Domain,
|
||||
Project,
|
||||
ServiceOffering,
|
||||
VirtualMachine,
|
||||
Zone,
|
||||
Network,
|
||||
NetworkOffering,
|
||||
NetworkPermission,
|
||||
NIC,
|
||||
PublicIPAddress,
|
||||
LoadBalancerRule,
|
||||
NATRule,
|
||||
StaticNATRule,
|
||||
|
||||
SSHKeyPair)
|
||||
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template)
|
||||
|
||||
NETWORK_FILTER_ACCOUNT = 'account'
|
||||
NETWORK_FILTER_DOMAIN = 'domain'
|
||||
NETWORK_FILTER_ACCOUNT_DOMAIN = 'accountdomain'
|
||||
NETWORK_FILTER_SHARED = 'shared'
|
||||
NETWORK_FILTER_ALL = 'all'
|
||||
|
||||
class TestNetworkPermissions(cloudstackTestCase):
|
||||
"""
|
||||
Test user-shared networks
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(
|
||||
TestNetworkPermissions,
|
||||
cls).getClsTestClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
|
||||
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
cls.zone = Zone(zone.__dict__)
|
||||
cls.template = get_template(cls.apiclient, cls.zone.id)
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger("TestNetworkPermissions")
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
|
||||
# Create small service offering
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["service_offerings"]["small"]
|
||||
)
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
|
||||
# Create network offering for isolated networks
|
||||
cls.network_offering_isolated = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["isolated_network_offering"]
|
||||
)
|
||||
cls.network_offering_isolated.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_isolated)
|
||||
|
||||
# Create sub-domain
|
||||
cls.sub_domain = Domain.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["domain1"]
|
||||
)
|
||||
cls._cleanup.append(cls.sub_domain)
|
||||
|
||||
# Create domain admin and normal user
|
||||
cls.domain_admin = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD1A"],
|
||||
admin=True,
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.domain_admin)
|
||||
|
||||
cls.network_owner = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD11A"],
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.network_owner)
|
||||
|
||||
cls.other_user = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD11B"],
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.other_user)
|
||||
|
||||
# Create project
|
||||
cls.project = Project.create(
|
||||
cls.apiclient,
|
||||
cls.services["project"],
|
||||
account=cls.domain_admin.name,
|
||||
domainid=cls.domain_admin.domainid
|
||||
)
|
||||
cls._cleanup.append(cls.project)
|
||||
|
||||
# Create api clients for domain admin and normal user
|
||||
cls.domainadmin_user = cls.domain_admin.user[0]
|
||||
cls.domainadmin_apiclient = cls.testClient.getUserApiClient(
|
||||
cls.domainadmin_user.username, cls.sub_domain.name
|
||||
)
|
||||
cls.networkowner_user = cls.network_owner.user[0]
|
||||
cls.user_apiclient = cls.testClient.getUserApiClient(
|
||||
cls.networkowner_user.username, cls.sub_domain.name
|
||||
)
|
||||
|
||||
cls.otheruser_user = cls.other_user.user[0]
|
||||
cls.otheruser_apiclient = cls.testClient.getUserApiClient(
|
||||
cls.otheruser_user.username, cls.sub_domain.name
|
||||
)
|
||||
|
||||
# Create networks for domain admin, normal user and project
|
||||
cls.services["network"]["name"] = "Test Network Isolated - Project"
|
||||
cls.project_network = Network.create(
|
||||
cls.apiclient,
|
||||
cls.services["network"],
|
||||
networkofferingid=cls.network_offering_isolated.id,
|
||||
domainid=cls.sub_domain.id,
|
||||
projectid=cls.project.id,
|
||||
zoneid=cls.zone.id
|
||||
)
|
||||
cls._cleanup.append(cls.project_network)
|
||||
|
||||
cls.services["network"]["name"] = "Test Network Isolated - Domain admin"
|
||||
cls.domainadmin_network = Network.create(
|
||||
cls.apiclient,
|
||||
cls.services["network"],
|
||||
networkofferingid=cls.network_offering_isolated.id,
|
||||
domainid=cls.sub_domain.id,
|
||||
accountid=cls.domain_admin.name,
|
||||
zoneid=cls.zone.id
|
||||
)
|
||||
cls._cleanup.append(cls.domainadmin_network)
|
||||
|
||||
cls.services["network"]["name"] = "Test Network Isolated - Normal user"
|
||||
cls.user_network = Network.create(
|
||||
cls.apiclient,
|
||||
cls.services["network"],
|
||||
networkofferingid=cls.network_offering_isolated.id,
|
||||
domainid=cls.sub_domain.id,
|
||||
accountid=cls.network_owner.name,
|
||||
zoneid=cls.zone.id
|
||||
)
|
||||
cls._cleanup.append(cls.user_network)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
super(TestNetworkPermissions, cls).tearDownClass()
|
||||
|
||||
def setUp(self):
|
||||
self.cleanup = []
|
||||
self.virtual_machine = None
|
||||
|
||||
def tearDown(self):
|
||||
super(TestNetworkPermissions, self).tearDown()
|
||||
|
||||
def list_network(self, apiclient, account, network, project, network_filter=None, expected=True):
|
||||
# List networks by apiclient, account, network, project and network network_filter
|
||||
# If account is specified, list the networks which can be used by the domain (canusefordeploy=true,listall=false)
|
||||
# otherwise canusefordeploy is None and listall is True.
|
||||
domain_id = None
|
||||
account_name = None
|
||||
project_id = None
|
||||
canusefordeploy = None
|
||||
list_all = True
|
||||
if account:
|
||||
domain_id = account.domainid
|
||||
account_name = account.name
|
||||
canusefordeploy = True
|
||||
list_all = False
|
||||
if project:
|
||||
project_id = project.id
|
||||
networks = None
|
||||
try:
|
||||
networks = Network.list(
|
||||
apiclient,
|
||||
canusefordeploy=canusefordeploy,
|
||||
listall=list_all,
|
||||
networkfilter= network_filter,
|
||||
domainid=domain_id,
|
||||
account=account_name,
|
||||
projectid=project_id,
|
||||
id=network.id
|
||||
)
|
||||
if isinstance(networks, list) and len(networks) > 0:
|
||||
if not expected:
|
||||
self.fail("Found the network, but expected to fail")
|
||||
elif expected:
|
||||
self.fail("Failed to find the network, but expected to succeed")
|
||||
except Exception as ex:
|
||||
networks = None
|
||||
if expected:
|
||||
self.fail(f"Failed to list network, but expected to succeed : {ex}")
|
||||
if networks and not expected:
|
||||
self.fail("network is listed successfully, but expected to fail")
|
||||
|
||||
def list_network_by_filters(self, apiclient, account, network, project, expected_results=None):
|
||||
# expected results in order: account/domain/accountdomain/shared/all
|
||||
self.list_network(apiclient, account, network, project, NETWORK_FILTER_ACCOUNT, expected_results[0])
|
||||
self.list_network(apiclient, account, network, project, NETWORK_FILTER_DOMAIN, expected_results[1])
|
||||
self.list_network(apiclient, account, network, project, NETWORK_FILTER_ACCOUNT_DOMAIN, expected_results[2])
|
||||
self.list_network(apiclient, account, network, project, NETWORK_FILTER_SHARED, expected_results[3])
|
||||
self.list_network(apiclient, account, network, project, NETWORK_FILTER_ALL, expected_results[4])
|
||||
|
||||
def create_network_permission(self, apiclient, network, account, project, expected=True):
|
||||
account_id = None
|
||||
project_id = None
|
||||
if account:
|
||||
account_id = account.id
|
||||
if project:
|
||||
project_id = project.id
|
||||
result = True
|
||||
try:
|
||||
NetworkPermission.create(
|
||||
apiclient,
|
||||
networkid=network.id,
|
||||
accountids=account_id,
|
||||
projectids=project_id
|
||||
)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to create network permissions, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("network permission is created successfully, but expected to fail")
|
||||
|
||||
def remove_network_permission(self, apiclient, network, account, project, expected=True):
|
||||
account_id = None
|
||||
project_id = None
|
||||
if account:
|
||||
account_id = account.id
|
||||
if project:
|
||||
project_id = project.id
|
||||
result = True
|
||||
try:
|
||||
NetworkPermission.remove(
|
||||
apiclient,
|
||||
networkid=network.id,
|
||||
accountids=account_id,
|
||||
projectids=project_id
|
||||
)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove network permissions, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("network permission is removed successfully, but expected to fail")
|
||||
|
||||
def reset_network_permission(self, apiclient, network, expected=True):
|
||||
result = True
|
||||
try:
|
||||
NetworkPermission.reset(
|
||||
apiclient,
|
||||
networkid=network.id
|
||||
)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to reset network permissions, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("network permission is reset successfully, but expected to fail")
|
||||
|
||||
def exec_command(self, apiclient_str, command, expected=None):
|
||||
result = True
|
||||
try:
|
||||
command = command.format(apiclient = apiclient_str)
|
||||
exec(command)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to execute command '{command}' with exception : {ex}")
|
||||
if result and expected is False:
|
||||
self.fail(f"command {command} is executed successfully, but expected to fail")
|
||||
if expected is None:
|
||||
# if expected is None, display the command and result
|
||||
self.logger.info(f"Result of command '{command}' : {result}")
|
||||
return result
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_01_network_permission_on_project_network(self):
|
||||
""" Testing network permissions on project network """
|
||||
|
||||
self.create_network_permission(self.apiclient, self.project_network, self.domain_admin, None, expected=False)
|
||||
self.create_network_permission(self.domainadmin_apiclient, self.project_network, self.domain_admin, None, expected=False)
|
||||
self.create_network_permission(self.user_apiclient, self.project_network, self.network_owner, None, expected=False)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_02_network_permission_on_user_network(self):
|
||||
""" Testing network permissions on user network """
|
||||
|
||||
# List user network by domain admin
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, None, self.user_network, None, [True, False, True, False, True])
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, self.domain_admin, self.user_network, None, [False, False, False, False, False])
|
||||
|
||||
# Create network permissions
|
||||
self.create_network_permission(self.apiclient, self.user_network, self.domain_admin, None, expected=True)
|
||||
self.create_network_permission(self.domainadmin_apiclient, self.user_network, self.domain_admin, None, expected=True)
|
||||
self.create_network_permission(self.user_apiclient, self.user_network, self.network_owner, None, expected=True)
|
||||
self.create_network_permission(self.user_apiclient, self.user_network, self.other_user, None, expected=True)
|
||||
self.create_network_permission(self.user_apiclient, self.user_network, None, self.project, expected=False)
|
||||
self.create_network_permission(self.domainadmin_apiclient, self.user_network, None, self.project, expected=True)
|
||||
self.create_network_permission(self.otheruser_apiclient, self.user_network, self.network_owner, None, expected=False)
|
||||
|
||||
# List domain admin network by domain admin
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, None, self.domainadmin_network, None, [True, False, True, False, True])
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, self.domain_admin, self.domainadmin_network, None, [True, False, True, False, True])
|
||||
# List user network by domain admin
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, None, self.user_network, None, [True, False, True, True, True])
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, self.domain_admin, self.user_network, None, [False, False, False, True, True])
|
||||
# List user network by user
|
||||
self.list_network_by_filters(self.user_apiclient, None, self.user_network, None, [True, False, True, False, True])
|
||||
self.list_network_by_filters(self.user_apiclient, self.network_owner, self.user_network, None, [True, False, True, False, True])
|
||||
# List user network by other user
|
||||
self.list_network_by_filters(self.otheruser_apiclient, None, self.user_network, None, [False, False, False, True, True])
|
||||
self.list_network_by_filters(self.otheruser_apiclient, self.network_owner, self.user_network, None, [False, False, False, False, False])
|
||||
|
||||
# Remove network permissions
|
||||
self.remove_network_permission(self.domainadmin_apiclient, self.user_network, self.domain_admin, None, expected=True)
|
||||
# List user network by domain admin
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, None, self.user_network, None, [True, False, True, True, True])
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, self.domain_admin, self.user_network, None, [False, False, False, False, False])
|
||||
|
||||
# Reset network permissions
|
||||
self.reset_network_permission(self.domainadmin_apiclient, self.user_network, expected=True)
|
||||
# List user network by domain admin
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, None, self.user_network, None, [True, False, True, False, True])
|
||||
self.list_network_by_filters(self.domainadmin_apiclient, self.domain_admin, self.user_network, None, [False, False, False, False, False])
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_03_network_operations_on_created_vm_of_otheruser(self):
|
||||
""" Testing network operations on a create vm owned by other user"""
|
||||
|
||||
# 1. Create an Isolated network by other user
|
||||
self.services["network"]["name"] = "Test Network Isolated - Other user"
|
||||
otheruser_network = Network.create(
|
||||
self.otheruser_apiclient,
|
||||
self.services["network"],
|
||||
networkofferingid=self.network_offering_isolated.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.cleanup.append(otheruser_network)
|
||||
|
||||
# 2. Deploy vm1 on other user's network
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.otheruser_apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
networkids=otheruser_network.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
|
||||
# 3. Add user network to vm1, should fail by vm owner and network owner
|
||||
command = """self.virtual_machine.add_nic({apiclient}, self.user_network.id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
|
||||
# 4. Create network permission for other user, should succeed by network owner
|
||||
command = """self.create_network_permission({apiclient}, self.user_network, self.other_user, None, expected=True)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
|
||||
# 5. Add user network to vm1, should succeed by vm owner
|
||||
command = """self.virtual_machine.add_nic({apiclient}, self.user_network.id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 6. Stop vm1 with forced=true, should succeed by vm owner
|
||||
command = """self.virtual_machine.stop({apiclient}, forced=True)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# Get id of the additional nic
|
||||
list_vms = VirtualMachine.list(
|
||||
self.otheruser_apiclient,
|
||||
id = self.virtual_machine.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vms, list),
|
||||
True,
|
||||
"Check if virtual machine is present"
|
||||
)
|
||||
self.assertEqual(
|
||||
len(list_vms) > 0,
|
||||
True,
|
||||
"Check if virtual machine list is empty"
|
||||
)
|
||||
self.vm_default_nic_id = None
|
||||
self.vm_new_nic_id = None
|
||||
for vm_nic in list_vms[0].nic:
|
||||
if vm_nic.networkid == self.user_network.id:
|
||||
self.vm_new_nic_id = vm_nic.id
|
||||
else:
|
||||
self.vm_default_nic_id = vm_nic.id
|
||||
|
||||
# 6. Update vm1 nic IP, should succeed by vm owner
|
||||
command = """NIC.updateIp({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 7. Start vm1, should succeed by vm owner
|
||||
command = """self.virtual_machine.start({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 8. Add secondary IP to nic, should succeed by vm owner
|
||||
command = """self.secondaryip = NIC.addIp({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 9 Remove secondary IP from nic, should succeed by vm owner
|
||||
command = """NIC.removeIp({apiclient}, self.secondaryip.id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 10. Update default NIC, should succeed by vm owner
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_default_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 11. Stop vm1 with forced=true
|
||||
command = """self.virtual_machine.stop({apiclient}, forced=True)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 12. Remove nic from vm1, should succeed by vm owner
|
||||
command = """self.virtual_machine.remove_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 13. Test operations by domain admin
|
||||
command = """self.virtual_machine.add_nic({apiclient}, self.user_network.id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
list_vms = VirtualMachine.list(
|
||||
self.otheruser_apiclient,
|
||||
id = self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.vm_default_nic_id = None
|
||||
self.vm_new_nic_id = None
|
||||
for vm_nic in list_vms[0].nic:
|
||||
if vm_nic.networkid == self.user_network.id:
|
||||
self.vm_new_nic_id = vm_nic.id
|
||||
else:
|
||||
self.vm_default_nic_id = vm_nic.id
|
||||
|
||||
command = """NIC.updateIp({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
command = """self.secondaryip = NIC.addIp({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
command = """NIC.removeIp({apiclient}, self.secondaryip.id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_default_nic_id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.remove_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 14. Test operations by vm owner, when network permission is removed
|
||||
command = """self.virtual_machine.add_nic({apiclient}, self.user_network.id)"""
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 15. Reset network permissions, should succeed by network owner
|
||||
command = """self.reset_network_permission({apiclient}, self.user_network, expected=True)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
|
||||
list_vms = VirtualMachine.list(
|
||||
self.otheruser_apiclient,
|
||||
id = self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.vm_default_nic_id = None
|
||||
self.vm_new_nic_id = None
|
||||
for vm_nic in list_vms[0].nic:
|
||||
if vm_nic.networkid == self.user_network.id:
|
||||
self.vm_new_nic_id = vm_nic.id
|
||||
else:
|
||||
self.vm_default_nic_id = vm_nic.id
|
||||
|
||||
command = """NIC.updateIp({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
command = """self.secondaryip = NIC.addIp({apiclient}, self.vm_new_nic_id)"""
|
||||
if self.exec_command("self.otheruser_apiclient", command, expected=True):
|
||||
command = """NIC.removeIp({apiclient}, self.secondaryip.id)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
if self.exec_command("self.otheruser_apiclient", command, expected=True):
|
||||
command = """self.virtual_machine.update_default_nic({apiclient}, self.vm_default_nic_id)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.start({apiclient})"""
|
||||
if self.exec_command("self.otheruser_apiclient", command, expected=True):
|
||||
command = """self.virtual_machine.stop({apiclient}, forced=True)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
command = """self.virtual_machine.remove_nic({apiclient}, self.vm_new_nic_id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 16. Destroy vm1, should succeed by root admin
|
||||
self.virtual_machine.delete(self.apiclient, expunge=True)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_04_deploy_vm_for_other_user_and_test_vm_operations(self):
|
||||
""" Deploy VM for other user and test VM operations by vm owner, network owner and domain admin"""
|
||||
|
||||
# 1. Create network permission for other user, by user
|
||||
command = """self.create_network_permission({apiclient}, self.user_network, self.other_user, None, expected=True)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
|
||||
# 2. Deploy vm2 on user network
|
||||
command = """self.virtual_machine = VirtualMachine.create(
|
||||
{apiclient},
|
||||
self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
networkids=self.user_network.id,
|
||||
accountid=self.other_user.name,
|
||||
domainid=self.other_user.domainid,
|
||||
zoneid=self.zone.id
|
||||
)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
if not self.virtual_machine:
|
||||
self.fail("Failed to find self.virtual_machine")
|
||||
|
||||
# 3. List vm2
|
||||
list_vms = VirtualMachine.list(
|
||||
self.user_apiclient,
|
||||
id = self.virtual_machine.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vms, list) and len(list_vms) > 0,
|
||||
False,
|
||||
"Check if virtual machine is not present"
|
||||
)
|
||||
list_vms = VirtualMachine.list(
|
||||
self.otheruser_apiclient,
|
||||
id = self.virtual_machine.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vms, list) and len(list_vms) > 0,
|
||||
True,
|
||||
"Check if virtual machine is present"
|
||||
)
|
||||
|
||||
# 4. Stop vm2 with forced=true
|
||||
command = """self.virtual_machine.stop({apiclient}, forced=True)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 5. Reset vm password
|
||||
if self.template.passwordenabled:
|
||||
command = """self.virtual_machine.resetPassword({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 6. Reset vm SSH key
|
||||
self.keypair = SSHKeyPair.create(
|
||||
self.otheruser_apiclient,
|
||||
name=self.other_user.name + ".pem"
|
||||
)
|
||||
command = """self.virtual_machine.resetSshKey({apiclient}, keypair=self.keypair.name)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 7. Start vm2
|
||||
command = """self.virtual_machine.start({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 8. Acquire public IP, should succeed by domain admin and network owner
|
||||
command = """self.public_ip = PublicIPAddress.create(
|
||||
{apiclient},
|
||||
zoneid=self.zone.id,
|
||||
networkid=self.user_network.id
|
||||
)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 9. Enable static nat, should succeed by domain admin
|
||||
command = """StaticNATRule.enable(
|
||||
{apiclient},
|
||||
ipaddressid=self.public_ip.ipaddress.id,
|
||||
virtualmachineid=self.virtual_machine.id
|
||||
)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 10. Disable static nat, should succeed by domain admin and network owner
|
||||
command = """StaticNATRule.disable(
|
||||
{apiclient},
|
||||
ipaddressid=self.public_ip.ipaddress.id
|
||||
)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 11. Create port forwarding rule, should succeed by domain admin
|
||||
command = """self.port_forwarding_rule = NATRule.create(
|
||||
{apiclient},
|
||||
virtual_machine=self.virtual_machine,
|
||||
services=self.services["natrule"],
|
||||
ipaddressid=self.public_ip.ipaddress.id,
|
||||
)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 12. Delete port forwarding rule, should succeed by domain admin and network owner
|
||||
command = """self.port_forwarding_rule.delete({apiclient})"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 13. Create load balancer rule, should succeed by domain admin and network owner
|
||||
command = """self.load_balancer_rule = LoadBalancerRule.create(
|
||||
{apiclient},
|
||||
self.services["lbrule"],
|
||||
ipaddressid=self.public_ip.ipaddress.id,
|
||||
networkid=self.user_network.id,
|
||||
)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 14. Assign virtual machine to load balancing rule, should succeed by domain admin
|
||||
command = """self.load_balancer_rule.assign({apiclient}, vms=[self.virtual_machine])"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 15. Remove virtual machine from load balancing rule, should succeed by domain admin and network owner
|
||||
command = """self.load_balancer_rule.remove({apiclient}, vms=[self.virtual_machine])"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 16. Delete load balancing rule, should succeed by domain admin and network owner
|
||||
command = """self.load_balancer_rule.delete({apiclient})"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 17. Release public IP, should succeed by domain admin and network owner
|
||||
command = """self.public_ip.delete({apiclient})"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
#self.exec_command("self.domainadmin_apiclient", command, expected=True)
|
||||
|
||||
# 18. Stop vm2 with forced=true, should succeed by vm owner
|
||||
command = """self.virtual_machine.stop({apiclient}, forced=True)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 19. Update vm2, should succeed by vm owner
|
||||
command = """self.virtual_machine.update({apiclient}, displayname = self.virtual_machine.displayname + ".new")"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 20. Restore vm2, should succeed by vm owner
|
||||
command = """self.virtual_machine.restore({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 21. Scale vm2 to another offering, should succeed by vm owner
|
||||
self.service_offering_new = ServiceOffering.create(
|
||||
self.apiclient,
|
||||
self.services["service_offerings"]["big"]
|
||||
)
|
||||
self.cleanup.append(self.service_offering_new)
|
||||
command = """self.virtual_machine.scale_virtualmachine({apiclient}, self.service_offering_new.id)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 22. Destroy vm2, should succeed by vm owner
|
||||
command = """self.virtual_machine.delete({apiclient}, expunge=False)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 23. Recover vm2, should succeed by vm owner
|
||||
allow_expunge_recover_vm = Configurations.list(self.apiclient, name="allow.user.expunge.recover.vm")[0].value
|
||||
self.logger.debug("Global configuration allow.user.expunge.recover.vm = %s", allow_expunge_recover_vm)
|
||||
if allow_expunge_recover_vm == "true":
|
||||
command = """self.virtual_machine.recover({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 24. Destroy vm2, should succeed by vm owner
|
||||
command = """self.virtual_machine.delete({apiclient}, expunge=False)"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
|
||||
# 25. Expunge vm2, should succeed by vm owner
|
||||
if allow_expunge_recover_vm == "true":
|
||||
command = """self.virtual_machine.expunge({apiclient})"""
|
||||
self.exec_command("self.user_apiclient", command, expected=False)
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=True)
|
||||
else:
|
||||
self.virtual_machine.expunge(self.apiclient)
|
||||
|
||||
# 26. Reset network permissions, should succeed by network owner
|
||||
command = """self.reset_network_permission({apiclient}, self.user_network, expected=True)"""
|
||||
self.exec_command("self.otheruser_apiclient", command, expected=False)
|
||||
self.exec_command("self.user_apiclient", command, expected=True)
|
||||
|
|
@ -30,12 +30,27 @@ _multiprocess_shared_ = True
|
|||
class TestPVLAN(cloudstackTestCase):
|
||||
|
||||
zoneId = 1
|
||||
networkOfferingId = 7
|
||||
vlan = 2468
|
||||
isolatedpvlan = 864
|
||||
|
||||
def setUp(self):
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
list_shared_network_offerings = NetworkOffering.list(
|
||||
self.apiClient,
|
||||
name="DefaultSharedNetworkOffering",
|
||||
displayText="Offering for Shared networks"
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_shared_network_offerings, list),
|
||||
True,
|
||||
"List network offerings response was not a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_shared_network_offerings),
|
||||
0,
|
||||
"List network offerings response was empty"
|
||||
)
|
||||
self.networkOfferingId = list_shared_network_offerings[0].id
|
||||
|
||||
@attr(tags = ["advanced"], required_hardware="false")
|
||||
def test_create_pvlan_network(self):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,425 @@
|
|||
# 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.
|
||||
|
||||
"""
|
||||
Tests of user-private gateway
|
||||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.utils import cleanup_resources, random_gen
|
||||
|
||||
from marvin.lib.base import (Account,
|
||||
Domain,
|
||||
Project,
|
||||
Configurations,
|
||||
ServiceOffering,
|
||||
Zone,
|
||||
Network,
|
||||
NetworkOffering,
|
||||
VPC,
|
||||
VpcOffering,
|
||||
PrivateGateway)
|
||||
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template)
|
||||
|
||||
NETWORK_STATE_ALLOCATED = "Allocated"
|
||||
NETWORK_STATE_IMPLEMENTED = "Implemented"
|
||||
NETWORK_STATE_SETUP = "Setup"
|
||||
NETWORK_STATE_REMOVED = "Removed"
|
||||
|
||||
class TestUserPrivateGateways(cloudstackTestCase):
|
||||
"""
|
||||
Test user-shared networks
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(
|
||||
TestUserPrivateGateways,
|
||||
cls).getClsTestClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
|
||||
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
cls.zone = Zone(zone.__dict__)
|
||||
cls.template = get_template(cls.apiclient, cls.zone.id)
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger("TestUserPrivateGateways")
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
|
||||
# Create small service offering
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["service_offerings"]["small"]
|
||||
)
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
|
||||
# Create network offering for isolated networks
|
||||
cls.network_offering_isolated = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["network_offering"]
|
||||
)
|
||||
cls.network_offering_isolated.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_isolated)
|
||||
|
||||
# Create vpc offering
|
||||
cls.vpc_offering = VpcOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["vpc_offering_multi_lb"])
|
||||
cls.vpc_offering.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.vpc_offering)
|
||||
|
||||
# Create network offering for vpc tiers
|
||||
cls.network_offering_vpc = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["nw_offering_isolated_vpc"],
|
||||
conservemode=False
|
||||
)
|
||||
cls.network_offering_vpc.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_vpc)
|
||||
|
||||
# Create sub-domain
|
||||
cls.sub_domain = Domain.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["domain1"]
|
||||
)
|
||||
cls._cleanup.append(cls.sub_domain)
|
||||
|
||||
# Create domain admin and normal user
|
||||
cls.domain_admin = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD1A"],
|
||||
admin=True,
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.domain_admin)
|
||||
|
||||
cls.normal_user = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD1B"],
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.normal_user)
|
||||
|
||||
# Create project
|
||||
cls.project = Project.create(
|
||||
cls.apiclient,
|
||||
cls.services["project"],
|
||||
account=cls.domain_admin.name,
|
||||
domainid=cls.domain_admin.domainid
|
||||
)
|
||||
cls._cleanup.append(cls.project)
|
||||
|
||||
# Create api clients for domain admin and normal user
|
||||
cls.domainadmin_user = cls.domain_admin.user[0]
|
||||
cls.domainapiclient = cls.testClient.getUserApiClient(
|
||||
cls.domainadmin_user.username, cls.sub_domain.name
|
||||
)
|
||||
cls.normaluser_user = cls.normal_user.user[0]
|
||||
cls.normaluser_apiclient = cls.testClient.getUserApiClient(
|
||||
cls.normaluser_user.username, cls.sub_domain.name
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
super(TestUserPrivateGateways, cls).tearDownClass()
|
||||
|
||||
def setUp(self):
|
||||
self.cleanup = []
|
||||
|
||||
def tearDown(self):
|
||||
super(TestUserPrivateGateways, self).tearDown()
|
||||
|
||||
def delete_network(self, network, apiclient, expected=True):
|
||||
result = True
|
||||
try:
|
||||
Network.delete(
|
||||
network,
|
||||
apiclient,
|
||||
)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove Shared network, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("network is removed successfully, but expected to fail")
|
||||
|
||||
def create_isolated_network_for_account(self, apiclient, domain, account, project, expected=True):
|
||||
self.services["network"]["name"] = "Test Network Isolated - " + random_gen()
|
||||
domain_id = None
|
||||
account_name = None
|
||||
project_id = None
|
||||
if domain:
|
||||
domain_id = domain.id
|
||||
if account:
|
||||
account_name = account.name
|
||||
if project:
|
||||
project_id = project.id
|
||||
try:
|
||||
network = Network.create(
|
||||
apiclient,
|
||||
self.services["network"],
|
||||
domainid=domain_id,
|
||||
accountid=account_name,
|
||||
projectid=project_id,
|
||||
networkofferingid=self.network_offering_isolated.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
except Exception as ex:
|
||||
network = None
|
||||
if expected:
|
||||
self.fail(f"Failed to create Isolated network, but expected to succeed : {ex}")
|
||||
if network and not expected:
|
||||
self.fail("Isolated network is created successfully, but expected to fail")
|
||||
return network
|
||||
|
||||
def check_network_state(self, apiclient, network, project, expected_state):
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
networks = Network.list(
|
||||
apiclient,
|
||||
listall=True,
|
||||
projectid=project_id,
|
||||
id=network.id
|
||||
)
|
||||
if isinstance(networks, list) and len(networks) > 0:
|
||||
if expected_state == NETWORK_STATE_REMOVED:
|
||||
self.fail("Found the network, but expected to fail")
|
||||
if networks[0].state != expected_state:
|
||||
self.fail(f"Expect network state is {expected_state}, but actual state is {networks[0].state}")
|
||||
elif expected_state != NETWORK_STATE_REMOVED:
|
||||
self.fail("Failed to find the network, but expected to succeed")
|
||||
|
||||
def create_vpc_for_account(self, apiclient, domain, account, project):
|
||||
self.services["vpc"]["name"] = "Test VPC - " + random_gen()
|
||||
self.services["vpc"]["cidr"] = "10.1.0.0/20"
|
||||
domain_id = None
|
||||
account_name = None
|
||||
if domain:
|
||||
domain_id = domain.id
|
||||
if account:
|
||||
account_name = account.name
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
vpc = VPC.create(
|
||||
apiclient,
|
||||
self.services["vpc"],
|
||||
domainid=domain_id,
|
||||
accountid=account_name,
|
||||
projectid=project_id,
|
||||
vpcofferingid=self.vpc_offering.id,
|
||||
zoneid=self.zone.id,
|
||||
start=False
|
||||
)
|
||||
return vpc
|
||||
|
||||
def create_vpc_tier_for_account(self, apiclient, vpc, project=None, gateway = '10.1.1.1'):
|
||||
self.services["network"]["name"] = "Test VPC tier - " + random_gen()
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
vpc_tier = Network.create(
|
||||
apiclient,
|
||||
self.services["network"],
|
||||
networkofferingid=self.network_offering_vpc.id,
|
||||
zoneid=self.zone.id,
|
||||
projectid=project_id,
|
||||
gateway=gateway,
|
||||
netmask="255.255.255.0",
|
||||
vpcid=vpc.id
|
||||
)
|
||||
return vpc_tier
|
||||
|
||||
def create_vpc_private_gateway(self, apiclient, vpc, vlan_id, associated_network=None, expected=True):
|
||||
self.services["private_gateway"]["name"] = "Test Network Isolated - " + random_gen()
|
||||
associated_network_id = None
|
||||
if associated_network:
|
||||
associated_network_id = associated_network.id
|
||||
private_gateway = None
|
||||
try:
|
||||
private_gateway = PrivateGateway.create(
|
||||
apiclient,
|
||||
vpcid=vpc.id,
|
||||
gateway = self.services["private_gateway"]["gateway"],
|
||||
ipaddress = self.services["private_gateway"]["ipaddress"],
|
||||
netmask = self.services["private_gateway"]["netmask"],
|
||||
vlan = vlan_id,
|
||||
associatednetworkid = associated_network_id
|
||||
)
|
||||
except Exception as ex:
|
||||
private_gateway = None
|
||||
if expected:
|
||||
self.fail(f"Failed to create private gateway, but expected to succeed : {ex}")
|
||||
if private_gateway and not expected:
|
||||
self.fail("private gateway is created successfully, but expected to fail")
|
||||
return private_gateway
|
||||
|
||||
def delete_vpc_private_gateway(self, apiclient, private_gateway, expected=True):
|
||||
result = True
|
||||
try:
|
||||
private_gateway.delete(apiclient)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove private gateway, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("private gateway is removed successfully, but expected to fail")
|
||||
|
||||
def delete_vpc(self, apiclient, vpc, expected=True):
|
||||
result = True
|
||||
try:
|
||||
vpc.delete(apiclient)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove VPC, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("VPC is removed successfully, but expected to fail")
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_01_create_private_gateway_with_vlan(self):
|
||||
""" Create private gateway with vlan """
|
||||
|
||||
# Create VPC
|
||||
vpc1 = self.create_vpc_for_account(self.apiclient, None, None, None)
|
||||
vpc2 = self.create_vpc_for_account(self.domainapiclient, None, None, None)
|
||||
vpc3 = self.create_vpc_for_account(self.normaluser_apiclient, None, None, None)
|
||||
vpc4 = self.create_vpc_for_account(self.domainapiclient, None, None, self.project)
|
||||
|
||||
# Create VPC private gateway with vlan (can only be done by ROOT admin)
|
||||
private_gateway1 = self.create_vpc_private_gateway(self.apiclient, vpc1, 10, None, True)
|
||||
self.create_vpc_private_gateway(self.domainapiclient, vpc2, 11, None, False)
|
||||
self.create_vpc_private_gateway(self.normaluser_apiclient, vpc3, 12, None, False)
|
||||
self.create_vpc_private_gateway(self.domainapiclient, vpc4, 13, None, False)
|
||||
private_gateway2 = self.create_vpc_private_gateway(self.apiclient, vpc2, 11, None, True)
|
||||
private_gateway3 = self.create_vpc_private_gateway(self.apiclient, vpc3, 12, None, True)
|
||||
private_gateway4 = self.create_vpc_private_gateway(self.apiclient, vpc4, 13, None, True)
|
||||
|
||||
# Delete VPC private gateway (should succeed by ROOT admin)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway1, True)
|
||||
self.delete_vpc_private_gateway(self.domainapiclient, private_gateway2, False)
|
||||
self.delete_vpc_private_gateway(self.normaluser_apiclient, private_gateway2, False)
|
||||
self.delete_vpc_private_gateway(self.domainapiclient, private_gateway4, False)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway2, True)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway3, True)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway4, True)
|
||||
|
||||
# Delete VPC
|
||||
self.delete_vpc(self.apiclient, vpc1)
|
||||
self.delete_vpc(self.domainapiclient, vpc2)
|
||||
self.delete_vpc(self.normaluser_apiclient, vpc3)
|
||||
self.delete_vpc(self.domainapiclient, vpc4)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_02_create_private_gateway_with_associated_network(self):
|
||||
""" Create private gateway with associated network """
|
||||
|
||||
self.services["network"]["networkoffering"] = self.network_offering_isolated.id
|
||||
self.services["network"]["vlan"] = None
|
||||
|
||||
# Create isolated networks
|
||||
isolated_network1 = self.create_isolated_network_for_account(self.apiclient, None, None, None)
|
||||
isolated_network2 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.domain_admin, None)
|
||||
isolated_network3 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.normal_user, None)
|
||||
isolated_network4 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, None, self.project)
|
||||
|
||||
# Check state of isolated networks (should be Allocated)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_ALLOCATED)
|
||||
|
||||
# Create VPC
|
||||
vpc1 = self.create_vpc_for_account(self.apiclient, None, None, None)
|
||||
vpc2 = self.create_vpc_for_account(self.domainapiclient, None, None, None)
|
||||
vpc3 = self.create_vpc_for_account(self.normaluser_apiclient, None, None, None)
|
||||
vpc4 = self.create_vpc_for_account(self.domainapiclient, None, None, self.project)
|
||||
|
||||
# Create VPC tier
|
||||
vpc1_tier1 = self.create_vpc_tier_for_account(self.apiclient, vpc1)
|
||||
vpc2_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc2)
|
||||
vpc3_tier1 = self.create_vpc_tier_for_account(self.normaluser_apiclient, vpc3)
|
||||
vpc4_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc4, self.project)
|
||||
|
||||
# Create VPC private gateway with associated network (can be done by ROOT admin / domain admin / normal user)
|
||||
private_gateway1 = self.create_vpc_private_gateway(self.apiclient, vpc1, None, isolated_network1, True)
|
||||
private_gateway2 = self.create_vpc_private_gateway(self.domainapiclient, vpc2, None, isolated_network2, True)
|
||||
private_gateway3 = self.create_vpc_private_gateway(self.normaluser_apiclient, vpc3, None, isolated_network3, True)
|
||||
private_gateway4 = self.create_vpc_private_gateway(self.domainapiclient, vpc4, None, isolated_network4, True)
|
||||
|
||||
# Check state of isolated networks (should be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete VPC private gateway of domain admin (should succeed)
|
||||
self.delete_vpc_private_gateway(self.domainapiclient, private_gateway2, True)
|
||||
|
||||
# Wait for network GC to shut down the isolated networks
|
||||
gc_wait = Configurations.list(self.apiclient, name="network.gc.wait")
|
||||
gc_interval = Configurations.list(self.apiclient, name="network.gc.interval")
|
||||
total_sleep = 360
|
||||
if gc_wait and gc_interval:
|
||||
self.logger.debug("network.gc.wait is ==> %s", gc_wait[0].value)
|
||||
self.logger.debug("network.gc.interval is ==> %s", gc_interval[0].value)
|
||||
total_sleep = max(int(gc_wait[0].value), int(gc_interval[0].value)) * 2 + 60
|
||||
else:
|
||||
self.logger.debug("Could not retrieve the keys 'network.gc.interval' and 'network.gc.wait'. Sleeping for 6 minutes.")
|
||||
time.sleep(total_sleep)
|
||||
|
||||
# Check state of isolated networks (1 should be Allocated, 2 should still be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete 2 VPC private gateway (should succeed)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway1, True)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway3, True)
|
||||
self.delete_vpc_private_gateway(self.apiclient, private_gateway4, True)
|
||||
|
||||
# Delete VPC tiers (should succeed)
|
||||
self.delete_network(vpc1_tier1, self.apiclient, True)
|
||||
self.delete_network(vpc2_tier1, self.domainapiclient, True)
|
||||
self.delete_network(vpc3_tier1, self.normaluser_apiclient, True)
|
||||
self.delete_network(vpc4_tier1, self.domainapiclient, True)
|
||||
|
||||
# Delete VPC
|
||||
self.delete_vpc(self.apiclient, vpc1)
|
||||
self.delete_vpc(self.domainapiclient, vpc2)
|
||||
self.delete_vpc(self.normaluser_apiclient, vpc3)
|
||||
self.delete_vpc(self.domainapiclient, vpc4)
|
||||
|
||||
# Delete isolated networks (should succeed)
|
||||
self.delete_network(isolated_network1, self.apiclient, True)
|
||||
self.delete_network(isolated_network2, self.domainapiclient, True)
|
||||
self.delete_network(isolated_network3, self.normaluser_apiclient, True)
|
||||
self.delete_network(isolated_network4, self.domainapiclient, True)
|
||||
|
|
@ -0,0 +1,631 @@
|
|||
# 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.
|
||||
|
||||
"""
|
||||
Tests of user-shared networks
|
||||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.utils import cleanup_resources, random_gen
|
||||
|
||||
from marvin.lib.base import (Account,
|
||||
Domain,
|
||||
Project,
|
||||
Configurations,
|
||||
ServiceOffering,
|
||||
Zone,
|
||||
Network,
|
||||
NetworkOffering,
|
||||
VPC,
|
||||
VpcOffering)
|
||||
|
||||
from marvin.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template)
|
||||
|
||||
NETWORK_STATE_ALLOCATED = "Allocated"
|
||||
NETWORK_STATE_IMPLEMENTED = "Implemented"
|
||||
NETWORK_STATE_SETUP = "Setup"
|
||||
NETWORK_STATE_REMOVED = "Removed"
|
||||
|
||||
class TestUserSharedNetworks(cloudstackTestCase):
|
||||
"""
|
||||
Test user-shared networks
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(
|
||||
TestUserSharedNetworks,
|
||||
cls).getClsTestClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
|
||||
zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
cls.zone = Zone(zone.__dict__)
|
||||
cls.template = get_template(cls.apiclient, cls.zone.id)
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger("TestUserSharedNetworks")
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
|
||||
|
||||
# Create small service offering
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["service_offerings"]["small"]
|
||||
)
|
||||
cls._cleanup.append(cls.service_offering)
|
||||
|
||||
# Create network offering for user-shared networks (specifyVlan=true)
|
||||
cls.network_offering_withvlan = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["network_offering_shared"]
|
||||
)
|
||||
cls.network_offering_withvlan.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_withvlan)
|
||||
|
||||
# Create network offering for user-shared networks (specifyVlan=false)
|
||||
cls.services["network_offering_shared"]["specifyVlan"] = "False"
|
||||
cls.network_offering_novlan = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["network_offering_shared"]
|
||||
)
|
||||
cls.network_offering_novlan.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_novlan)
|
||||
|
||||
# Create network offering for isolated networks
|
||||
cls.network_offering_isolated = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["network_offering"]
|
||||
)
|
||||
cls.network_offering_isolated.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_isolated)
|
||||
|
||||
# Create vpc offering
|
||||
cls.vpc_offering = VpcOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["vpc_offering_multi_lb"])
|
||||
cls.vpc_offering.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.vpc_offering)
|
||||
|
||||
# Create network offering for vpc tiers
|
||||
cls.network_offering_vpc = NetworkOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["nw_offering_isolated_vpc"],
|
||||
conservemode=False
|
||||
)
|
||||
cls.network_offering_vpc.update(cls.apiclient, state='Enabled')
|
||||
cls._cleanup.append(cls.network_offering_vpc)
|
||||
|
||||
# Create sub-domain
|
||||
cls.sub_domain = Domain.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["domain1"]
|
||||
)
|
||||
cls._cleanup.append(cls.sub_domain)
|
||||
|
||||
# Create domain admin and normal user
|
||||
cls.domain_admin = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD1A"],
|
||||
admin=True,
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.domain_admin)
|
||||
|
||||
cls.normal_user = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["acl"]["accountD1B"],
|
||||
domainid=cls.sub_domain.id
|
||||
)
|
||||
cls._cleanup.append(cls.normal_user)
|
||||
|
||||
# Create project
|
||||
cls.project = Project.create(
|
||||
cls.apiclient,
|
||||
cls.services["project"],
|
||||
account=cls.domain_admin.name,
|
||||
domainid=cls.domain_admin.domainid
|
||||
)
|
||||
cls._cleanup.append(cls.project)
|
||||
|
||||
# Create api clients for domain admin and normal user
|
||||
cls.domainadmin_user = cls.domain_admin.user[0]
|
||||
cls.domainapiclient = cls.testClient.getUserApiClient(
|
||||
cls.domainadmin_user.username, cls.sub_domain.name
|
||||
)
|
||||
cls.normaluser_user = cls.normal_user.user[0]
|
||||
cls.normaluser_apiclient = cls.testClient.getUserApiClient(
|
||||
cls.normaluser_user.username, cls.sub_domain.name
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
super(TestUserSharedNetworks, cls).tearDownClass()
|
||||
|
||||
def setUp(self):
|
||||
self.cleanup = []
|
||||
|
||||
def tearDown(self):
|
||||
super(TestUserSharedNetworks, self).tearDown()
|
||||
|
||||
def create_shared_network_for_account(self, apiclient, domain, account, expected=True):
|
||||
return self.create_shared_network_with_associated_network(apiclient, domain, account, None, None, expected)
|
||||
|
||||
def create_shared_network_with_associated_network_for_domain(self, apiclient, domain, associated_network, expected=True):
|
||||
return self.create_shared_network_with_associated_network(apiclient, domain, None, None, associated_network, expected)
|
||||
|
||||
def create_shared_network_with_associated_network_for_caller(self, apiclient, project, associated_network, expected=True):
|
||||
return self.create_shared_network_with_associated_network(apiclient, None, None, project, associated_network, expected)
|
||||
|
||||
def create_shared_network_with_associated_network(self, apiclient, domain, account, project, associated_network, expected=True):
|
||||
self.services["network2"]["acltype"] = "Account"
|
||||
self.services["network2"]["name"] = "Test Network Shared - " + random_gen()
|
||||
domain_id = None
|
||||
account_name = None
|
||||
project_id = None
|
||||
if domain:
|
||||
self.services["network2"]["acltype"] = "Domain"
|
||||
domain_id = domain.id
|
||||
if account:
|
||||
self.services["network2"]["acltype"] = "Account"
|
||||
account_name = account.name
|
||||
if project:
|
||||
self.services["network2"]["acltype"] = "Account"
|
||||
project_id = project.id
|
||||
associated_network_id = None
|
||||
if associated_network:
|
||||
associated_network_id = associated_network.id
|
||||
try:
|
||||
network = Network.create(
|
||||
apiclient,
|
||||
self.services["network2"],
|
||||
domainid=domain_id,
|
||||
accountid=account_name,
|
||||
projectid=project_id,
|
||||
associatednetworkid=associated_network_id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
except Exception as ex:
|
||||
network = None
|
||||
if expected:
|
||||
self.fail(f"Failed to create Shared network, but expected to succeed : {ex}")
|
||||
if network and not expected:
|
||||
self.fail("Shared network is created successfully, but expected to fail")
|
||||
return network
|
||||
|
||||
def delete_network(self, network, apiclient, expected=True):
|
||||
result = True
|
||||
try:
|
||||
Network.delete(
|
||||
network,
|
||||
apiclient,
|
||||
)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove Shared network, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("network is removed successfully, but expected to fail")
|
||||
|
||||
def create_isolated_network_for_account(self, apiclient, domain, account, project, expected=True):
|
||||
self.services["network"]["name"] = "Test Network Isolated - " + random_gen()
|
||||
domain_id = None
|
||||
account_name = None
|
||||
project_id = None
|
||||
if domain:
|
||||
domain_id = domain.id
|
||||
if account:
|
||||
account_name = account.name
|
||||
if project:
|
||||
project_id = project.id
|
||||
try:
|
||||
network = Network.create(
|
||||
apiclient,
|
||||
self.services["network"],
|
||||
domainid=domain_id,
|
||||
accountid=account_name,
|
||||
projectid=project_id,
|
||||
networkofferingid=self.network_offering_isolated.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
except Exception as ex:
|
||||
network = None
|
||||
if expected:
|
||||
self.fail(f"Failed to create Isolated network, but expected to succeed : {ex}")
|
||||
if network and not expected:
|
||||
self.fail("Isolated network is created successfully, but expected to fail")
|
||||
return network
|
||||
|
||||
def check_network_state(self, apiclient, network, project, expected_state):
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
networks = Network.list(
|
||||
apiclient,
|
||||
listall=True,
|
||||
projectid=project_id,
|
||||
id=network.id
|
||||
)
|
||||
if isinstance(networks, list) and len(networks) > 0:
|
||||
if expected_state == NETWORK_STATE_REMOVED:
|
||||
self.fail("Found the network, but expected to fail")
|
||||
if networks[0].state != expected_state:
|
||||
self.fail(f"Expect network state is {expected_state}, but actual state is {networks[0].state}")
|
||||
elif expected_state != NETWORK_STATE_REMOVED:
|
||||
self.fail("Failed to find the network, but expected to succeed")
|
||||
|
||||
def create_vpc_for_account(self, apiclient, domain, account, project):
|
||||
self.services["vpc"]["name"] = "Test VPC - " + random_gen()
|
||||
self.services["vpc"]["displaytext"] = self.services["vpc"]["name"]
|
||||
self.services["vpc"]["cidr"] = "10.1.0.0/20"
|
||||
domain_id = None
|
||||
account_name = None
|
||||
if domain:
|
||||
domain_id = domain.id
|
||||
if account:
|
||||
account_name = account.name
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
vpc = VPC.create(
|
||||
apiclient,
|
||||
self.services["vpc"],
|
||||
domainid=domain_id,
|
||||
accountid=account_name,
|
||||
projectid=project_id,
|
||||
vpcofferingid=self.vpc_offering.id,
|
||||
zoneid=self.zone.id,
|
||||
start=False
|
||||
)
|
||||
return vpc
|
||||
|
||||
def create_vpc_tier_for_account(self, apiclient, vpc, project=None, gateway = '10.1.1.1'):
|
||||
self.services["network"]["name"] = "Test VPC tier - " + random_gen()
|
||||
project_id = None
|
||||
if project:
|
||||
project_id = project.id
|
||||
vpc_tier = Network.create(
|
||||
apiclient,
|
||||
self.services["network"],
|
||||
networkofferingid=self.network_offering_vpc.id,
|
||||
zoneid=self.zone.id,
|
||||
projectid=project_id,
|
||||
gateway=gateway,
|
||||
netmask="255.255.255.0",
|
||||
vpcid=vpc.id
|
||||
)
|
||||
return vpc_tier
|
||||
|
||||
def delete_vpc(self, apiclient, vpc, expected=True):
|
||||
result = True
|
||||
try:
|
||||
vpc.delete(apiclient)
|
||||
except Exception as ex:
|
||||
result = False
|
||||
if expected:
|
||||
self.fail(f"Failed to remove VPC, but expected to succeed : {ex}")
|
||||
if result and not expected:
|
||||
self.fail("VPC is removed successfully, but expected to fail")
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_01_create_user_shared_network_without_vlan(self):
|
||||
""" Create user-shared networks without vlan """
|
||||
self.services["network2"]["networkoffering"] = self.network_offering_novlan.id
|
||||
self.services["network2"]["vlan"] = None
|
||||
|
||||
network1 = self.create_shared_network_for_account(self.apiclient, None, None)
|
||||
network2 = self.create_shared_network_for_account(self.domainapiclient, None, None)
|
||||
network3 = self.create_shared_network_for_account(self.normaluser_apiclient, None, None)
|
||||
|
||||
self.delete_network(network1, self.apiclient)
|
||||
self.delete_network(network2, self.domainapiclient)
|
||||
self.delete_network(network3, self.normaluser_apiclient)
|
||||
|
||||
network4 = self.create_shared_network_for_account(self.domainapiclient, self.sub_domain, self.normal_user, True)
|
||||
self.delete_network(network4, self.normaluser_apiclient)
|
||||
|
||||
network5 = self.create_shared_network_for_account(self.apiclient, self.sub_domain, None, True)
|
||||
self.delete_network(network5, self.apiclient)
|
||||
network6 = self.create_shared_network_for_account(self.domainapiclient, self.sub_domain, None, True)
|
||||
self.delete_network(network6, self.apiclient)
|
||||
self.create_shared_network_for_account(self.normaluser_apiclient, self.sub_domain, None, False)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_02_create_shared_network_with_vlan(self):
|
||||
""" Create shared networks with vlan
|
||||
Only be created/deleted by root admin, Cannot create networks with same vlan
|
||||
"""
|
||||
self.services["network2"]["networkoffering"] = self.network_offering_withvlan.id
|
||||
self.services["network2"]["vlan"] = 4000
|
||||
|
||||
self.create_shared_network_for_account(self.domainapiclient, self.sub_domain, None, False)
|
||||
self.create_shared_network_for_account(self.normaluser_apiclient, self.sub_domain, None, False)
|
||||
network1 = self.create_shared_network_for_account(self.apiclient, self.sub_domain, None, True)
|
||||
self.create_shared_network_for_account(self.apiclient, self.sub_domain, self.normal_user, False)
|
||||
self.delete_network(network1, self.domainapiclient, False)
|
||||
self.delete_network(network1, self.apiclient, True)
|
||||
|
||||
self.create_shared_network_for_account(self.domainapiclient, self.sub_domain, self.normal_user, False)
|
||||
self.create_shared_network_for_account(self.normaluser_apiclient, self.sub_domain, self.normal_user, False)
|
||||
network2 = self.create_shared_network_for_account(self.apiclient, self.sub_domain, self.normal_user, True)
|
||||
self.delete_network(network2, self.domainapiclient, False)
|
||||
self.delete_network(network2, self.normaluser_apiclient, False)
|
||||
self.delete_network(network2, self.apiclient, True)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_03_create_domain_shared_network_with_associated_network(self):
|
||||
""" Create domain-level shared networks with associated network """
|
||||
|
||||
self.services["network2"]["networkoffering"] = self.network_offering_novlan.id
|
||||
self.services["network2"]["vlan"] = None
|
||||
|
||||
# Create isolated networks
|
||||
isolated_network1 = self.create_isolated_network_for_account(self.apiclient, None, None, None, True)
|
||||
isolated_network2 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.domain_admin, None, True)
|
||||
isolated_network3 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.normal_user, None, True)
|
||||
isolated_network4 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, None, self.project, True)
|
||||
|
||||
# Create domain-level shared network with associated_network (caller must be root admin/domain admin, must be in same domain)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.apiclient, self.sub_domain, isolated_network1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, isolated_network1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, isolated_network1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, isolated_network2, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, isolated_network3, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, isolated_network4, False)
|
||||
shared_network1 = self.create_shared_network_with_associated_network_for_domain(self.apiclient, self.domain, isolated_network1, True)
|
||||
shared_network2 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, isolated_network2, True)
|
||||
shared_network3 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, isolated_network3, True)
|
||||
shared_network4 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, isolated_network4, True)
|
||||
|
||||
# Check state of isolated networks (should be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete isolated networks (should fail)
|
||||
self.delete_network(isolated_network1, self.apiclient, False)
|
||||
self.delete_network(isolated_network2, self.apiclient, False)
|
||||
self.delete_network(isolated_network3, self.apiclient, False)
|
||||
self.delete_network(isolated_network4, self.apiclient, False)
|
||||
|
||||
# Create VPC
|
||||
vpc1 = self.create_vpc_for_account(self.apiclient, None, None, None)
|
||||
vpc2 = self.create_vpc_for_account(self.domainapiclient, None, None, None)
|
||||
vpc3 = self.create_vpc_for_account(self.normaluser_apiclient, None, None, None)
|
||||
vpc4 = self.create_vpc_for_account(self.domainapiclient, None, None, self.project)
|
||||
|
||||
# Create VPC tier
|
||||
vpc1_tier1 = self.create_vpc_tier_for_account(self.apiclient, vpc1)
|
||||
vpc2_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc2)
|
||||
vpc3_tier1 = self.create_vpc_tier_for_account(self.normaluser_apiclient, vpc3)
|
||||
vpc4_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc4, self.project)
|
||||
|
||||
# Create domain-level shared network with associated vpc tier (caller must be root admin/domain admin, must be in same domain)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.apiclient, self.sub_domain, vpc1_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, vpc1_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, vpc1_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, vpc2_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, vpc3_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_domain(self.normaluser_apiclient, self.sub_domain, vpc4_tier1, False)
|
||||
shared_network_vpctier1 = self.create_shared_network_with_associated_network_for_domain(self.apiclient, self.domain, vpc1_tier1, True)
|
||||
shared_network_vpctier2 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, vpc2_tier1, True)
|
||||
shared_network_vpctier3 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, vpc3_tier1, True)
|
||||
shared_network_vpctier4 = self.create_shared_network_with_associated_network_for_domain(self.domainapiclient, self.sub_domain, vpc4_tier1, True)
|
||||
|
||||
# Check state of vpc tiers (should be Implemented)
|
||||
self.check_network_state(self.apiclient, vpc1_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc2_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.normaluser_apiclient, vpc3_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc4_tier1, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete vpc tiers(should fail)
|
||||
self.delete_network(vpc1_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc2_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc3_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc4_tier1, self.apiclient, False)
|
||||
|
||||
# Delete shared networks associated to domain admin's isolated network or vpc tier(should succeed)
|
||||
self.delete_network(shared_network2, self.domainapiclient, True)
|
||||
self.delete_network(shared_network_vpctier2, self.domainapiclient, True)
|
||||
|
||||
# Wait for network GC to shut down the isolated networks
|
||||
gc_wait = Configurations.list(self.apiclient, name="network.gc.wait")
|
||||
gc_interval = Configurations.list(self.apiclient, name="network.gc.interval")
|
||||
total_sleep = 360
|
||||
if gc_wait and gc_interval:
|
||||
self.logger.debug("network.gc.wait is ==> %s", gc_wait[0].value)
|
||||
self.logger.debug("network.gc.interval is ==> %s", gc_interval[0].value)
|
||||
total_sleep = max(int(gc_wait[0].value), int(gc_interval[0].value)) * 2 + 60
|
||||
else:
|
||||
self.logger.debug("Could not retrieve the keys 'network.gc.interval' and 'network.gc.wait'. Sleeping for 6 minutes.")
|
||||
time.sleep(total_sleep)
|
||||
|
||||
# Check state of isolated networks (1 should be Allocated, 3 should still be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
self.check_network_state(self.apiclient, vpc1_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc2_tier1, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, vpc3_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc4_tier1, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Check state of shared network (should be Setup)
|
||||
self.check_network_state(self.apiclient, shared_network1, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.normaluser_apiclient, shared_network3, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.domainapiclient, shared_network4, None, NETWORK_STATE_SETUP)
|
||||
|
||||
self.check_network_state(self.apiclient, shared_network_vpctier1, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.normaluser_apiclient, shared_network_vpctier3, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.domainapiclient, shared_network_vpctier4, None, NETWORK_STATE_SETUP)
|
||||
|
||||
# Delete admin's shared networks (should succeed)
|
||||
self.delete_network(shared_network1, self.apiclient, True)
|
||||
self.delete_network(shared_network3, self.domainapiclient, True)
|
||||
self.delete_network(shared_network4, self.domainapiclient, True)
|
||||
|
||||
self.delete_network(shared_network_vpctier1, self.apiclient, True)
|
||||
self.delete_network(shared_network_vpctier3, self.domainapiclient, True)
|
||||
self.delete_network(shared_network_vpctier4, self.domainapiclient, True)
|
||||
|
||||
# Delete admin's and domain admin's isolated network, but keep the normal user's network
|
||||
# normal user's shared network and isolated network should be removed in tearDown successfully
|
||||
self.delete_network(isolated_network1, self.apiclient, True)
|
||||
self.delete_network(isolated_network2, self.domainapiclient, True)
|
||||
|
||||
self.delete_network(vpc1_tier1, self.apiclient, True)
|
||||
self.delete_vpc(self.apiclient, vpc1)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_04_create_account_shared_network_with_associated_network(self):
|
||||
""" Create account-level shared networks with associated network """
|
||||
|
||||
self.services["network2"]["networkoffering"] = self.network_offering_novlan.id
|
||||
self.services["network2"]["vlan"] = None
|
||||
|
||||
# Create isolated networks
|
||||
isolated_network1 = self.create_isolated_network_for_account(self.apiclient, None, None, None, True)
|
||||
isolated_network2 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.domain_admin, None, True)
|
||||
isolated_network3 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, self.normal_user, None, True)
|
||||
isolated_network4 = self.create_isolated_network_for_account(self.apiclient, self.sub_domain, None, self.project, True)
|
||||
|
||||
# Check state of isolated networks (should be Allocated)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_ALLOCATED)
|
||||
|
||||
# Create shared networks with associated network (must be same owner)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, isolated_network1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, isolated_network3, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, isolated_network4, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, isolated_network1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, isolated_network2, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, isolated_network4, False)
|
||||
shared_network1 = self.create_shared_network_with_associated_network_for_caller(self.apiclient, None, isolated_network1, True)
|
||||
shared_network2 = self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, isolated_network2, True)
|
||||
shared_network3 = self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, isolated_network3, True)
|
||||
shared_network4 = self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, self.project, isolated_network4, True)
|
||||
|
||||
# Check state of isolated networks (should be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete isolated networks (should fail)
|
||||
self.delete_network(isolated_network1, self.apiclient, False)
|
||||
self.delete_network(isolated_network2, self.apiclient, False)
|
||||
self.delete_network(isolated_network3, self.apiclient, False)
|
||||
self.delete_network(isolated_network4, self.apiclient, False)
|
||||
|
||||
# Create VPC
|
||||
vpc1 = self.create_vpc_for_account(self.apiclient, None, None, None)
|
||||
vpc2 = self.create_vpc_for_account(self.domainapiclient, None, None, None)
|
||||
vpc3 = self.create_vpc_for_account(self.normaluser_apiclient, None, None, None)
|
||||
vpc4 = self.create_vpc_for_account(self.domainapiclient, None, None, self.project)
|
||||
|
||||
# Create VPC tier
|
||||
vpc1_tier1 = self.create_vpc_tier_for_account(self.apiclient, vpc1)
|
||||
vpc2_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc2)
|
||||
vpc3_tier1 = self.create_vpc_tier_for_account(self.normaluser_apiclient, vpc3)
|
||||
vpc4_tier1 = self.create_vpc_tier_for_account(self.domainapiclient, vpc4, self.project)
|
||||
|
||||
# Create account-level shared network with associated vpc tier (caller must be root admin/domain admin, must be in same domain)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, vpc1_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, vpc3_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, vpc4_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, vpc1_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, vpc2_tier1, False)
|
||||
self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, vpc4_tier1, False)
|
||||
shared_network_vpctier1 = self.create_shared_network_with_associated_network_for_caller(self.apiclient, None, vpc1_tier1, True)
|
||||
shared_network_vpctier2 = self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, None, vpc2_tier1, True)
|
||||
shared_network_vpctier3 = self.create_shared_network_with_associated_network_for_caller(self.normaluser_apiclient, None, vpc3_tier1, True)
|
||||
shared_network_vpctier4 = self.create_shared_network_with_associated_network_for_caller(self.domainapiclient, self.project, vpc4_tier1, True)
|
||||
|
||||
# Check state of vpc tiers (should be Implemented)
|
||||
self.check_network_state(self.apiclient, vpc1_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc2_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.normaluser_apiclient, vpc3_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc4_tier1, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Delete vpc tiers(should fail)
|
||||
self.delete_network(vpc1_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc2_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc3_tier1, self.apiclient, False)
|
||||
self.delete_network(vpc4_tier1, self.apiclient, False)
|
||||
|
||||
# Delete shared networks associated to domain admin's isolated network or vpc tier(should succeed)
|
||||
self.delete_network(shared_network2, self.domainapiclient, True)
|
||||
self.delete_network(shared_network_vpctier2, self.domainapiclient, True)
|
||||
|
||||
# Wait for network GC to shut down the isolated networks
|
||||
gc_wait = Configurations.list(self.apiclient, name="network.gc.wait")
|
||||
gc_interval = Configurations.list(self.apiclient, name="network.gc.interval")
|
||||
total_sleep = 360
|
||||
if gc_wait and gc_interval:
|
||||
self.logger.debug("network.gc.wait is ==> %s", gc_wait[0].value)
|
||||
self.logger.debug("network.gc.interval is ==> %s", gc_interval[0].value)
|
||||
total_sleep = max(int(gc_wait[0].value), int(gc_interval[0].value)) * 2 + 60
|
||||
else:
|
||||
self.logger.debug("Could not retrieve the keys 'network.gc.interval' and 'network.gc.wait'. Sleeping for 6 minutes.")
|
||||
time.sleep(total_sleep)
|
||||
|
||||
# Check state of isolated networks (1 should be Allocated, 3 should still be Implemented)
|
||||
self.check_network_state(self.apiclient, isolated_network1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network2, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, isolated_network3, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, isolated_network4, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
self.check_network_state(self.apiclient, vpc1_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc2_tier1, None, NETWORK_STATE_ALLOCATED)
|
||||
self.check_network_state(self.normaluser_apiclient, vpc3_tier1, None, NETWORK_STATE_IMPLEMENTED)
|
||||
self.check_network_state(self.domainapiclient, vpc4_tier1, self.project, NETWORK_STATE_IMPLEMENTED)
|
||||
|
||||
# Check state of shared network (should be Setup)
|
||||
self.check_network_state(self.apiclient, shared_network1, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.normaluser_apiclient, shared_network3, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.domainapiclient, shared_network4, self.project, NETWORK_STATE_SETUP)
|
||||
|
||||
self.check_network_state(self.apiclient, shared_network_vpctier1, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.normaluser_apiclient, shared_network_vpctier3, None, NETWORK_STATE_SETUP)
|
||||
self.check_network_state(self.domainapiclient, shared_network_vpctier4, self.project, NETWORK_STATE_SETUP)
|
||||
|
||||
# Delete admin's shared networks (should succeed)
|
||||
self.delete_network(shared_network1, self.apiclient, True)
|
||||
self.delete_network(shared_network_vpctier1, self.apiclient, True)
|
||||
|
||||
# Delete admin's and domain admin's isolated network, but keep the normal user's network
|
||||
# normal user's shared network and isolated network should be removed in tearDown successfully
|
||||
self.delete_network(isolated_network1, self.apiclient, True)
|
||||
self.delete_network(isolated_network2, self.domainapiclient, True)
|
||||
|
||||
self.delete_network(vpc1_tier1, self.apiclient, True)
|
||||
self.delete_vpc(self.apiclient, vpc1)
|
||||
self.delete_network(vpc2_tier1, self.domainapiclient, True)
|
||||
self.delete_vpc(self.domainapiclient, vpc2)
|
||||
|
|
@ -3143,7 +3143,7 @@ class Network:
|
|||
networkofferingid=None, projectid=None,
|
||||
subdomainaccess=None, zoneid=None,
|
||||
gateway=None, netmask=None, vpcid=None, aclid=None, vlan=None,
|
||||
externalid=None, bypassvlanoverlapcheck=None):
|
||||
externalid=None, bypassvlanoverlapcheck=None, associatednetworkid=None):
|
||||
"""Create Network for account"""
|
||||
cmd = createNetwork.createNetworkCmd()
|
||||
cmd.name = services["name"]
|
||||
|
|
@ -3211,6 +3211,8 @@ class Network:
|
|||
cmd.externalid = externalid
|
||||
if bypassvlanoverlapcheck:
|
||||
cmd.bypassvlanoverlapcheck = bypassvlanoverlapcheck
|
||||
if associatednetworkid:
|
||||
cmd.associatednetworkid = associatednetworkid
|
||||
return Network(apiclient.createNetwork(cmd).__dict__)
|
||||
|
||||
def delete(self, apiclient):
|
||||
|
|
@ -4731,14 +4733,15 @@ class PrivateGateway:
|
|||
|
||||
@classmethod
|
||||
def create(cls, apiclient, gateway, ipaddress, netmask, vlan, vpcid,
|
||||
physicalnetworkid=None, aclid=None, bypassvlanoverlapcheck=None):
|
||||
physicalnetworkid=None, aclid=None, bypassvlanoverlapcheck=None, associatednetworkid=None):
|
||||
"""Create private gateway"""
|
||||
|
||||
cmd = createPrivateGateway.createPrivateGatewayCmd()
|
||||
cmd.gateway = gateway
|
||||
cmd.ipaddress = ipaddress
|
||||
cmd.netmask = netmask
|
||||
cmd.vlan = vlan
|
||||
if vlan:
|
||||
cmd.vlan = vlan
|
||||
cmd.vpcid = vpcid
|
||||
if physicalnetworkid:
|
||||
cmd.physicalnetworkid = physicalnetworkid
|
||||
|
|
@ -4746,6 +4749,8 @@ class PrivateGateway:
|
|||
cmd.aclid = aclid
|
||||
if bypassvlanoverlapcheck:
|
||||
cmd.bypassvlanoverlapcheck = bypassvlanoverlapcheck
|
||||
if associatednetworkid:
|
||||
cmd.associatednetworkid = associatednetworkid
|
||||
|
||||
return PrivateGateway(apiclient.createPrivateGateway(cmd).__dict__)
|
||||
|
||||
|
|
@ -5301,7 +5306,7 @@ class NIC:
|
|||
"""Remove secondary Ip from NIC"""
|
||||
cmd = removeIpFromNic.removeIpFromNicCmd()
|
||||
cmd.id = ipaddressid
|
||||
return (apiclient.addIpToNic(cmd))
|
||||
return (apiclient.removeIpFromNic(cmd))
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
|
|
@ -5313,6 +5318,14 @@ class NIC:
|
|||
cmd.listall = True
|
||||
return (apiclient.listNics(cmd))
|
||||
|
||||
@classmethod
|
||||
def updateIp(cls, apiclient, id, ipaddress=None):
|
||||
"""Update Ip for NIC"""
|
||||
cmd = updateVmNicIp.updateVmNicIpCmd()
|
||||
cmd.nicid = id
|
||||
if ipaddress:
|
||||
cmd.ipaddress = ipaddress
|
||||
return (apiclient.updateVmNicIp(cmd))
|
||||
|
||||
class SimulatorMock:
|
||||
"""Manage simulator mock lifecycle"""
|
||||
|
|
@ -5656,3 +5669,40 @@ class ProjectRolePermission:
|
|||
cmd.projectid = projectid
|
||||
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
|
||||
return (apiclient.listProjectRolePermissions(cmd))
|
||||
|
||||
class NetworkPermission:
|
||||
"""Manage Network Permission"""
|
||||
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, **kwargs):
|
||||
"""Creates network permissions"""
|
||||
cmd = createNetworkPermissions.createNetworkPermissionsCmd()
|
||||
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
|
||||
return (apiclient.createNetworkPermissions(cmd))
|
||||
|
||||
@classmethod
|
||||
def remove(cls, apiclient, **kwargs):
|
||||
"""Removes the network permissions"""
|
||||
|
||||
cmd = removeNetworkPermissions.removeNetworkPermissionsCmd()
|
||||
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
|
||||
return (apiclient.removeNetworkPermissions(cmd))
|
||||
|
||||
@classmethod
|
||||
def reset(cls, apiclient, **kwargs):
|
||||
"""Updates the network permissions"""
|
||||
|
||||
cmd = resetNetworkPermissions.resetNetworkPermissionsCmd()
|
||||
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
|
||||
return (apiclient.resetNetworkPermissions(cmd))
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
"""List all role permissions matching criteria"""
|
||||
|
||||
cmd = listNetworkPermissions.listNetworkPermissionsCmd()
|
||||
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
|
||||
return (apiclient.listNetworkPermissions(cmd))
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@
|
|||
"label.action.delete.load.balancer": "Delete load balancer rule",
|
||||
"label.action.delete.load.balancer.processing": "Deleting Load Balancer....",
|
||||
"label.action.delete.network": "Delete Network",
|
||||
"label.action.delete.network.permission": "Delete Network Permission",
|
||||
"label.action.delete.network.processing": "Deleting Network....",
|
||||
"label.action.delete.nexusvswitch": "Delete Nexus 1000v",
|
||||
"label.action.delete.nic": "Remove NIC",
|
||||
|
|
@ -250,6 +251,7 @@
|
|||
"label.action.remove.host.processing": "Removing Host....",
|
||||
"label.action.remove.vm": "Release VM",
|
||||
"label.action.reserve.ip": "Reserve Public IP",
|
||||
"label.action.reset.network.permissions": "Reset Network Permissions",
|
||||
"label.action.reset.password": "Reset Password",
|
||||
"label.action.reset.password.processing": "Resetting Password....",
|
||||
"label.action.resize.volume": "Resize Volume",
|
||||
|
|
@ -344,6 +346,7 @@
|
|||
"label.add.network.acl.list": "Add Network ACL List",
|
||||
"label.add.network.device": "Add Network Device",
|
||||
"label.add.network.offering": "Add Network Offering",
|
||||
"label.add.network.permission": "Add Network Permission",
|
||||
"label.add.new.f5": "Add new F5",
|
||||
"label.add.new.gateway": "Add new gateway",
|
||||
"label.add.new.iso": "Add new ISO",
|
||||
|
|
@ -439,6 +442,7 @@
|
|||
"label.all": "All",
|
||||
"label.all.zone": "All Zones",
|
||||
"label.allocated": "Allocated",
|
||||
"label.allocatedonly": "Allocated",
|
||||
"label.allocatediops": "IOPS Allocated",
|
||||
"label.allocationstate": "Allocation State",
|
||||
"label.allow": "Allow",
|
||||
|
|
@ -1045,6 +1049,7 @@
|
|||
"label.guestnetworkname": "Network Name",
|
||||
"label.guestosid": "OS Type",
|
||||
"label.gueststartip": "Guest start IP",
|
||||
"label.guest.vlan": "Guest VLAN",
|
||||
"label.guestvlanrange": "VLAN Range(s)",
|
||||
"label.guestvmcidr": "CIDR",
|
||||
"label.ha": "HA",
|
||||
|
|
@ -1516,6 +1521,7 @@
|
|||
"label.network.offering.display.text": "Network Offering Display Text",
|
||||
"label.network.offering.name": "Network Offering Name",
|
||||
"label.network.offerings": "Network Offerings",
|
||||
"label.network.permissions": "Network Permissions",
|
||||
"label.network.selection": "Network Selection",
|
||||
"label.network.service.providers": "Network Service Providers",
|
||||
"label.networkcidr": "Network CIDR",
|
||||
|
|
@ -1665,6 +1671,7 @@
|
|||
"label.physical.network.id": "Physical network ID",
|
||||
"label.physical.network.name": "Physical network name",
|
||||
"label.physicalnetworkid": "Physical Network",
|
||||
"label.physicalnetworkname": "Physical Network Name",
|
||||
"label.physicalsize": "Physical Size",
|
||||
"label.ping.cifs.password": "PING CIFS password",
|
||||
"label.ping.cifs.username": "PING CIFS username",
|
||||
|
|
@ -2192,6 +2199,7 @@
|
|||
"label.tag.value": "Tag Value",
|
||||
"label.tagged": "Tagged",
|
||||
"label.tags": "Tags",
|
||||
"label.taken": "Taken",
|
||||
"label.target.iqn": "Target IQN",
|
||||
"label.tariffactions": "Actions",
|
||||
"label.tariffvalue": "Tariff Value",
|
||||
|
|
@ -2773,11 +2781,13 @@
|
|||
"message.confirm.remove.ip.range": "Please confirm that you would like to remove this IP range.",
|
||||
"message.confirm.remove.load.balancer": "Please confirm you want to remove VM from load balancer",
|
||||
"message.confirm.remove.network.offering": "Are you sure you want to remove this network offering?",
|
||||
"message.confirm.remove.network.permission": "Are you sure you want to remove this network permission?",
|
||||
"message.confirm.remove.selected.alerts": "Please confirm you would like to remove the selected alerts",
|
||||
"message.confirm.remove.selected.events": "Please confirm you would like to remove the selected events",
|
||||
"message.confirm.remove.vmware.datacenter": "Please confirm you want to remove VMware datacenter",
|
||||
"message.confirm.remove.vpc.offering": "Are you sure you want to remove this VPC offering?",
|
||||
"message.confirm.replace.acl.new.one": "Do you want to replace the ACL with a new one?",
|
||||
"message.confirm.reset.network.permissions": "Are you sure you want to reset this network permissions?",
|
||||
"message.confirm.scale.up.router.vm": "Do you really want to scale up the Router VM ?",
|
||||
"message.confirm.scale.up.system.vm": "Do you really want to scale up the system VM ?",
|
||||
"message.confirm.shutdown.provider": "Please confirm that you would like to shutdown this provider",
|
||||
|
|
@ -3288,6 +3298,7 @@
|
|||
"message.setup.physical.network.during.zone.creation": "When adding a zone, you need to set up one or more physical networks. Each network corresponds to a NIC on the hypervisor. Each physical network can carry one or more types of traffic, with certain restrictions on how they may be combined. Add or remove one or more traffic types onto each physical network.",
|
||||
"message.setup.physical.network.during.zone.creation.basic": "When adding a basic zone, you can set up one physical network, which corresponds to a NIC on the hypervisor. The network carries several types of traffic.<br/><br/>You may also <strong>add</strong> other traffic types onto the physical network.",
|
||||
"message.setup.successful": "Cloud setup successful!",
|
||||
"message.shared.network.offering.warning": "Domain admins and regular users can only create Shared networks from network offering with specifyvlan=false. Please contact admin to create a network offering if this list is empty.",
|
||||
"message.specify.tag.key": "Please specify a tag key",
|
||||
"message.specify.tag.key.value": "Please specify a tag key and value",
|
||||
"message.specify.tag.value": "Please specify a tag value",
|
||||
|
|
@ -3307,6 +3318,7 @@
|
|||
"message.success.add.kuberversion": "Successfully added Kubernetes version",
|
||||
"message.success.add.network": "Successfully added network",
|
||||
"message.success.add.network.acl": "Successfully added Network ACL List",
|
||||
"message.success.add.network.permissions": "Successfully added Network Permissions",
|
||||
"message.success.add.port.forward": "Successfully added new Port Forwarding rule",
|
||||
"message.success.add.private.gateway": "Successfully added Private Gateway",
|
||||
"message.success.add.rule": "Successfully added new rule",
|
||||
|
|
@ -3362,11 +3374,13 @@
|
|||
"message.success.remove.instance.rule": "Successfully removed instance from rule",
|
||||
"message.success.remove.ip": "Successfully removed IP",
|
||||
"message.success.remove.iprange": "Successfully removed IP Range",
|
||||
"message.success.remove.network.permissions": "Successfully removed Network Permissions",
|
||||
"message.success.remove.nic": "Successfully removed",
|
||||
"message.success.remove.port.forward": "Successfully removed Port Forwarding rule",
|
||||
"message.success.remove.rule": "Successfully deleted rule",
|
||||
"message.success.remove.secondary.ipaddress": "Successfully removed secondary IP Address",
|
||||
"message.success.remove.sticky.policy": "Successfully removed sticky policy",
|
||||
"message.success.reset.network.permissions": "Successfully reset Network Permissions",
|
||||
"message.success.resize.volume": "Successfully resized volume",
|
||||
"message.success.scale.kubernetes": "Successfully scaled Kubernetes cluster",
|
||||
"message.success.unmanage.instance": "Successfully unmanaged instance",
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@
|
|||
<div class="resource-detail-item__label">{{ $t('label.associatednetwork') }}</div>
|
||||
<div class="resource-detail-item__details">
|
||||
<wifi-outlined />
|
||||
<router-link :to="{ path: '/guestnetwork/' + resource.associatednetworkid }">{{ resource.associatednetworkname || resource.associatednetworkid }} </router-link>
|
||||
<router-link :to="{ path: '/guestnetwork/' + resource.associatednetworkid }">{{ resource.associatednetworkname || resource.associatednetwork || resource.associatednetworkid }} </router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-detail-item" v-if="resource.sourceipaddressnetworkid">
|
||||
|
|
|
|||
|
|
@ -195,6 +195,11 @@
|
|||
<template #agentstate="{ text }">
|
||||
<status :text="text ? text : ''" displayText />
|
||||
</template>
|
||||
<template #vlan="{ text, record }">
|
||||
<a href="javascript:;">
|
||||
<router-link v-if="$route.path === '/guestvlans'" :to="{ path: '/guestvlans/' + record.id }">{{ text }}</router-link>
|
||||
</a>
|
||||
</template>
|
||||
<template #guestnetworkname="{ text, record }">
|
||||
<router-link :to="{ path: '/guestnetwork/' + record.guestnetworkid }">{{ text }}</router-link>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ export default {
|
|||
if (item === 'clusterid' && !('listClusters' in this.$store.getters.apis)) {
|
||||
return true
|
||||
}
|
||||
if (['zoneid', 'domainid', 'state', 'level', 'clusterid', 'podid', 'entitytype'].includes(item)) {
|
||||
if (['zoneid', 'domainid', 'state', 'level', 'clusterid', 'podid', 'entitytype', 'type'].includes(item)) {
|
||||
type = 'list'
|
||||
} else if (item === 'tags') {
|
||||
type = 'tag'
|
||||
|
|
@ -271,6 +271,15 @@ export default {
|
|||
let podIndex = -1
|
||||
let clusterIndex = -1
|
||||
|
||||
if (arrayField.includes('type')) {
|
||||
if (this.$route.path === '/guestnetwork' || this.$route.path.includes('/guestnetwork/')) {
|
||||
const typeIndex = this.fields.findIndex(item => item.name === 'type')
|
||||
this.fields[typeIndex].loading = true
|
||||
this.fields[typeIndex].opts = this.fetchGuestNetworkTypes()
|
||||
this.fields[typeIndex].loading = false
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayField.includes('state')) {
|
||||
const stateIndex = this.fields.findIndex(item => item.name === 'state')
|
||||
this.fields[stateIndex].loading = true
|
||||
|
|
@ -431,6 +440,24 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
fetchGuestNetworkTypes () {
|
||||
const types = []
|
||||
if (this.apiName.indexOf('listNetworks') > -1) {
|
||||
types.push({
|
||||
id: 'Isolated',
|
||||
name: 'label.isolated'
|
||||
})
|
||||
types.push({
|
||||
id: 'Shared',
|
||||
name: 'label.shared'
|
||||
})
|
||||
types.push({
|
||||
id: 'L2',
|
||||
name: 'label.l2'
|
||||
})
|
||||
}
|
||||
return types
|
||||
},
|
||||
fetchState () {
|
||||
const state = []
|
||||
if (this.apiName.indexOf('listVolumes') > -1) {
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ export default {
|
|||
return fields
|
||||
},
|
||||
details: () => {
|
||||
var fields = ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'aclname', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'egressdefaultpolicy', 'zonename', 'account', 'domain']
|
||||
var fields = ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'aclname', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'egressdefaultpolicy', 'zonename', 'account', 'domain', 'associatednetwork', 'associatednetworkid']
|
||||
if (!isAdmin()) {
|
||||
fields = fields.filter(function (e) { return e !== 'broadcasturi' })
|
||||
}
|
||||
return fields
|
||||
},
|
||||
filters: ['all', 'isolated', 'shared', 'l2'],
|
||||
searchFilters: ['keyword', 'zoneid', 'domainid', 'account', 'tags'],
|
||||
filters: ['all', 'account', 'domain', 'shared'],
|
||||
searchFilters: ['keyword', 'zoneid', 'domainid', 'account', 'type', 'tags'],
|
||||
related: [{
|
||||
name: 'vm',
|
||||
title: 'label.instances',
|
||||
|
|
@ -71,6 +71,10 @@ export default {
|
|||
name: 'guest.ip.range',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/GuestIpRanges.vue'))),
|
||||
show: (record) => { return 'listVlanIpRanges' in store.getters.apis && (record.type === 'Shared' || (record.service && record.service.filter(x => x.name === 'SourceNat').count === 0)) }
|
||||
}, {
|
||||
name: 'network.permissions',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/NetworkPermissions.vue'))),
|
||||
show: (record, route, user) => { return 'listNetworkPermissions' in store.getters.apis && record.acltype === 'Account' && !('vpcid' in record) && (['Admin', 'DomainAdmin'].includes(user.roletype) || record.account === user.account) }
|
||||
},
|
||||
{
|
||||
name: 'comments',
|
||||
|
|
@ -372,7 +376,7 @@ export default {
|
|||
hidden: true,
|
||||
permission: ['listPrivateGateways'],
|
||||
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account'],
|
||||
details: ['ipaddress', 'gateway', 'netmask', 'vlan', 'sourcenatsupported', 'aclname', 'account', 'domain', 'zone'],
|
||||
details: ['ipaddress', 'gateway', 'netmask', 'vlan', 'sourcenatsupported', 'aclname', 'account', 'domain', 'zone', 'associatednetwork', 'associatednetworkid'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
||||
|
|
@ -707,6 +711,31 @@ export default {
|
|||
groupMap: (selection) => { return selection.map(x => { return { id: x } }) }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'guestvlans',
|
||||
title: 'label.guest.vlan',
|
||||
icon: 'folder-outlined',
|
||||
permission: ['listGuestVlans'],
|
||||
resourceType: 'GuestVlan',
|
||||
filters: ['allocatedonly', 'all'],
|
||||
columns: ['vlan', 'zonename', 'physicalnetworkname', 'allocationstate', 'taken', 'domain', 'account', 'project'],
|
||||
details: ['vlan', 'zonename', 'physicalnetworkname', 'allocationstate', 'taken', 'domain', 'account', 'project', 'isdedicated'],
|
||||
searchFilters: ['zoneid'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/components/view/DetailsTab.vue')))
|
||||
}, {
|
||||
name: 'guest.networks',
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/GuestVlanNetworksTab.vue'))),
|
||||
show: (record) => { return (record.allocationstate === 'Allocated') }
|
||||
}],
|
||||
show: () => {
|
||||
if (!store.getters.zones || store.getters.zones.length === 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
:value="$route.query.filter || (projectView && $route.name === 'vm' ||
|
||||
['Admin', 'DomainAdmin'].includes($store.getters.userInfo.roletype) && ['vm', 'iso', 'template'].includes($route.name)
|
||||
? 'all' : ['publicip'].includes($route.name)
|
||||
? 'allocated': ['guestnetwork'].includes($route.name) ? 'all' : 'self')"
|
||||
? 'allocated' : ['guestnetwork', 'guestvlans'].includes($route.name) ? 'all' : 'self')"
|
||||
style="min-width: 100px; margin-left: 10px"
|
||||
@change="changeFilter"
|
||||
showSearch
|
||||
|
|
@ -1497,9 +1497,9 @@ export default {
|
|||
query.isofilter = filter
|
||||
} else if (this.$route.name === 'guestnetwork') {
|
||||
if (filter === 'all') {
|
||||
delete query.type
|
||||
delete query.networkfilter
|
||||
} else {
|
||||
query.type = filter
|
||||
query.networkfilter = filter
|
||||
}
|
||||
} else if (this.$route.name === 'publicip') {
|
||||
query.state = filter
|
||||
|
|
@ -1512,6 +1512,12 @@ export default {
|
|||
}
|
||||
} else if (this.$route.name === 'comment') {
|
||||
query.annotationfilter = filter
|
||||
} else if (this.$route.name === 'guestvlans') {
|
||||
if (filter === 'all') {
|
||||
query.allocatedonly = 'false'
|
||||
} else if (filter === 'allocatedonly') {
|
||||
query.allocatedonly = 'true'
|
||||
}
|
||||
}
|
||||
query.filter = filter
|
||||
query.page = '1'
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
@refresh-data="refreshParent"
|
||||
@refresh="handleRefresh"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane :tab="$t('label.shared')" key="3" v-if="isAdmin()">
|
||||
<a-tab-pane :tab="$t('label.shared')" key="3">
|
||||
<CreateSharedNetworkForm
|
||||
:loading="loading"
|
||||
:resource="resource"
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import { isAdmin } from '@/role'
|
||||
import CreateIsolatedNetworkForm from '@/views/network/CreateIsolatedNetworkForm'
|
||||
import CreateL2NetworkForm from '@/views/network/CreateL2NetworkForm'
|
||||
import CreateSharedNetworkForm from '@/views/network/CreateSharedNetworkForm'
|
||||
|
|
@ -108,9 +107,6 @@ export default {
|
|||
this.loading = false
|
||||
})
|
||||
},
|
||||
isAdmin () {
|
||||
return isAdmin()
|
||||
},
|
||||
handleRefresh () {
|
||||
},
|
||||
refreshParent () {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,247 @@
|
|||
// 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.
|
||||
|
||||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<div class="form-layout" v-ctrl-enter="handleSubmit">
|
||||
<div class="form">
|
||||
<a-form
|
||||
:ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
@finish="handleSubmit"
|
||||
layout="vertical">
|
||||
<a-form-item v-if="isAdminOrDomainAdmin()" name="accountids" ref="accountids">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.account')" :tooltip="apiParams.accountids.description"/>
|
||||
</template>
|
||||
<a-select
|
||||
v-model:value="form.accountids"
|
||||
mode="multiple"
|
||||
:loading="accountLoading"
|
||||
:placeholder="apiParams.accountids.description"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt, optIndex) in accounts" :key="optIndex" :label="opt.name || opt.description">
|
||||
<span>
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<global-outlined style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isAdminOrDomainAdmin()" name="projectids" ref="projectids">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.project')" :tooltip="apiParams.projectids.description"/>
|
||||
</template>
|
||||
<a-select
|
||||
v-model:value="form.projectids"
|
||||
mode="multiple"
|
||||
:loading="projectLoading"
|
||||
:placeholder="apiParams.projectids.description"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt, optIndex) in projects" :key="optIndex" :label="opt.name || opt.description">
|
||||
<span>
|
||||
<resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<global-outlined style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="!isAdminOrDomainAdmin()">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.accounts')" :tooltip="apiParams.accounts.description"/>
|
||||
</template>
|
||||
<a-input
|
||||
v-model:value="form.accounts"
|
||||
:placeholder="apiParams.accounts.description"
|
||||
v-focus="true" />
|
||||
</a-form-item>
|
||||
<div :span="24" class="action-button">
|
||||
<a-button
|
||||
:loading="loading"
|
||||
@click="closeAction">
|
||||
{{ this.$t('label.cancel') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
:loading="loading"
|
||||
type="primary"
|
||||
ref="submit"
|
||||
@click="handleSubmit">
|
||||
{{ this.$t('label.ok') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import { isAdminOrDomainAdmin } from '@/role'
|
||||
import { ref, reactive, toRaw } from 'vue'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
||||
export default {
|
||||
name: 'CreateNetworkPermissions',
|
||||
components: {
|
||||
TooltipLabel,
|
||||
ResourceIcon
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
accountLoading: false,
|
||||
projectLoading: false,
|
||||
accounts: [],
|
||||
projects: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.formRef = ref()
|
||||
this.form = reactive({})
|
||||
this.apiParams = this.$getApiParams('createNetworkPermissions')
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
isAdminOrDomainAdmin () {
|
||||
return isAdminOrDomainAdmin()
|
||||
},
|
||||
async fetchData () {
|
||||
this.fetchAccountData()
|
||||
this.fetchProjectData()
|
||||
},
|
||||
fetchAccountData () {
|
||||
this.accounts = []
|
||||
const params = {}
|
||||
params.showicon = true
|
||||
params.details = 'min'
|
||||
params.domainid = this.resource.domainid
|
||||
this.accountLoading = true
|
||||
api('listAccounts', params).then(json => {
|
||||
const listaccounts = json.listaccountsresponse.account || []
|
||||
this.accounts = listaccounts
|
||||
}).finally(() => {
|
||||
this.accountLoading = false
|
||||
})
|
||||
},
|
||||
fetchProjectData () {
|
||||
this.projects = []
|
||||
const params = {}
|
||||
params.listall = true
|
||||
params.showicon = true
|
||||
params.details = 'min'
|
||||
params.domainid = this.resource.domainid
|
||||
this.projectLoading = true
|
||||
api('listProjects', params).then(json => {
|
||||
const listProjects = json.listprojectsresponse.project || []
|
||||
this.projects = listProjects
|
||||
}).finally(() => {
|
||||
this.projectLoading = false
|
||||
})
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
if (this.loading) return
|
||||
this.formRef.value.validate().then(() => {
|
||||
const values = toRaw(this.form)
|
||||
const params = {}
|
||||
params.networkid = this.resource.id
|
||||
var accountIndexes = values.accountids
|
||||
var accountId = null
|
||||
if (accountIndexes && accountIndexes.length > 0) {
|
||||
var accountIds = []
|
||||
for (var i = 0; i < accountIndexes.length; i++) {
|
||||
accountIds = accountIds.concat(this.accounts[accountIndexes[i]].id)
|
||||
}
|
||||
accountId = accountIds.join(',')
|
||||
}
|
||||
if (accountId) {
|
||||
params.accountids = accountId
|
||||
}
|
||||
var projectIndexes = values.projectids
|
||||
var projectId = null
|
||||
if (projectIndexes && projectIndexes.length > 0) {
|
||||
var projectIds = []
|
||||
for (var j = 0; j < projectIndexes.length; j++) {
|
||||
projectIds = projectIds.concat(this.projects[projectIndexes[j]].id)
|
||||
}
|
||||
projectId = projectIds.join(',')
|
||||
}
|
||||
if (projectId) {
|
||||
params.projectids = projectId
|
||||
}
|
||||
|
||||
if (values.accounts && values.accounts.length > 0) {
|
||||
params.accounts = values.accounts
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
|
||||
api('createNetworkPermissions', params)
|
||||
.then(() => {
|
||||
this.$notification.success({
|
||||
message: this.$t('message.success.add.network.permissions')
|
||||
})
|
||||
this.closeAction()
|
||||
this.$emit('refresh-data')
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: `${this.$t('label.error')} ${error.response.status}`,
|
||||
description: error.response.data.createnetworkpermissionsresponse.errortext || error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}).catch(error => {
|
||||
this.formRef.value.scrollToField(error.errorFields[0].name)
|
||||
})
|
||||
},
|
||||
closeAction () {
|
||||
this.$emit('close-action')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.form-layout {
|
||||
width: 60vw;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
width: 450px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isObjectEmpty(zone)" name="physicalnetworkid" ref="physicalnetworkid">
|
||||
<a-form-item v-if="isObjectEmpty(zone) && isAdmin()" name="physicalnetworkid" ref="physicalnetworkid">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.physicalnetworkid')" :tooltip="apiParams.physicalnetworkid.description"/>
|
||||
</template>
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
:loading="formPhysicalNetworkLoading"
|
||||
:placeholder="apiParams.physicalnetworkid.description"
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item name="vlanid" ref="vlanid">
|
||||
<a-form-item v-if="!this.isObjectEmpty(this.selectedNetworkOffering) && this.selectedNetworkOffering.specifyvlan && isAdmin()" name="vlanid" ref="vlanid">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.vlan')" :tooltip="apiParams.vlan.description"/>
|
||||
</template>
|
||||
|
|
@ -93,14 +93,14 @@
|
|||
v-model:value="form.vlanid"
|
||||
:placeholder="apiParams.vlan.description"/>
|
||||
</a-form-item>
|
||||
<a-form-item name="bypassvlanoverlapcheck" ref="bypassvlanoverlapcheck">
|
||||
<a-form-item name="bypassvlanoverlapcheck" ref="bypassvlanoverlapcheck" v-if="isAdmin()">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.bypassvlanoverlapcheck')" :tooltip="apiParams.bypassvlanoverlapcheck.description"/>
|
||||
</template>
|
||||
<a-switch v-model:checked="form.bypassvlanoverlapcheck" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="!isObjectEmpty(selectedNetworkOffering) && selectedNetworkOffering.specifyvlan"
|
||||
v-if="!isObjectEmpty(selectedNetworkOffering) && selectedNetworkOffering.specifyvlan && isAdmin()"
|
||||
name="isolatedpvlantype"
|
||||
ref="isolatedpvlantype">
|
||||
<template #label>
|
||||
|
|
@ -136,10 +136,10 @@
|
|||
v-model:value="form.scope"
|
||||
buttonStyle="solid"
|
||||
@change="selected => { handleScopeTypeChange(selected.target.value) }">
|
||||
<a-radio-button value="all">
|
||||
<a-radio-button value="all" v-if="isAdmin()">
|
||||
{{ $t('label.all') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="domain" v-if="!parseBooleanValueForKey(selectedZone, 'securitygroupsenabled')">
|
||||
<a-radio-button value="domain" v-if="!parseBooleanValueForKey(selectedZone, 'securitygroupsenabled') && isAdminOrDomainAdmin()">
|
||||
{{ $t('label.domain') }}
|
||||
</a-radio-button>
|
||||
<a-radio-button value="account" v-if="!parseBooleanValueForKey(selectedZone, 'securitygroupsenabled')">
|
||||
|
|
@ -150,7 +150,7 @@
|
|||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="scopeType !== 'all'" name="domainid" ref="domainid">
|
||||
<a-form-item v-if="scopeType !== 'all' && isAdminOrDomainAdmin()" name="domainid" ref="domainid">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.domainid')" :tooltip="apiParams.domainid.description"/>
|
||||
</template>
|
||||
|
|
@ -164,32 +164,47 @@
|
|||
:loading="domainLoading"
|
||||
:placeholder="apiParams.domainid.description"
|
||||
@change="val => { handleDomainChange(domains[val]) }">
|
||||
<a-select-option v-for="(opt, optIndex) in domains" :key="optIndex" :label="opt.path || opt.name || opt.description">
|
||||
<a-select-option v-for="(opt, optIndex) in domains" :key="optIndex">
|
||||
<span>
|
||||
<resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<block-outlined v-else-if="optIndex !== 0" style="margin-right: 5px" />
|
||||
<block-outlined v-else style="margin-right: 5px" />
|
||||
{{ opt.path || opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="scopeType === 'domain'" name="subdomainaccess" ref="subdomainaccess">
|
||||
<a-form-item v-if="scopeType === 'domain' && isAdminOrDomainAdmin()" name="subdomainaccess" ref="subdomainaccess">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.subdomainaccess')" :tooltip="apiParams.subdomainaccess.description"/>
|
||||
</template>
|
||||
<a-switch v-model:checked="form.subdomainaccess" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="scopeType === 'account'" name="account" ref="account">
|
||||
<a-form-item v-if="scopeType === 'account' && isAdminOrDomainAdmin()" name="account" ref="account">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.account')" :tooltip="apiParams.account.description"/>
|
||||
</template>
|
||||
<a-input
|
||||
<a-select
|
||||
v-model:value="form.account"
|
||||
:placeholder="apiParams.account.description"/>
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
:loading="accountLoading"
|
||||
:placeholder="apiParams.account.description"
|
||||
@change="val => { handleAccountChange(accounts[val]) }">
|
||||
<a-select-option v-for="(opt, optIndex) in accounts" :key="optIndex">
|
||||
<span>
|
||||
<resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<user-outlined v-else style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="scopeType === 'project'" name="projectid" ref="projectid">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.projectid')" :tooltip="apiParams.projectid.description"/>
|
||||
<tooltip-label :title="$t('label.project')" :tooltip="apiParams.projectid.description"/>
|
||||
</template>
|
||||
<a-select
|
||||
v-model:value="form.projectid"
|
||||
|
|
@ -201,12 +216,8 @@
|
|||
:loading="projectLoading"
|
||||
:placeholder="apiParams.projectid.description"
|
||||
@change="val => { handleProjectChange(projects[val]) }">
|
||||
<a-select-option v-for="(opt, optIndex) in projects" :key="optIndex" :label="opt.name || opt.description">
|
||||
<span>
|
||||
<resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<project-outlined v-else-if="optIndex !== 0" style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
<a-select-option v-for="(opt, optIndex) in projects" :key="optIndex">
|
||||
{{ opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
|
@ -219,7 +230,7 @@
|
|||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
:loading="networkOfferingLoading"
|
||||
:placeholder="apiParams.networkofferingid.description"
|
||||
|
|
@ -228,6 +239,31 @@
|
|||
{{ opt.displaytext || opt.name || opt.description }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-alert type="warning" :loading="networkOfferingLoading" v-if="networkOfferingWarning">
|
||||
<template #message>{{ $t('message.shared.network.offering.warning') }}</template>
|
||||
</a-alert>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="!isObjectEmpty(selectedNetworkOffering) && !selectedNetworkOffering.specifyvlan" name="associatednetworkid" ref="associatednetworkid">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.associatednetwork')" :tooltip="apiParams.associatednetworkid.description"/>
|
||||
</template>
|
||||
<a-select
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}"
|
||||
:loading="networkLoading"
|
||||
:placeholder="this.$t('label.associatednetwork')"
|
||||
@change="val => { this.handleNetworkChange(this.networks[val]) }">
|
||||
<a-select-option v-for="(opt, optIndex) in this.networks" :key="optIndex" :label="opt.name || opt.description">
|
||||
<span>
|
||||
<resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<apartment-outlined v-else style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item name="ip4gateway" ref="ip4gateway">
|
||||
<template #label>
|
||||
|
|
@ -338,6 +374,7 @@
|
|||
<script>
|
||||
import { ref, reactive, toRaw } from 'vue'
|
||||
import { api } from '@/api'
|
||||
import { isAdmin, isAdminOrDomainAdmin } from '@/role'
|
||||
import { mixinForm } from '@/utils/mixin'
|
||||
import ResourceIcon from '@/components/view/ResourceIcon'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
|
|
@ -358,10 +395,6 @@ export default {
|
|||
type: Object,
|
||||
default: null
|
||||
},
|
||||
physicalNetworks: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
resource: {
|
||||
type: Object,
|
||||
default: () => { return {} }
|
||||
|
|
@ -382,7 +415,14 @@ export default {
|
|||
selectedDomain: {},
|
||||
networkOfferings: [],
|
||||
networkOfferingLoading: false,
|
||||
networkOfferingWarning: false,
|
||||
selectedNetworkOffering: {},
|
||||
networks: [],
|
||||
networkLoading: false,
|
||||
selectedNetwork: {},
|
||||
accounts: [],
|
||||
accountLoading: false,
|
||||
selectedAccount: {},
|
||||
projects: [],
|
||||
projectLoading: false,
|
||||
selectedProject: {},
|
||||
|
|
@ -408,8 +448,15 @@ export default {
|
|||
methods: {
|
||||
initForm () {
|
||||
this.formRef = ref()
|
||||
if (isAdmin()) {
|
||||
this.scopeType = 'all'
|
||||
} else if (isAdminOrDomainAdmin()) {
|
||||
this.scopeType = 'domain'
|
||||
} else {
|
||||
this.scopeType = 'account'
|
||||
}
|
||||
this.form = reactive({
|
||||
scope: 'all',
|
||||
scope: this.scopeType,
|
||||
isolatedpvlantype: 'none'
|
||||
})
|
||||
this.rules = reactive({
|
||||
|
|
@ -418,8 +465,9 @@ export default {
|
|||
zoneid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
|
||||
vlanid: [{ required: true, message: this.$t('message.please.enter.value') }],
|
||||
networkofferingid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
|
||||
domainid: [{ required: true, message: this.$t('message.error.select') }],
|
||||
projectid: [{ required: true, message: this.$t('message.error.select') }]
|
||||
domainid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
|
||||
account: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
|
||||
projectid: [{ type: 'number', required: true, message: this.$t('message.error.select') }]
|
||||
})
|
||||
},
|
||||
fetchData () {
|
||||
|
|
@ -428,6 +476,15 @@ export default {
|
|||
} else {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
if (this.scopeType !== 'all') {
|
||||
this.handleScopeTypeChange(this.scopeType)
|
||||
}
|
||||
},
|
||||
isAdmin () {
|
||||
return isAdmin()
|
||||
},
|
||||
isAdminOrDomainAdmin () {
|
||||
return isAdminOrDomainAdmin()
|
||||
},
|
||||
isObjectEmpty (obj) {
|
||||
return !(obj !== null && obj !== undefined && Object.keys(obj).length > 0 && obj.constructor === Object)
|
||||
|
|
@ -478,43 +535,42 @@ export default {
|
|||
},
|
||||
handleZoneChange (zone) {
|
||||
this.selectedZone = zone
|
||||
this.fetchPhysicalNetworkData()
|
||||
if (isAdmin()) {
|
||||
this.fetchPhysicalNetworkData()
|
||||
} else {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
},
|
||||
fetchPhysicalNetworkData () {
|
||||
this.formSelectedPhysicalNetwork = {}
|
||||
this.formPhysicalNetworks = []
|
||||
if (this.physicalNetworks != null) {
|
||||
this.formPhysicalNetworks = this.physicalNetworks
|
||||
this.selectFirstPhysicalNetwork()
|
||||
} else {
|
||||
if (this.selectedZone === null || this.selectedZone === undefined) {
|
||||
return
|
||||
}
|
||||
const promises = []
|
||||
const params = {
|
||||
zoneid: this.selectedZone.id
|
||||
}
|
||||
this.formPhysicalNetworkLoading = true
|
||||
api('listPhysicalNetworks', params).then(json => {
|
||||
var networks = json.listphysicalnetworksresponse.physicalnetwork
|
||||
if (this.arrayHasItems(networks)) {
|
||||
for (const network of networks) {
|
||||
promises.push(this.addPhysicalNetworkForGuestTrafficType(network))
|
||||
}
|
||||
} else {
|
||||
this.formPhysicalNetworkLoading = false
|
||||
}
|
||||
}).finally(() => {
|
||||
if (this.arrayHasItems(promises)) {
|
||||
Promise.all(promises).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.formPhysicalNetworkLoading = false
|
||||
this.selectFirstPhysicalNetwork()
|
||||
})
|
||||
}
|
||||
})
|
||||
if (this.selectedZone === null || this.selectedZone === undefined) {
|
||||
return
|
||||
}
|
||||
const promises = []
|
||||
const params = {
|
||||
zoneid: this.selectedZone.id
|
||||
}
|
||||
this.formPhysicalNetworkLoading = true
|
||||
api('listPhysicalNetworks', params).then(json => {
|
||||
var networks = json.listphysicalnetworksresponse.physicalnetwork
|
||||
if (this.arrayHasItems(networks)) {
|
||||
for (const network of networks) {
|
||||
promises.push(this.addPhysicalNetworkForGuestTrafficType(network))
|
||||
}
|
||||
} else {
|
||||
this.formPhysicalNetworkLoading = false
|
||||
}
|
||||
}).finally(() => {
|
||||
if (this.arrayHasItems(promises)) {
|
||||
Promise.all(promises).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.formPhysicalNetworkLoading = false
|
||||
this.selectFirstPhysicalNetwork()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
selectFirstPhysicalNetwork () {
|
||||
if (this.arrayHasItems(this.formPhysicalNetworks)) {
|
||||
|
|
@ -556,14 +612,29 @@ export default {
|
|||
}
|
||||
case 'project':
|
||||
{
|
||||
this.fetchDomainData()
|
||||
this.fetchProjectData()
|
||||
this.fetchNetworkOfferingData()
|
||||
if (isAdminOrDomainAdmin()) {
|
||||
this.fetchDomainData()
|
||||
} else {
|
||||
this.fetchProjectData()
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'account':
|
||||
{
|
||||
if (isAdminOrDomainAdmin()) {
|
||||
this.fetchDomainData()
|
||||
} else {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
{
|
||||
this.fetchNetworkOfferingData()
|
||||
if (isAdminOrDomainAdmin()) {
|
||||
this.fetchDomainData()
|
||||
} else {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -576,6 +647,9 @@ export default {
|
|||
zoneid: this.selectedZone.id,
|
||||
state: 'Enabled'
|
||||
}
|
||||
if (!isAdmin()) {
|
||||
params.specifyvlan = false
|
||||
}
|
||||
if (!this.isObjectEmpty(this.formSelectedPhysicalNetwork) &&
|
||||
this.formSelectedPhysicalNetwork.tags &&
|
||||
this.formSelectedPhysicalNetwork.tags.length > 0) {
|
||||
|
|
@ -583,25 +657,25 @@ export default {
|
|||
}
|
||||
// Network tab in Guest Traffic Type in Infrastructure menu is only available when it's under Advanced zone.
|
||||
// zone dropdown in add guest network dialog includes only Advanced zones.
|
||||
if (this.scopeType === 'all' || this.scopeType === 'domain') {
|
||||
params.guestiptype = 'Shared'
|
||||
if (this.scopeType === 'domain') {
|
||||
params.domainid = this.selectedDomain.id
|
||||
}
|
||||
params.guestiptype = 'Shared'
|
||||
if (this.scopeType === 'domain') {
|
||||
params.domainid = this.selectedDomain.id
|
||||
}
|
||||
this.handleNetworkOfferingChange(null)
|
||||
this.networkOfferings = []
|
||||
api('listNetworkOfferings', params).then(json => {
|
||||
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
|
||||
this.handleNetworkOfferingChange(this.networkOfferings[0])
|
||||
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering || []
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.networkOfferingLoading = false
|
||||
if (this.arrayHasItems(this.networkOfferings)) {
|
||||
this.form.networkofferingid = 0
|
||||
this.handleNetworkOfferingChange(this.networkOfferings[0])
|
||||
this.networkOfferingWarning = false
|
||||
} else {
|
||||
this.form.networkofferingid = null
|
||||
this.networkOfferingWarning = true
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -609,8 +683,71 @@ export default {
|
|||
this.selectedNetworkOffering = networkOffering
|
||||
if (networkOffering) {
|
||||
this.networkServiceProviderMap(this.selectedNetworkOffering.id)
|
||||
if (!networkOffering.specifyvlan) {
|
||||
this.fetchNetworkData()
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchNetworkData () {
|
||||
if (this.isObjectEmpty(this.selectedZone)) {
|
||||
return
|
||||
}
|
||||
if (this.isObjectEmpty(this.selectedNetworkOffering) || this.selectedNetworkOffering.specifyvlan) {
|
||||
return
|
||||
}
|
||||
if (this.isObjectEmpty(this.selectedProject) && this.scopeType === 'project') {
|
||||
return
|
||||
}
|
||||
this.networkLoading = true
|
||||
var params = {
|
||||
zoneid: this.selectedZone.id,
|
||||
networkfilter: 'Account'
|
||||
}
|
||||
if (this.formSelectedPhysicalNetwork) {
|
||||
params.physicalnetworkid = this.formSelectedPhysicalNetwork.id
|
||||
}
|
||||
switch (this.scopeType) {
|
||||
case 'domain':
|
||||
{
|
||||
params.domainid = this.selectedDomain.id
|
||||
params.ignoreproject = true
|
||||
break
|
||||
}
|
||||
case 'project':
|
||||
{
|
||||
params.domainid = this.selectedProject.domainid
|
||||
params.projectid = this.selectedProject.id
|
||||
break
|
||||
}
|
||||
case 'account':
|
||||
{
|
||||
params.domainid = this.selectedAccount.domainid
|
||||
params.account = this.selectedAccount.name
|
||||
params.ignoreproject = true
|
||||
break
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
this.handleNetworkChange(null)
|
||||
this.networks = []
|
||||
api('listNetworks', params).then(json => {
|
||||
var networks = json.listnetworksresponse.network || []
|
||||
for (const network of networks) {
|
||||
if (network.type === 'Isolated' || network.type === 'L2') {
|
||||
this.networks.push(network)
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.networkLoading = false
|
||||
})
|
||||
},
|
||||
handleNetworkChange (selectedNetwork) {
|
||||
this.selectedNetwork = selectedNetwork
|
||||
},
|
||||
networkServiceProviderMap (id) {
|
||||
api('listNetworkOfferings', { id: id }).then(json => {
|
||||
var networkOffering = json.listnetworkofferingsresponse.networkoffering[0]
|
||||
|
|
@ -630,9 +767,10 @@ export default {
|
|||
})
|
||||
},
|
||||
fetchDomainData () {
|
||||
this.networkOfferingWarning = false
|
||||
const params = {}
|
||||
if (!this.isObjectEmpty(this.selectedZone) && this.selectedZone.domainid != null) {
|
||||
params.id = this.selectedZone.id
|
||||
params.id = this.selectedZone.domainid
|
||||
params.isrecursive = true
|
||||
} else {
|
||||
params.listall = true
|
||||
|
|
@ -640,40 +778,86 @@ export default {
|
|||
params.showicon = true
|
||||
this.domainLoading = true
|
||||
api('listDomains', params).then(json => {
|
||||
const listDomains = json.listdomainsresponse.domain
|
||||
this.domains = this.domains.concat(listDomains)
|
||||
const listDomains = json.listdomainsresponse.domain || []
|
||||
this.domains = listDomains
|
||||
}).finally(() => {
|
||||
this.domainLoading = false
|
||||
this.form.domainid = 0
|
||||
this.handleDomainChange(this.domains[0])
|
||||
if (this.arrayHasItems(this.domains) && this.scopeType !== 'all') {
|
||||
this.form.domainid = 0
|
||||
this.handleDomainChange(this.domains[0])
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDomainChange (domain) {
|
||||
this.selectedDomain = domain
|
||||
if (!this.isObjectEmpty(domain)) {
|
||||
if (this.scopeType === 'domain') {
|
||||
this.fetchNetworkOfferingData()
|
||||
} else if (this.scopeType === 'account') {
|
||||
this.fetchAccountData()
|
||||
} else if (this.scopeType === 'project') {
|
||||
this.fetchProjectData()
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchAccountData () {
|
||||
this.networkOfferingWarning = false
|
||||
this.accounts = []
|
||||
const params = {}
|
||||
params.showicon = true
|
||||
params.details = 'min'
|
||||
if (this.selectedDomain) {
|
||||
params.domainid = this.selectedDomain.id
|
||||
}
|
||||
this.accountLoading = true
|
||||
this.handleAccountChange(null)
|
||||
api('listAccounts', params).then(json => {
|
||||
this.accounts = json.listaccountsresponse.account || []
|
||||
}).finally(() => {
|
||||
this.accountLoading = false
|
||||
if (this.arrayHasItems(this.accounts) && this.scopeType === 'account') {
|
||||
this.form.account = 0
|
||||
this.handleAccountChange(this.accounts[0])
|
||||
} else {
|
||||
this.form.account = null
|
||||
}
|
||||
})
|
||||
},
|
||||
handleAccountChange (account) {
|
||||
this.selectedAccount = account
|
||||
if (!this.isObjectEmpty(account)) {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
},
|
||||
fetchProjectData () {
|
||||
this.networkOfferingWarning = false
|
||||
this.projects = []
|
||||
const params = {}
|
||||
params.listall = true
|
||||
params.showicon = true
|
||||
params.details = 'min'
|
||||
if (this.selectedDomain) {
|
||||
params.domainid = this.selectedDomain.id
|
||||
}
|
||||
this.projectLoading = true
|
||||
this.handleProjectChange(null)
|
||||
api('listProjects', params).then(json => {
|
||||
const listProjects = json.listprojectsresponse.project
|
||||
this.projects = this.projects.concat(listProjects)
|
||||
this.projects = json.listprojectsresponse.project || []
|
||||
}).finally(() => {
|
||||
this.projectLoading = false
|
||||
if (this.arrayHasItems(this.projects)) {
|
||||
if (this.arrayHasItems(this.projects) && this.scopeType === 'project') {
|
||||
this.form.projectid = 0
|
||||
this.handleProjectChange(this.projects[0])
|
||||
} else {
|
||||
this.form.projectid = null
|
||||
}
|
||||
})
|
||||
},
|
||||
handleProjectChange (project) {
|
||||
this.selectedProject = project
|
||||
if (!this.isObjectEmpty(project)) {
|
||||
this.fetchNetworkOfferingData()
|
||||
}
|
||||
},
|
||||
handleSubmit (e) {
|
||||
if (this.actionLoading) return
|
||||
|
|
@ -714,18 +898,26 @@ export default {
|
|||
params.isolatedpvlan = values.isolatedpvlan
|
||||
}
|
||||
}
|
||||
if (this.selectedNetwork) {
|
||||
params.associatednetworkid = this.selectedNetwork.id
|
||||
}
|
||||
if (this.scopeType !== 'all') {
|
||||
params.domainid = this.selectedDomain.id
|
||||
params.acltype = this.scopeType
|
||||
if (this.scopeType === 'account') { // account-specific
|
||||
params.account = values.account
|
||||
params.domainid = this.selectedAccount.domainid
|
||||
params.account = this.selectedAccount.name
|
||||
} else if (this.scopeType === 'project') { // project-specific
|
||||
params.acltype = 'account'
|
||||
params.domainid = this.selectedProject.domainid
|
||||
params.projectid = this.selectedProject.id
|
||||
} else { // domain-specific
|
||||
params.subdomainaccess = this.parseBooleanValueForKey(values, 'subdomainaccess')
|
||||
}
|
||||
} else { // zone-wide
|
||||
} else if (isAdminOrDomainAdmin()) { // zone-wide
|
||||
params.acltype = 'domain' // server-side will make it Root domain (i.e. domainid=1)
|
||||
} else {
|
||||
params.acltype = 'account' // acl type is "account" for regular users
|
||||
}
|
||||
// IPv4 (begin)
|
||||
if (this.isValidTextValueForKey(values, 'ip4gateway')) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
<template>
|
||||
<a-table
|
||||
size="small"
|
||||
style="overflow-y: auto"
|
||||
:columns="columns"
|
||||
:dataSource="networks"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false"
|
||||
:loading="fetchLoading"
|
||||
>
|
||||
<template #name="{ text, record }">
|
||||
<router-link v-if="record.issystem === false && !record.projectid" :to="{ path: '/guestnetwork/' + record.id }" >{{ text }}</router-link>
|
||||
<router-link v-else-if="record.issystem === false && record.projectid" :to="{ path: '/guestnetwork/' + record.id, query: { projectid: record.projectid}}" >{{ text }}</router-link>
|
||||
<span v-else>{{ text }}</span>
|
||||
</template>
|
||||
<template #state="{ record }">
|
||||
<status :text="record.state" displayText></status>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import Status from '@/components/widgets/Status'
|
||||
|
||||
export default {
|
||||
name: 'GuestVlanNetworksTab',
|
||||
components: {
|
||||
Status
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fetchLoading: false,
|
||||
networks: [],
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('label.name'),
|
||||
dataIndex: 'name',
|
||||
slots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
title: this.$t('label.type'),
|
||||
dataIndex: 'type'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.state'),
|
||||
slots: { customRender: 'state' }
|
||||
},
|
||||
{
|
||||
title: this.$t('label.broadcasturi'),
|
||||
dataIndex: 'broadcasturi'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.domain'),
|
||||
dataIndex: 'domain'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.account'),
|
||||
dataIndex: 'account'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.project'),
|
||||
dataIndex: 'project'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.vpc'),
|
||||
dataIndex: 'vpc'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
resource: function (newItem, oldItem) {
|
||||
if (!newItem || !newItem.id) {
|
||||
return
|
||||
}
|
||||
this.fetchData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
var params = {
|
||||
id: this.resource.id
|
||||
}
|
||||
this.fetchLoading = true
|
||||
api('listGuestVlans', params).then(json => {
|
||||
this.networks = json.listguestvlansresponse.guestvlan[0].network || []
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.status {
|
||||
margin-top: -5px;
|
||||
|
||||
&--end {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
// 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.
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-spin :spinning="fetchLoading">
|
||||
<a-button
|
||||
shape="round"
|
||||
style="float: right;margin-bottom: 10px; z-index: 8"
|
||||
@click="() => { showCreateForm = true }">
|
||||
<template #icon><plus-outlined /></template>
|
||||
{{ $t('label.add.network.permission') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
shape="round"
|
||||
style="float: right;margin-bottom: 10px; z-index: 8"
|
||||
@click="showResetPermissionModal = true"
|
||||
:disabled="!('createNetworkPermissions' in $store.getters.apis)">
|
||||
<template #icon><minus-outlined /></template>
|
||||
{{ $t('label.action.reset.network.permissions') }}
|
||||
</a-button>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a-table
|
||||
size="small"
|
||||
style="overflow-y: auto; width: 100%;"
|
||||
:columns="columns"
|
||||
:dataSource="networkpermissions"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false" >
|
||||
|
||||
<template #action="{ record }">
|
||||
<a-popconfirm
|
||||
:title="$t('message.confirm.remove.network.permission')"
|
||||
@confirm="removeNetworkPermission(record.accountid, record.projectid)"
|
||||
:okText="$t('label.yes')"
|
||||
:cancelText="$t('label.no')" >
|
||||
<tooltip-button
|
||||
tooltipPlacement="bottom"
|
||||
:tooltip="$t('label.action.delete.network.permission')"
|
||||
type="primary"
|
||||
:danger="true"
|
||||
icon="delete-outlined" />
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
<a-divider/>
|
||||
</a-spin>
|
||||
<a-modal
|
||||
v-if="showCreateForm"
|
||||
:visible="showCreateForm"
|
||||
:title="$t('label.add.network.permission')"
|
||||
:maskClosable="false"
|
||||
:closable="true"
|
||||
:footer="null"
|
||||
@cancel="() => { showCreateForm = false }"
|
||||
centered
|
||||
width="auto">
|
||||
<CreateNetworkPermission
|
||||
:resource="resource"
|
||||
@refresh-data="fetchData"
|
||||
@close-action="showCreateForm = false" />
|
||||
</a-modal>
|
||||
<a-modal
|
||||
:visible="showResetPermissionModal"
|
||||
:title="$t('label.action.reset.network.permissions')"
|
||||
:maskClosable="false"
|
||||
:closable="true"
|
||||
:footer="null"
|
||||
@cancel="showResetPermissionModal = false"
|
||||
centered
|
||||
width="auto"
|
||||
v-ctrl-enter="resetNetworkPermission">
|
||||
{{ $t('message.confirm.reset.network.permissions') }}
|
||||
<a-form @submit="resetNetworkPermission">
|
||||
<div :span="24" class="action-button">
|
||||
<a-button @click="showResetPermissionModal = false">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button type="primary" ref="submit" @click="resetNetworkPermission">{{ $t('label.ok') }}</a-button>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import CreateNetworkPermission from '@/views/network/CreateNetworkPermission'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
export default {
|
||||
name: 'NetworkPermissions',
|
||||
components: {
|
||||
CreateNetworkPermission,
|
||||
TooltipButton
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showResetPermissionModal: false,
|
||||
fetchLoading: false,
|
||||
showCreateForm: false,
|
||||
total: 0,
|
||||
networkpermissions: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('label.domain'),
|
||||
dataIndex: 'domain'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.account'),
|
||||
dataIndex: 'account'
|
||||
},
|
||||
{
|
||||
title: this.$t('label.project'),
|
||||
dataIndex: 'project'
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
slots: { customRender: 'action' }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
resource: {
|
||||
deep: true,
|
||||
handler (newItem) {
|
||||
if (!newItem || !newItem.id) {
|
||||
return
|
||||
}
|
||||
this.fetchData()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
const params = {
|
||||
networkid: this.resource.id
|
||||
}
|
||||
this.fetchLoading = true
|
||||
api('listNetworkPermissions', params).then(json => {
|
||||
this.total = json.listnetworkpermissionsresponse.count || 0
|
||||
this.networkpermissions = json.listnetworkpermissionsresponse.networkpermission || []
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
},
|
||||
removeNetworkPermission (accountId, projectId) {
|
||||
const params = {
|
||||
networkid: this.resource.id
|
||||
}
|
||||
if (projectId) {
|
||||
params.projectids = projectId
|
||||
} else {
|
||||
params.accountids = accountId
|
||||
}
|
||||
api('removeNetworkPermissions', params).then(json => {
|
||||
this.$notification.success({
|
||||
message: this.$t('message.success.remove.network.permissions')
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchData()
|
||||
})
|
||||
},
|
||||
resetNetworkPermission () {
|
||||
api('resetNetworkPermissions', {
|
||||
networkid: this.resource.id
|
||||
}).then(json => {
|
||||
this.$notification.success({
|
||||
message: this.$t('message.success.reset.network.permissions')
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchData()
|
||||
this.showResetPermissionModal = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.vlan')" :required="true" ref="vlan" name="vlan">
|
||||
<a-form-item :label="$t('label.vlan')" ref="vlan" name="vlan" v-if="this.isAdmin()">
|
||||
<a-input
|
||||
:placeholder="placeholders.vlan"
|
||||
v-model:value="form.vlan"
|
||||
|
|
@ -180,24 +180,41 @@
|
|||
ref="bypassvlanoverlapcheck"
|
||||
name="bypassvlanoverlapcheck"
|
||||
:label="$t('label.bypassvlanoverlapcheck')"
|
||||
v-if="$store.getters.apis.createPrivateGateway && $store.getters.apis.createPrivateGateway.params.filter(x => x.name === 'bypassvlanoverlapcheck').length > 0" >
|
||||
v-if="this.isAdmin()">
|
||||
<a-checkbox
|
||||
v-model:checked="form.bypassvlanoverlapcheck"
|
||||
></a-checkbox>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.publicip')" :required="true" ref="ipaddress" name="ipaddress">
|
||||
<a-form-item :label="$t('label.associatednetwork')" ref="associatednetworkid" name="associatednetworkid">
|
||||
<a-select
|
||||
v-model:value="form.associatednetwork"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option v-for="(opt, optIndex) in this.associatedNetworks" :key="optIndex" :label="opt.name || opt.description" :value="opt.id">
|
||||
<span>
|
||||
<resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<user-outlined style="margin-right: 5px" />
|
||||
{{ opt.name || opt.description }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.publicip')" ref="ipaddress" name="ipaddress">
|
||||
<a-input
|
||||
:placeholder="placeholders.ipaddress"
|
||||
v-model:value="form.ipaddress"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.gateway')" :required="true" ref="gateway" name="gateway">
|
||||
<a-form-item :label="$t('label.gateway')" ref="gateway" name="gateway">
|
||||
<a-input
|
||||
:placeholder="placeholders.gateway"
|
||||
v-model:value="form.gateway"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.netmask')" :required="true" ref="netmask" name="netmask">
|
||||
<a-form-item :label="$t('label.netmask')" ref="netmask" name="netmask">
|
||||
<a-input
|
||||
:placeholder="placeholders.netmask"
|
||||
v-model:value="form.netmask"
|
||||
|
|
@ -383,6 +400,7 @@ export default {
|
|||
return {
|
||||
fetchLoading: false,
|
||||
privateGateways: [],
|
||||
associatedNetworks: [],
|
||||
vpnGateways: [],
|
||||
vpnConnections: [],
|
||||
networkAcls: [],
|
||||
|
|
@ -492,6 +510,9 @@ export default {
|
|||
this.form = reactive({})
|
||||
this.rules = reactive({})
|
||||
},
|
||||
isAdmin () {
|
||||
return ['Admin'].includes(this.$store.getters.userInfo.roletype)
|
||||
},
|
||||
setCurrentTab () {
|
||||
this.currentTab = this.$route?.query?.tab || 'details'
|
||||
},
|
||||
|
|
@ -558,6 +579,22 @@ export default {
|
|||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
this.associatedNetworks = []
|
||||
api('listNetworks', {
|
||||
domainid: this.resource.domainid,
|
||||
account: this.resource.account,
|
||||
listAll: true,
|
||||
networkfilter: 'Account'
|
||||
}).then(json => {
|
||||
var networks = json.listnetworksresponse.network || []
|
||||
for (const network of networks) {
|
||||
if (network.type === 'Isolated' || network.type === 'L2') {
|
||||
this.associatedNetworks.push(network)
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
this.$notifyError(error)
|
||||
})
|
||||
},
|
||||
fetchVpnGateways () {
|
||||
this.fetchLoading = true
|
||||
|
|
@ -609,6 +646,10 @@ export default {
|
|||
},
|
||||
fetchPhysicalNetworks () {
|
||||
this.modals.gatewayLoading = true
|
||||
if (!this.isAdmin()) {
|
||||
this.modals.gatewayLoading = false
|
||||
return
|
||||
}
|
||||
api('listPhysicalNetworks', { zoneid: this.resource.zoneid }).then(json => {
|
||||
this.physicalnetworks = json.listphysicalnetworksresponse.physicalnetwork
|
||||
if (this.modals.gateway === true) {
|
||||
|
|
@ -639,7 +680,6 @@ export default {
|
|||
switch (e) {
|
||||
case 'privateGateways':
|
||||
this.rules = {
|
||||
vlan: [{ required: true, message: this.$t('label.required') }],
|
||||
ipaddress: [{ required: true, message: this.$t('label.required') }],
|
||||
gateway: [{ required: true, message: this.$t('label.required') }],
|
||||
netmask: [{ required: true, message: this.$t('label.required') }]
|
||||
|
|
@ -676,12 +716,17 @@ export default {
|
|||
ipaddress: data.ipaddress,
|
||||
gateway: data.gateway,
|
||||
netmask: data.netmask,
|
||||
vlan: data.vlan,
|
||||
aclid: data.acl
|
||||
}
|
||||
if (data.bypassvlanoverlapcheck) {
|
||||
params.bypassvlanoverlapcheck = data.bypassvlanoverlapcheck
|
||||
}
|
||||
if (data.vlan && String(data.vlan).length > 0) {
|
||||
params.vlan = data.vlan
|
||||
}
|
||||
if (data.associatednetwork) {
|
||||
params.associatednetworkid = data.associatednetwork
|
||||
}
|
||||
|
||||
api('createPrivateGateway', params).then(response => {
|
||||
this.$pollJob({
|
||||
|
|
|
|||
|
|
@ -68,15 +68,7 @@
|
|||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-row :gutter="12" v-if="guestType !== 'shared'">
|
||||
<a-col :md="12" :lg="12">
|
||||
<a-form-item name="ispersistent" ref="ispersistent">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.ispersistent')" :tooltip="apiParams.ispersistent.description"/>
|
||||
</template>
|
||||
<a-switch v-model:checked="form.ispersistent" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-row :gutter="12">
|
||||
<a-col :md="12" :lg="12">
|
||||
<a-form-item name="specifyvlan" ref="specifyvlan">
|
||||
<template #label>
|
||||
|
|
@ -85,6 +77,14 @@
|
|||
<a-switch v-model:checked="form.specifyvlan" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :md="12" :lg="12">
|
||||
<a-form-item name="ispersistent" ref="ispersistent" v-if="guestType !== 'shared'">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.ispersistent')" :tooltip="apiParams.ispersistent.description"/>
|
||||
</template>
|
||||
<a-switch v-model:checked="form.ispersistent" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item name="forvpc" ref="forvpc" v-if="guestType === 'isolated'">
|
||||
<template #label>
|
||||
|
|
@ -818,7 +818,9 @@ export default {
|
|||
})
|
||||
|
||||
if (values.guestiptype === 'shared') { // specifyVlan checkbox is disabled, so inputData won't include specifyVlan
|
||||
params.specifyvlan = true
|
||||
if (values.specifyvlan === true) {
|
||||
params.specifyvlan = true
|
||||
}
|
||||
params.specifyipranges = true
|
||||
delete params.ispersistent
|
||||
} else if (values.guestiptype === 'isolated') { // specifyVlan checkbox is shown
|
||||
|
|
|
|||
Loading…
Reference in New Issue