network: ipv6 static routes (#5786)

* wip

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* IPv6: configure VR of isolated networks

* IPv6: add default IPv6 route in VR of isolated networks

* Reformat server/src/main/java/com/cloud/network/NetworkServiceImpl.java

* IPv6: update network to offering which support IPv6

* IPv6: update vm nic ipv6 address when update network to new offering

* IPv6: configure VPC VR to support multiple tiers with IPv6

* IPv6: add RDNSS in radvd.conf

* IPv6/UI: support ipv6 protocols in Network ACL

* wip

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* changes for diagnostics

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* more import fromo #5594

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* IPv6: fix wrong public ipv6 in VPC VR

* changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* Update server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Co-authored-by: dahn <daan.hoogland@gmail.com>

* ui: fix add ipv6 prefix labels, message

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: label fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* logging fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* minor ui refactor

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ip6 events

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ip6 usage

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* unused

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* slaac based public ip

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* remove unused

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* diagnostics fix for vr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* firewall changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* alert and show ipv6 usage

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* change for network response

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ipv6 network test

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: fix ipaddress listing

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* wip

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix simulator

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test and fixes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test temp change revert

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fixes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* use uuid

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* event syntax fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* wip

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* review comments

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* assign vlan public IP for dualstack only if both protocols present on same vlan

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* internetprotocol in networkofferingresponse

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* add tcp, udp

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* support vpc with ipv6 only on same vlan

- adds new internet protocol param to createVpcOffering API
- When DualStack internet protocol is selected for the VPC offering, tiers with network with or without IPv6 support can be deployed.
- When IPv4 internet protocol is used for the VPC offering, tiers with network with only IPv4 support can be deployed

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* change and fix

allow VPC with IPv4 protocol to deploy tiers with IPv6

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test fix

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui fixes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix multiple routes, network guest ipv6 gateway

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* address review comments

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* stop radvd on backup VR

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix router redundant status with ipv6

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* disable radvd for backup vr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* correctly set ipv6 in redundant router case

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* remove unused code

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix connection

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: don't show all protocol for egress

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix guest ipv6 for redundant VRs

Redundant VRs will not be assigned an IPv6 by ACS and guest netwrok gateway will be added as IPv6 for guest interface by systemvm scripts during setting redundant state of the VR.

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix missing ipv6 on redundant vr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix syntax

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: fix vpc tier redirect to show details

When redirecting to VPC tier, details tab should be active by default

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* restart radvd on primary redundant vr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* check for ipv6 values

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* remove old ui change

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix condition

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* remove gateway from backup vr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* network upgrade fail early

when IPv6 network cannot be allocated fail before shutting down the network

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix radvd not running on RVR

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* prepare radvd.conf once

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix job polling

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix RVR for vpc with ipv6

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix ipv6 network acls

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* Update CsConfig.py

* add check

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test: vpc offering test

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test: add negative tests for guest prefix, public range

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* add default ipv6 route for primary

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix dadfailed on vpc rvr

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: fix add iprange form, dedicate action visibility

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix adding, deleting ipv6 range

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix failing test

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix missing destination cidr in ipv6 firewall

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix ipv6 nftables rules

Allow storing linger IPv6 CIDRs in DB
Specify all port range for TC{, UDP protocol rules withot ports
Fix adding nft rules by creating chains first

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix icmpv6 type, code

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix icmp type, code

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test: add more for ipv6 network

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* add warning message for egress policy in ipv6 fw rule

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui,server: update ipv6 vlan range

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* subnet operations inside transaction

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* server: persistent public IPv6 for network

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* ui: fix action alignment

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix vpc acl for tiers

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix removing network placeholder nic

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix acl rules for ip version

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix placeholder nic and nd-neighbor block issue

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* test for redundant nw

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* fix ping

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

* systemvm: uprgade to debian 11.3.0

* ipv6: enable ipv6 in sysctl config in bootstrap.sh

* VR: fix KeyError: 'nic_ip6_cidr'

* build fix for latest event changes

Signed-off-by: Abhishek Kumar <abhishek.kumar@shapeblue.com>

Co-authored-by: Wei Zhou <weizhou@apache.org>
Co-authored-by: dahn <daan.hoogland@gmail.com>
This commit is contained in:
Abhishek Kumar 2022-04-26 07:21:32 +05:30 committed by GitHub
parent a9bbcf8700
commit 4a914aa88d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
148 changed files with 7632 additions and 620 deletions

View File

@ -155,6 +155,9 @@ public class FirewallRuleTO implements InternalIdentity {
rule.getIcmpType(),
rule.getIcmpCode());
this.trafficType = trafficType;
if (FirewallRule.Purpose.Ipv6Firewall.equals(purpose)) {
this.destCidrList = rule.getDestinationCidrList();
}
}
public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType,

View File

@ -39,6 +39,7 @@ public class NetworkTO {
protected boolean isSecurityGroupEnabled;
protected String name;
protected String ip6address;
protected String ip6gateway;
protected String ip6cidr;
public NetworkTO() {
@ -68,6 +69,10 @@ public class NetworkTO {
this.ip6address = addr;
}
public void setIp6Gateway(String gateway) {
this.ip6gateway = gateway;
}
public void setIp6Cidr(String cidr) {
this.ip6cidr = cidr;
}
@ -161,6 +166,10 @@ public class NetworkTO {
return ip6address;
}
public String getIp6Gateway() {
return ip6gateway;
}
public String getIp6Cidr() {
return ip6cidr;
}

View File

@ -30,6 +30,7 @@ public interface Capacity extends InternalIdentity, Identity {
public static final short CAPACITY_TYPE_VLAN = 7;
public static final short CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8;
public static final short CAPACITY_TYPE_LOCAL_STORAGE = 9;
public static final short CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = 10;
public static final short CAPACITY_TYPE_GPU = 19;
public static final short CAPACITY_TYPE_CPU_CORE = 90;

View File

@ -20,10 +20,13 @@ import java.util.List;
import org.apache.cloudstack.api.command.admin.config.ResetCfgCmd;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.UpdatePodManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
@ -51,6 +54,7 @@ import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.Pod;
import com.cloud.dc.Vlan;
import com.cloud.domain.Domain;
@ -223,6 +227,21 @@ public interface ConfigurationService {
*/
void updatePodIpRange(UpdatePodManagementNetworkIpRangeCmd cmd) throws ConcurrentOperationException;
/**
* Creates a new IPv6 prefix for a zone. Needs to be >= /64.
*/
DataCenterGuestIpv6Prefix createDataCenterGuestIpv6Prefix(CreateGuestNetworkIpv6PrefixCmd cmd);
/**
* Lists IPv6 prefixes for a zone.
*/
List<? extends DataCenterGuestIpv6Prefix> listDataCenterGuestIpv6Prefixes(ListGuestNetworkIpv6PrefixesCmd cmd);
/**
* Deletes an existing IPv6 prefix.
*/
boolean deleteDataCenterGuestIpv6Prefix(DeleteGuestNetworkIpv6PrefixCmd cmd);
/**
* Edits a pod in the database. Will not allow you to edit pods that are being used anywhere in the system.
*

View File

@ -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.dc;
import java.util.Date;
import org.apache.cloudstack.acl.InfrastructureEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface DataCenterGuestIpv6Prefix extends InfrastructureEntity, InternalIdentity, Identity {
Long getDataCenterId();
String getPrefix();
Date getCreated();
}

View File

@ -32,6 +32,7 @@ import org.apache.cloudstack.ha.HAConfig;
import org.apache.cloudstack.usage.Usage;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.Pod;
import com.cloud.dc.StorageNetworkIpRange;
import com.cloud.dc.Vlan;
@ -150,6 +151,10 @@ public class EventTypes {
public static final String EVENT_FIREWALL_CLOSE = "FIREWALL.CLOSE";
public static final String EVENT_FIREWALL_UPDATE = "FIREWALL.UPDATE";
public static final String EVENT_NET_IP6_ASSIGN = "NET.IP6ASSIGN";
public static final String EVENT_NET_IP6_RELEASE = "NET.IP6RELEASE";
public static final String EVENT_NET_IP6_UPDATE = "NET.IP6UPDATE";
public static final String EVENT_FIREWALL_EGRESS_OPEN = "FIREWALL.EGRESS.OPEN";
public static final String EVENT_FIREWALL_EGRESS_CLOSE = "FIREWALL.EGRESS.CLOSE";
public static final String EVENT_FIREWALL_EGRESS_UPDATE = "FIREWALL.EGRESS.UPDATE";
@ -334,6 +339,9 @@ public class EventTypes {
public static final String EVENT_MANAGEMENT_IP_RANGE_DELETE = "MANAGEMENT.IP.RANGE.DELETE";
public static final String EVENT_MANAGEMENT_IP_RANGE_UPDATE = "MANAGEMENT.IP.RANGE.UPDATE";
public static final String EVENT_GUEST_IP6_PREFIX_CREATE = "GUEST.IP6.PREFIX.CREATE";
public static final String EVENT_GUEST_IP6_PREFIX_DELETE = "GUEST.IP6.PREFIX.DELETE";
public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE";
public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE";
public static final String EVENT_STORAGE_IP_RANGE_UPDATE = "STORAGE.IP.RANGE.UPDATE";
@ -482,6 +490,11 @@ public class EventTypes {
public static final String EVENT_NETWORK_ACL_ITEM_UPDATE = "NETWORK.ACL.ITEM.UPDATE";
public static final String EVENT_NETWORK_ACL_ITEM_DELETE = "NETWORK.ACL.ITEM.DELETE";
// IPv6 firewall rule
public static final String EVENT_IPV6_FIREWALL_RULE_CREATE = "IPV6.FIREWALL.RULE.CREATE";
public static final String EVENT_IPV6_FIREWALL_RULE_UPDATE = "IPV6.FIREWALL.RULE.UPDATE";
public static final String EVENT_IPV6_FIREWALL_RULE_DELETE = "IPV6.FIREWALL.RULE.DELETE";
// VPC offerings
public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE";
public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE";
@ -704,6 +717,9 @@ public class EventTypes {
entityEventDetails.put(EVENT_FIREWALL_EGRESS_OPEN, FirewallRule.class);
entityEventDetails.put(EVENT_FIREWALL_EGRESS_CLOSE, FirewallRule.class);
entityEventDetails.put(EVENT_FIREWALL_EGRESS_UPDATE, FirewallRule.class);
entityEventDetails.put(EVENT_NET_IP6_ASSIGN, Network.class);
entityEventDetails.put(EVENT_NET_IP6_RELEASE, Network.class);
entityEventDetails.put(EVENT_NET_IP6_UPDATE, Network.class);
// Nic Events
entityEventDetails.put(EVENT_NIC_CREATE, Nic.class);
@ -845,6 +861,9 @@ public class EventTypes {
entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_CREATE, Pod.class);
entityEventDetails.put(EVENT_MANAGEMENT_IP_RANGE_DELETE, Pod.class);
entityEventDetails.put(EVENT_GUEST_IP6_PREFIX_CREATE, DataCenterGuestIpv6Prefix.class);
entityEventDetails.put(EVENT_GUEST_IP6_PREFIX_DELETE, DataCenterGuestIpv6Prefix.class);
entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class);
entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class);
entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class);

View File

@ -0,0 +1,37 @@
// 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 Ipv6GuestPrefixSubnetNetworkMap extends Identity, InternalIdentity {
enum State {
Allocating, // The subnet will be assigned to a network
Allocated, // The subnet is in use.
Free // The subnet is ready to be allocated.
}
long getPrefixId();
String getSubnet();
Long getNetworkId();
State getState();
}

View File

@ -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 com.cloud.network;
import java.util.List;
import org.apache.cloudstack.api.command.user.ipv6.CreateIpv6FirewallRuleCmd;
import org.apache.cloudstack.api.command.user.ipv6.ListIpv6FirewallRulesCmd;
import org.apache.cloudstack.api.command.user.ipv6.UpdateIpv6FirewallRuleCmd;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.Vlan;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.vpc.Vpc;
import com.cloud.utils.Pair;
import com.cloud.utils.component.PluggableService;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
public interface Ipv6Service extends PluggableService, Configurable {
public static final int IPV6_SLAAC_CIDR_NETMASK = 64;
static final ConfigKey<Boolean> Ipv6OfferingCreationEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class,
"ipv6.offering.enabled",
"false",
"Indicates whether creation of IPv6 network/VPC offering is enabled or not.",
true);
static final ConfigKey<Integer> Ipv6PrefixSubnetCleanupInterval = new ConfigKey<Integer>("Advanced", Integer.class,
"network.ipv6.prefix.subnet.cleanup.interval",
"1800",
"Determines how long (in seconds) to wait before deallocating prefix subnets which are in Allocating state. The default value = 1800 seconds.",
true);
Pair<Integer, Integer> getUsedTotalIpv6SubnetForPrefix(DataCenterGuestIpv6Prefix prefix);
Pair<Integer, Integer> getUsedTotalIpv6SubnetForZone(long zoneId);
Pair<String, String> preAllocateIpv6SubnetForNetwork(long zoneId) throws ResourceAllocationException;
void assignIpv6SubnetToNetwork(String subnet, long networkId);
void releaseIpv6SubnetForNetwork(long networkId);
List<String> getAllocatedIpv6FromVlanRange(Vlan vlan);
Nic assignPublicIpv6ToNetwork(Network network, Nic nic);
void updateNicIpv6(NicProfile nic, DataCenter dc, Network network) throws InsufficientAddressCapacityException;
void releasePublicIpv6ForNic(Network network, String nicIpv6Address);
List<String> getPublicIpv6AddressesForNetwork(Network network);
void updateIpv6RoutesForVpcResponse(Vpc vpc, VpcResponse response);
void checkNetworkIpv6Upgrade(Network network) throws InsufficientAddressCapacityException, ResourceAllocationException;
FirewallRule updateIpv6FirewallRule(UpdateIpv6FirewallRuleCmd updateIpv6FirewallRuleCmd);
Pair<List<? extends FirewallRule>,Integer> listIpv6FirewallRules(ListIpv6FirewallRulesCmd listIpv6FirewallRulesCmd);
boolean revokeIpv6FirewallRule(Long id);
FirewallRule createIpv6FirewallRule(CreateIpv6FirewallRuleCmd createIpv6FirewallRuleCmd) throws NetworkRuleConflictException;
FirewallRule getIpv6FirewallRule(Long entityId);
boolean applyIpv6FirewallRule(long id);
void removePublicIpv6PlaceholderNics(Network network);
}

View File

@ -22,16 +22,15 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.cloud.exception.InvalidParameterValueException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Displayable;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
@ -79,6 +78,22 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
}
}
enum Routing {
Static, Dynamic;
public static Routing fromValue(String type) {
if (StringUtils.isBlank(type)) {
return null;
} else if (type.equalsIgnoreCase("Static")) {
return Static;
} else if (type.equalsIgnoreCase("Dynamic")) {
return Dynamic;
} else {
throw new InvalidParameterValueException("Unexpected Routing type : " + type);
}
}
}
String updatingInSequence = "updatingInSequence";
String hideIpAddressUsage = "hideIpAddressUsage";

View File

@ -25,7 +25,7 @@ import org.apache.cloudstack.api.InternalIdentity;
public interface FirewallRule extends ControlledEntity, Identity, InternalIdentity, Displayable {
enum Purpose {
Firewall, PortForwarding, LoadBalancing, Vpn, StaticNat, NetworkACL,
Firewall, PortForwarding, LoadBalancing, Vpn, StaticNat, NetworkACL, Ipv6Firewall,
}
enum FirewallRuleType {

View File

@ -25,6 +25,7 @@ import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
import com.cloud.utils.Pair;
import com.cloud.utils.net.NetUtils;
public interface VpcProvisioningService {
@ -34,7 +35,7 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
Map<String, List<String>> serviceProviders,
Map serviceCapabilitystList,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
Long serviceOfferingId, List<Long> domainIds, List<Long> zoneIds, VpcOffering.State state);
Pair<List<? extends VpcOffering>,Integer> listVpcOfferings(ListVPCOfferingsCmd cmd);

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.offering;
import java.util.Date;
import org.apache.cloudstack.acl.InfrastructureEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
@ -23,8 +25,6 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Networks.TrafficType;
import java.util.Date;
/**
* Describes network offering
*
@ -40,7 +40,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
}
public enum Detail {
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RelatedNetworkOffering, domainid, zoneid, pvlanType
InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RelatedNetworkOffering, domainid, zoneid, pvlanType, internetProtocol
}
public final static String SystemPublicNetwork = "System-Public-Network";

View File

@ -42,6 +42,7 @@ public interface AlertService {
public static final AlertType ALERT_TYPE_STORAGE_ALLOCATED = new AlertType(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, "ALERT.STORAGE.ALLOCATED", true);
public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, "ALERT.NETWORK.PUBLICIP",
true);
public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, "ALERT.NETWORK.IPV6SUBNET", true);
public static final AlertType ALERT_TYPE_PRIVATE_IP = new AlertType(Capacity.CAPACITY_TYPE_PRIVATE_IP, "ALERT.NETWORK.PRIVATEIP", true);
public static final AlertType ALERT_TYPE_SECONDARY_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, "ALERT.STORAGE.SECONDARY", true);
public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true);

View File

@ -38,6 +38,7 @@ public class ApiConstants {
public static final String LIST_LB_VMIPS = "lbvmips";
public static final String LIVE_PATCH = "livepatch";
public static final String AVAILABLE = "available";
public static final String AVAILABLE_SUBNETS = "availablesubnets";
public static final String BACKUP_ID = "backupid";
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
public static final String BACKUP_OFFERING_ID = "backupofferingid";
@ -113,6 +114,7 @@ public class ApiConstants {
public static final String HYPERVISOR_SNAPSHOT_RESERVE = "hypervisorsnapshotreserve";
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
public static final String DESCRIPTION = "description";
public static final String DESTINATION = "destination";
public static final String DESTINATION_ZONE_ID = "destzoneid";
public static final String DETAILS = "details";
public static final String DEVICE_ID = "deviceid";
@ -205,12 +207,14 @@ public class ApiConstants {
public static final String ID = "id";
public static final String IDS = "ids";
public static final String INDEX = "index";
public static final String PREFIX = "prefix";
public static final String PREVIOUS_ACL_RULE_ID = "previousaclruleid";
public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
public static final String IMAGE_PATH = "imagepath";
public static final String INTERNAL_DNS1 = "internaldns1";
public static final String INTERNAL_DNS2 = "internaldns2";
public static final String INTERNET_PROTOCOL = "internetprotocol";
public static final String INTERVAL_TYPE = "intervaltype";
public static final String LOCATION_TYPE = "locationtype";
public static final String IOPS_READ_RATE = "iopsreadrate";
@ -238,6 +242,7 @@ public class ApiConstants {
public static final String IS_READY = "isready";
public static final String IS_RECURSIVE = "isrecursive";
public static final String ISO_FILTER = "isofilter";
public static final String ISO_ID = "isoid";
public static final String ISO_GUEST_OS_NONE = "None";
public static final String JAVA_DISTRIBUTION = "javadistribution";
public static final String JAVA_VERSION = "javaversion";
@ -385,6 +390,7 @@ public class ApiConstants {
public static final String STORAGE_POLICY = "storagepolicy";
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
public static final String SUBNET = "subnet";
public static final String OWNER = "owner";
public static final String SWAP_OWNER = "swapowner";
public static final String SYSTEM_VM_TYPE = "systemvmtype";
@ -395,15 +401,16 @@ public class ApiConstants {
public static final String TEMPLATE_ID = "templateid";
public static final String TEMPLATE_IDS = "templateids";
public static final String TEMPLATE_NAME = "templatename";
public static final String ISO_ID = "isoid";
public static final String TIMEOUT = "timeout";
public static final String TIMEZONE = "timezone";
public static final String TIMEZONEOFFSET = "timezoneoffset";
public static final String TOTAL_SUBNETS = "totalsubnets";
public static final String TYPE = "type";
public static final String TRUST_STORE = "truststore";
public static final String TRUST_STORE_PASSWORD = "truststorepass";
public static final String URL = "url";
public static final String USAGE_INTERFACE = "usageinterface";
public static final String USED_SUBNETS = "usedsubnets";
public static final String USER_DATA = "userdata";
public static final String USER_FILTER = "userfilter";
public static final String USER_ID = "userid";
@ -560,6 +567,7 @@ public class ApiConstants {
public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
public static final String LOCAL_STORAGE_ENABLED = "localstorageenabled";
public static final String GUEST_IP_TYPE = "guestiptype";
public static final String GUEST_IP6_PREFIX = "guestip6prefix";
public static final String XENSERVER_NETWORK_LABEL = "xennetworklabel";
public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
@ -602,6 +610,8 @@ public class ApiConstants {
public static final String KEYWORD = "keyword";
public static final String LIST_ALL = "listall";
public static final String IP_RANGES = "ipranges";
public static final String IPV6_ROUTING = "ip6routing";
public static final String IPV6_ROUTES = "ip6routes";
public static final String SPECIFY_IP_RANGES = "specifyipranges";
public static final String IS_SOURCE_NAT = "issourcenat";
public static final String IS_STATIC_NAT = "isstaticnat";

View File

@ -50,6 +50,7 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Ipv6Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkService;
import com.cloud.network.NetworkUsageService;
@ -207,6 +208,8 @@ public abstract class BaseCmd {
public AnnotationService annotationService;
@Inject
public ResourceIconManager resourceIconManager;
@Inject
public Ipv6Service ipv6Service;
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException, NetworkRuleConflictException;

View File

@ -22,20 +22,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.cloud.server.ResourceIcon;
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;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.management.ManagementServerHost;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
@ -49,6 +35,7 @@ import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.BackupScheduleResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
@ -56,6 +43,9 @@ import org.apache.cloudstack.api.response.ConditionResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
import org.apache.cloudstack.api.response.CounterResponse;
import org.apache.cloudstack.api.response.CreateCmdResponse;
import org.apache.cloudstack.api.response.DataCenterGuestIpv6PrefixResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
@ -67,6 +57,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;
@ -84,6 +75,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.NicResponse;
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
@ -100,8 +92,11 @@ import org.apache.cloudstack.api.response.ProviderResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
import org.apache.cloudstack.api.response.ResourceCountResponse;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.ResourceLimitResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
@ -125,7 +120,6 @@ import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
import org.apache.cloudstack.api.response.UsageRecordResponse;
import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.VMSnapshotResponse;
import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
@ -134,10 +128,14 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.backup.Backup;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.backup.BackupSchedule;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.management.ManagementServerHost;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
@ -148,6 +146,7 @@ import com.cloud.capacity.Capacity;
import com.cloud.configuration.ResourceCount;
import com.cloud.configuration.ResourceLimit;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.Pod;
import com.cloud.dc.StorageNetworkIpRange;
import com.cloud.dc.Vlan;
@ -201,6 +200,8 @@ import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
import com.cloud.projects.ProjectInvitation;
import com.cloud.region.ha.GlobalLoadBalancerRule;
import com.cloud.resource.RollingMaintenanceManager;
import com.cloud.server.ResourceIcon;
import com.cloud.server.ResourceTag;
import com.cloud.storage.GuestOS;
import com.cloud.storage.GuestOSHypervisor;
@ -216,6 +217,7 @@ import com.cloud.user.SSHKeyPair;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.net.Ip;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.Nic;
@ -284,6 +286,8 @@ public interface ResponseGenerator {
ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon);
DataCenterGuestIpv6PrefixResponse createDataCenterGuestIpv6PrefixResponse(DataCenterGuestIpv6Prefix prefix);
VolumeResponse createVolumeResponse(ResponseView view, Volume volume);
InstanceGroupResponse createInstanceGroupResponse(InstanceGroup group);
@ -512,4 +516,6 @@ public interface ResponseGenerator {
DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(DirectDownloadManager.HostCertificateStatus status);
DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair<Boolean, String> result);
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
}

View File

@ -0,0 +1,115 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.network;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiArgValidator;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DataCenterGuestIpv6PrefixResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.log4j.Logger;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
@APICommand(name = CreateGuestNetworkIpv6PrefixCmd.APINAME,
description = "Creates a guest network IPv6 prefix.",
responseObject = DataCenterGuestIpv6PrefixResponse.class,
since = "4.17.0.0",
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false,
authorized = {RoleType.Admin})
public class CreateGuestNetworkIpv6PrefixCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(CreateGuestNetworkIpv6PrefixCmd.class);
public static final String APINAME = "createGuestNetworkIpv6Prefix";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
description = "UUID of zone to which the IPv6 prefix belongs to.",
validations = {ApiArgValidator.PositiveNumber})
private Long zoneId;
@Parameter(name = ApiConstants.PREFIX,
type = CommandType.STRING,
required = true,
description = "The /56 or higher IPv6 CIDR for network prefix.")
private String prefix;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public String getPrefix() {
return prefix;
}
@Override
public String getEventType() {
return EventTypes.EVENT_GUEST_IP6_PREFIX_CREATE;
}
@Override
public String getEventDescription() {
return "Creating guest IPv6 prefix " + getPrefix() + " for zone=" + getZoneId();
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
DataCenterGuestIpv6Prefix result = _configService.createDataCenterGuestIpv6Prefix(this);
if (result != null) {
DataCenterGuestIpv6PrefixResponse response = _responseGenerator.createDataCenterGuestIpv6PrefixResponse(result);
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create zone guest IPv6 prefix.");
}
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseAsyncCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -89,7 +89,7 @@ public class CreateManagementNetworkIpRangeCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.VLAN,
type = CommandType.STRING,
description = "Optional. The vlan id the ip range sits on, default to Null when it is not specificed which means you network is not on any Vlan")
description = "Optional. The vlan id the ip range sits on, default to Null when it is not specified which means you network is not on any Vlan")
private String vlan;
/////////////////////////////////////////////////////

View File

@ -92,6 +92,12 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, required = true, description = "guest type of the network offering: Shared or Isolated")
private String guestIptype;
@Parameter(name = ApiConstants.INTERNET_PROTOCOL,
type = CommandType.STRING,
description = "The internet protocol of network offering. Options are ipv4 and dualstack. Default is ipv4. dualstack will create a network offering that supports both IPv4 and IPv6",
since = "4.17.0")
private String internetProtocol;
@Parameter(name = ApiConstants.SUPPORTED_SERVICES,
type = CommandType.LIST,
collectionType = CommandType.STRING,
@ -211,6 +217,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
return guestIptype;
}
public String getInternetProtocol() {
return internetProtocol;
}
public Boolean getSpecifyIpRanges() {
return specifyIpRanges == null ? false : specifyIpRanges;
}

View File

@ -0,0 +1,101 @@
// 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 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.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.DataCenterGuestIpv6PrefixResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = DeleteGuestNetworkIpv6PrefixCmd.APINAME,
description = "Deletes an existing guest network IPv6 prefix.",
responseObject = SuccessResponse.class,
since = "4.17.0.0",
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false,
authorized = {RoleType.Admin})
public class DeleteGuestNetworkIpv6PrefixCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeleteGuestNetworkIpv6PrefixCmd.class);
public static final String APINAME = "deleteGuestNetworkIpv6Prefix";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DataCenterGuestIpv6PrefixResponse.class, required = true, description = "Id of the guest network IPv6 prefix")
private Long id;
public Long getId() {
return id;
}
@Override
public String getEventType() {
return EventTypes.EVENT_GUEST_IP6_PREFIX_DELETE;
}
@Override
public String getEventDescription() {
return "Deleting guest IPv6 prefix " + getId();
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
boolean result = _configService.deleteDataCenterGuestIpv6Prefix(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete guest network IPv6 prefix:" + getId());
}
} catch (InvalidParameterValueException ex) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage());
} catch (CloudRuntimeException ex) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -0,0 +1,88 @@
// 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.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.DataCenterGuestIpv6PrefixResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
@APICommand(name = ListGuestNetworkIpv6PrefixesCmd.APINAME,
description = "Lists guest network IPv6 prefixes",
responseObject = DataCenterGuestIpv6PrefixResponse.class,
since = "4.17.0",
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false)
public class ListGuestNetworkIpv6PrefixesCmd extends BaseListCmd {
public static final String APINAME = "listGuestNetworkIpv6Prefixes";
@Parameter(name = ApiConstants.ID,
type = CommandType.UUID,
entityType = DataCenterGuestIpv6PrefixResponse.class,
description = "UUID of the IPv6 prefix.")
private Long id;
@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
description = "UUID of zone to which the IPv6 prefix belongs to.")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Long getZoneId() {
return zoneId;
}
@Override
public void execute() {
List<? extends DataCenterGuestIpv6Prefix> prefixes = _configService.listDataCenterGuestIpv6Prefixes(this);
ListResponse<DataCenterGuestIpv6PrefixResponse> response = new ListResponse<>();
List<DataCenterGuestIpv6PrefixResponse> prefixResponses = new ArrayList<>();
for (DataCenterGuestIpv6Prefix prefix : prefixes) {
DataCenterGuestIpv6PrefixResponse prefixResponse = _responseGenerator.createDataCenterGuestIpv6PrefixResponse(prefix);
prefixResponse.setObjectName("guestnetworkipv6prefix");
prefixResponses.add(prefixResponse);
}
response.setResponses(prefixResponses, prefixes.size());
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
}

View File

@ -72,7 +72,13 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
private Map<String, ? extends Map<String, String>> serviceProviderList;
@Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of vpc offering", since = "4.4")
private Map<String, List<String>> serviceCapabilitystList;
private Map<String, List<String>> serviceCapabilityList;
@Parameter(name = ApiConstants.INTERNET_PROTOCOL,
type = CommandType.STRING,
description = "The internet protocol of the offering. Options are ipv4 and dualstack. Default is ipv4. dualstack will create an offering that supports both IPv4 and IPv6",
since = "4.17.0")
private String internetProtocol;
@Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
type = CommandType.UUID,
@ -145,8 +151,12 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
return serviceProviderMap;
}
public Map<String, List<String>> getServiceCapabilitystList() {
return serviceCapabilitystList;
public Map<String, List<String>> getServiceCapabilityList() {
return serviceCapabilityList;
}
public String getInternetProtocol() {
return internetProtocol;
}
public Long getServiceOfferingId() {

View File

@ -0,0 +1,255 @@
// 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.ipv6;
import java.util.ArrayList;
import java.util.List;
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.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.FirewallResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.rules.FirewallRule;
import com.cloud.user.Account;
import com.cloud.utils.net.NetUtils;
@APICommand(name = CreateIpv6FirewallRuleCmd.APINAME, description = "Creates an Ipv6 firewall rule in the given network (the network has to belong to VPC)", responseObject = FirewallRuleResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateIpv6FirewallRuleCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreateIpv6FirewallRuleCmd.class.getName());
public static final String APINAME = "createIpv6FirewallRule";
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the Ipv6 firewall rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
private String protocol;
@Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of Ipv6 firewall rule")
private Integer publicStartPort;
@Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of Ipv6 firewall rule")
private Integer publicEndPort;
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the source CIDR list to allow traffic from. Multiple entries must be separated by a single comma character (,).")
private List<String> sourceCidrList;
@Parameter(name = ApiConstants.DEST_CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the destination CIDR list to allow traffic to. Multiple entries must be separated by a single comma character (,).")
private List<String> destinationCidrlist;
@Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
private Integer icmpType;
@Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
private Integer icmpCode;
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the Ipv6 firewall rule will be created for", required = true)
private Long networkId;
@Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the Ipv6 firewall rule, can be ingress or egress, defaulted to ingress if not specified")
private String trafficType;
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", authorized = {RoleType.Admin})
private Boolean display;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@Override
public boolean isDisplay() {
if (display != null) {
return display;
} else {
return true;
}
}
public String getProtocol() {
String p = protocol == null ? "" : protocol.trim();
if (StringUtils.isNumeric(p)) {
int protoNumber = Integer.parseInt(p);
switch (protoNumber) {
case 1:
p = NetUtils.ICMP_PROTO;
break;
case 6:
p = NetUtils.TCP_PROTO;
break;
case 17:
p = NetUtils.UDP_PROTO;
break;
default:
throw new InvalidParameterValueException(String.format("Protocol %d not supported", protoNumber));
}
}
return p;
}
public List<String> getSourceCidrList() {
if (sourceCidrList != null) {
return sourceCidrList;
} else {
List<String> oneCidrList = new ArrayList<String>();
oneCidrList.add(NetUtils.ALL_IP6_CIDRS);
return oneCidrList;
}
}
public List<String> getDestinationCidrList() {
if (destinationCidrlist != null) {
return destinationCidrlist;
} else {
List<String> oneCidrList = new ArrayList<String>();
oneCidrList.add(NetUtils.ALL_IP6_CIDRS);
return oneCidrList;
}
}
public FirewallRule.TrafficType getTrafficType() {
if (trafficType == null) {
return FirewallRule.TrafficType.Ingress;
}
for (FirewallRule.TrafficType type : FirewallRule.TrafficType.values()) {
if (type.toString().equalsIgnoreCase(trafficType)) {
return type;
}
}
throw new InvalidParameterValueException("Invalid traffic type " + trafficType);
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
public Integer getSourcePortStart() {
return publicStartPort;
}
public Integer getSourcePortEnd() {
if (publicEndPort == null) {
if (publicStartPort != null) {
return publicStartPort;
}
} else {
return publicEndPort;
}
return null;
}
public Long getNetworkId() {
return networkId;
}
@Override
public long getEntityOwnerId() {
Network network = _networkService.getNetwork(networkId);
if (network != null) {
return network.getAccountId();
}
Account owner = CallContext.current().getCallingAccount();
return owner.getAccountId();
}
@Override
public String getEventType() {
return EventTypes.EVENT_IPV6_FIREWALL_RULE_CREATE;
}
@Override
public String getEventDescription() {
return "Creating ipv6 firewall rule";
}
public Integer getIcmpCode() {
if (icmpCode != null) {
return icmpCode;
} else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
return -1;
}
return null;
}
public Integer getIcmpType() {
if (icmpType != null) {
return icmpType;
} else if (getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
return -1;
}
return null;
}
@Override
public void create() {
try {
FirewallRule result = ipv6Service.createIpv6FirewallRule(this);
setEntityId(result.getId());
setEntityUuid(result.getUuid());
} catch (NetworkRuleConflictException e) {
s_logger.trace("Network Rule Conflict: ", e);
throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, e.getMessage(), e);
}
}
@Override
public void execute() throws ResourceUnavailableException {
boolean success = false;
FirewallRule rule = ipv6Service.getIpv6FirewallRule(getEntityId());
try {
CallContext.current().setEventDetails("Rule ID: " + getEntityId());
success = ipv6Service.applyIpv6FirewallRule(rule.getId());
// State is different after the rule is applied, so get new object here
rule = ipv6Service.getIpv6FirewallRule(getEntityId());
FirewallResponse ruleResponse = new FirewallResponse();
if (rule != null) {
ruleResponse = _responseGenerator.createIpv6FirewallRuleResponse(rule);
setResponseObject(ruleResponse);
}
ruleResponse.setResponseName(getCommandName());
} finally {
if (!success || rule == null) {
ipv6Service.revokeIpv6FirewallRule(getEntityId());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create ipv6 firewall rule");
}
}
}
}

View File

@ -0,0 +1,97 @@
// 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.ipv6;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule;
import com.cloud.user.Account;
@APICommand(name = DeleteIpv6FirewallRuleCmd.APINAME, description = "Deletes a IPv6 firewall rule", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteIpv6FirewallRuleCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeleteIpv6FirewallRuleCmd.class.getName());
public static final String APINAME = "deleteIpv6FirewallRule";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = true, description = "the ID of the IPv6 firewall rule")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
@Override
public String getEventType() {
return EventTypes.EVENT_IPV6_FIREWALL_RULE_DELETE;
}
@Override
public String getEventDescription() {
return ("Deleting IPv6 firewall rule ID=" + id);
}
@Override
public long getEntityOwnerId() {
FirewallRule rule = _firewallService.getFirewallRule(id);
if (rule != null) {
return rule.getAccountId();
}
Account caller = CallContext.current().getCallingAccount();
return caller.getAccountId();
}
@Override
public void execute() throws ResourceUnavailableException {
CallContext.current().setEventDetails("IPv6 firewall rule ID: " + id);
boolean result = ipv6Service.revokeIpv6FirewallRule(id);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete IPv6 firewall rule");
}
}
}

View File

@ -0,0 +1,118 @@
// 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.ipv6;
import java.util.ArrayList;
import java.util.List;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.command.user.firewall.IListFirewallRulesCmd;
import org.apache.cloudstack.api.response.FirewallResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.log4j.Logger;
import com.cloud.network.rules.FirewallRule;
import com.cloud.utils.Pair;
@APICommand(name = ListIpv6FirewallRulesCmd.APINAME, description = "Lists all IPv6 firewall rules", responseObject = FirewallRuleResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListIpv6FirewallRulesCmd extends BaseListTaggedResourcesCmd implements IListFirewallRulesCmd {
public static final Logger s_logger = Logger.getLogger(ListIpv6FirewallRulesCmd.class.getName());
public static final String APINAME = "listIpv6FirewallRules";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class,
description = "Lists ipv6 firewall rule with the specified ID")
private Long id;
@Parameter(name = ApiConstants.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "list ipv6 firewall rules by network ID")
private Long networkId;
@Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "list ipv6 firewall rules by traffic type - ingress or egress")
private String trafficType;
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", authorized = {RoleType.Admin})
private Boolean display;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@Override
public Long getNetworkId() {
return networkId;
}
@Override
public Long getId() {
return id;
}
@Override
public FirewallRule.TrafficType getTrafficType() {
if (trafficType != null) {
return FirewallRule.TrafficType.valueOf(trafficType);
}
return null;
}
@Override
public Long getIpAddressId() {
return null;
}
@Override
public Boolean getDisplay() {
if (display != null) {
return display;
}
return super.getDisplay();
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
@Override
public void execute() {
Pair<List<? extends FirewallRule>, Integer> result = ipv6Service.listIpv6FirewallRules(this);
ListResponse<FirewallResponse> response = new ListResponse<>();
List<FirewallResponse> ruleResponses = new ArrayList<>();
for (FirewallRule rule : result.first()) {
FirewallResponse ruleData = _responseGenerator.createIpv6FirewallRuleResponse(rule);
ruleResponses.add(ruleData);
}
response.setResponses(ruleResponses, result.second());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,175 @@
// 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.ipv6;
import java.util.List;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseAsyncCustomIdCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.FirewallResponse;
import org.apache.cloudstack.api.response.FirewallRuleResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule;
import com.cloud.user.Account;
@APICommand(name = UpdateIpv6FirewallRuleCmd.APINAME, description = "Updates Ipv6 firewall rule with specified ID", responseObject = FirewallRuleResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class UpdateIpv6FirewallRuleCmd extends BaseAsyncCustomIdCmd {
public static final Logger s_logger = Logger.getLogger(UpdateIpv6FirewallRuleCmd.class.getName());
public static final String APINAME = "updateIpv6FirewallRule";
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = FirewallRuleResponse.class, required = true, description = "the ID of the ipv6 firewall rule")
private Long id;
@Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "the protocol for the Ipv6 firewall rule. Valid values are TCP/UDP/ICMP/ALL or valid protocol number")
private String protocol;
@Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, description = "the starting port of Ipv6 firewall rule")
private Integer publicStartPort;
@Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of Ipv6 firewall rule")
private Integer publicEndPort;
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to allow traffic from/to. Multiple entries must be separated by a single comma character (,).")
private List<String> cidrlist;
@Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the ICMP message being sent")
private Integer icmpType;
@Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this ICMP message")
private Integer icmpCode;
@Parameter(name = ApiConstants.TRAFFIC_TYPE, type = CommandType.STRING, description = "the traffic type for the Ipv6 firewall rule, can be Ingress or Egress, defaulted to Ingress if not specified")
private String trafficType;
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the Ipv6 firewall rule to the end user or not", since = "4.4", authorized = {
RoleType.Admin})
private Boolean display;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@Override
public boolean isDisplay() {
if (display != null) {
return display;
} else {
return true;
}
}
public Long getId() {
return id;
}
public String getProtocol() {
if (protocol != null) {
return protocol.trim();
} else {
return null;
}
}
public List<String> getSourceCidrList() {
return cidrlist;
}
public FirewallRule.TrafficType getTrafficType() {
if (trafficType != null) {
for (FirewallRule.TrafficType type : FirewallRule.TrafficType.values()) {
if (type.toString().equalsIgnoreCase(trafficType)) {
return type;
}
}
}
return null;
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
public Integer getSourcePortStart() {
return publicStartPort;
}
public Integer getSourcePortEnd() {
return publicEndPort;
}
@Override
public long getEntityOwnerId() {
FirewallRule rule = _firewallService.getFirewallRule(id);
if (rule != null) {
return rule.getAccountId();
}
Account caller = CallContext.current().getCallingAccount();
return caller.getAccountId();
}
@Override
public String getEventType() {
return EventTypes.EVENT_IPV6_FIREWALL_RULE_UPDATE;
}
@Override
public String getEventDescription() {
return "Updating ipv6 firewall rule";
}
public Integer getIcmpCode() {
return icmpCode;
}
public Integer getIcmpType() {
return icmpType;
}
@Override
public void execute() throws ResourceUnavailableException {
CallContext.current().setEventDetails("Rule Id: " + getId());
FirewallRule rules = ipv6Service.updateIpv6FirewallRule(this);
FirewallResponse ruleResponse = _responseGenerator.createIpv6FirewallRuleResponse(rules);
setResponseObject(ruleResponse);
ruleResponse.setResponseName(getCommandName());
}
@Override
public void checkUuid() {
if (this.getCustomId() != null) {
_uuidMgr.checkUuid(this.getCustomId(), FirewallRule.class);
}
}
}

View File

@ -122,6 +122,7 @@ public class CreateNetworkACLCmd extends BaseAsyncCreateCmd {
} else {
List<String> oneCidrList = new ArrayList<String>();
oneCidrList.add(NetUtils.ALL_IP4_CIDRS);
oneCidrList.add(NetUtils.ALL_IP6_CIDRS);
return oneCidrList;
}
}

View File

@ -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 java.util.Date;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@EntityReference(value = DataCenterGuestIpv6Prefix.class)
public class DataCenterGuestIpv6PrefixResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "id of the guest IPv6 prefix")
private String id;
@SerializedName(ApiConstants.PREFIX)
@Param(description = "guest IPv6 prefix")
private String prefix;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "id of zone to which the IPv6 prefix belongs to." )
private String zoneId;
@SerializedName(ApiConstants.USED_SUBNETS)
@Param(description = "count of the used IPv6 subnets for the prefix." )
private Integer usedSubnets;
@SerializedName(ApiConstants.AVAILABLE_SUBNETS)
@Param(description = "count of the available IPv6 subnets for the prefix." )
private Integer availableSubnets;
@SerializedName(ApiConstants.TOTAL_SUBNETS)
@Param(description = "count of the total IPv6 subnets for the prefix." )
private Integer totalSubnets;
@SerializedName(ApiConstants.CREATED)
@Param(description = " date when this IPv6 prefix was created." )
private Date created;
public void setId(String id) {
this.id = id;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setZoneId(String zoneId) {
this.zoneId = zoneId;
}
public void setUsedSubnets(Integer usedSubnets) {
this.usedSubnets = usedSubnets;
}
public void setAvailableSubnets(Integer availableSubnets) {
this.availableSubnets = availableSubnets;
}
public void setTotalSubnets(Integer totalSubnets) {
this.totalSubnets = totalSubnets;
}
public void setCreated(Date created) {
this.created = created;
}
}

View File

@ -83,6 +83,10 @@ public class FirewallResponse extends BaseResponse {
@Param(description = "the cidr list to forward traffic to. Multiple entries are separated by a single comma character (,).")
private String destCidr;
@SerializedName(ApiConstants.TRAFFIC_TYPE)
@Param(description = "the traffic type for the firewall rule", since = "4.17.0")
private String trafficType;
public void setId(String id) {
this.id = id;
}
@ -138,4 +142,8 @@ public class FirewallResponse extends BaseResponse {
public void setDestCidr(String cidrList){
this.destCidr = cidrList;
}
public void setTrafficType(String trafficType) {
this.trafficType = trafficType;
}
}

View File

@ -16,16 +16,23 @@
// 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 com.google.gson.annotations.SerializedName;
@SuppressWarnings("unused")
public class IpRangeResponse extends BaseResponse {
@SerializedName(ApiConstants.GATEWAY)
@Param(description = "the gateway for the range")
private String gateway;
@SerializedName(ApiConstants.CIDR)
@Param(description = "the CIDR for the range")
private String cidr;
@SerializedName(ApiConstants.START_IP)
@Param(description = "the starting IP for the range")
private String startIp;
@ -42,6 +49,22 @@ public class IpRangeResponse extends BaseResponse {
@Param(description = "indicates Vlan ID for the range")
private String vlanId;
public String getGateway() {
return gateway;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
public String getCidr() {
return cidr;
}
public void setCidr(String cidr) {
this.cidr = cidr;
}
public String getStartIp() {
return startIp;
}

View File

@ -0,0 +1,56 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.response;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class Ipv6RouteResponse extends BaseResponse {
@SerializedName(ApiConstants.SUBNET)
@Param(description = "the guest IPv6 cidr for route")
private String subnet;
@SerializedName(ApiConstants.GATEWAY)
@Param(description = "the outbound IPv6 gateway")
private String gateway;
public Ipv6RouteResponse(String subnet, String gateway) {
this.subnet = subnet;
this.gateway = gateway;
}
public String getSubnet() {
return subnet;
}
public void setSubnet(String subnet) {
this.subnet = subnet;
}
public String getGateway() {
return gateway;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
}

View File

@ -139,6 +139,10 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations {
@Param(description = "the zone name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.", since = "4.13.0")
private String zone;
@SerializedName(ApiConstants.INTERNET_PROTOCOL)
@Param(description = "the internet protocol of the network offering")
private String internetProtocol;
public void setId(String id) {
this.id = id;
}
@ -262,4 +266,12 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations {
public void setZone(String zone) {
this.zone = zone;
}
public String getInternetProtocol() {
return internetProtocol;
}
public void setInternetProtocol(String internetProtocol) {
this.internetProtocol = internetProtocol;
}
}

View File

@ -275,6 +275,20 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
@Param(description = "true if guest network default egress policy is allow; false if default egress policy is deny")
private Boolean egressDefaultPolicy;
@SerializedName(ApiConstants.INTERNET_PROTOCOL)
@Param(description = "The internet protocol of network offering")
private String internetProtocol;
@SerializedName(ApiConstants.IPV6_ROUTING)
@Param(description = "The routing mode of network offering", since = "4.17.0")
private String ipv6Routing;
@SerializedName(ApiConstants.IPV6_ROUTES)
@Param(description = "The routes for the network to ease adding route in upstream router", since = "4.17.0")
private Set<Ipv6RouteResponse> ipv6Routes;
public NetworkResponse() {}
public Boolean getDisplayNetwork() {
return displayNetwork;
}
@ -556,4 +570,20 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
public void setEgressDefaultPolicy(Boolean egressDefaultPolicy) {
this.egressDefaultPolicy = egressDefaultPolicy;
}
public void setInternetProtocol(String internetProtocol) {
this.internetProtocol = internetProtocol;
}
public void setIpv6Routing(String ipv6Routing) {
this.ipv6Routing = ipv6Routing;
}
public void setIpv6Routes(Set<Ipv6RouteResponse> ipv6Routes) {
this.ipv6Routes = ipv6Routes;
}
public void addIpv6Route(Ipv6RouteResponse ipv6Route) {
this.ipv6Routes.add(ipv6Route);
}
}

View File

@ -16,14 +16,13 @@
// 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.dc.Vlan;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
@EntityReference(value = Vlan.class)
@SuppressWarnings("unused")
@ -64,6 +63,10 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
@Param(description = "the Pod name for the VLAN IP range")
private String podName;
@SerializedName(ApiConstants.DESCRIPTION)
@Param(description = "the description of the VLAN IP range")
private String description;
@SerializedName(ApiConstants.GATEWAY)
@Param(description = "the gateway of the VLAN IP range")
private String gateway;
@ -72,9 +75,9 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
@Param(description = "the netmask of the VLAN IP range")
private String netmask;
@SerializedName(ApiConstants.DESCRIPTION)
@Param(description = "the description of the VLAN IP range")
private String description;
@SerializedName(ApiConstants.CIDR)
@Param(description = "the cidr of the VLAN IP range")
private String cidr;
@SerializedName(ApiConstants.START_IP)
@Param(description = "the start ip of the VLAN IP range")
@ -167,6 +170,10 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
this.podName = podName;
}
public void setDescription(String description) {
this.description = description;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
@ -175,8 +182,8 @@ public class VlanIpRangeResponse extends BaseResponse implements ControlledEntit
this.netmask = netmask;
}
public void setDescription(String description) {
this.description = description;
public void setCidr(String cidr) {
this.cidr = cidr;
}
public void setStartIp(String startIp) {

View File

@ -82,6 +82,10 @@ public class VpcOfferingResponse extends BaseResponse {
@Param(description = "the zone name(s) this disk offering belongs to. Ignore this information as it is not currently applicable.", since = "4.13.0")
private String zone;
@SerializedName(ApiConstants.INTERNET_PROTOCOL)
@Param(description = "the internet protocol of the vpc offering")
private String internetProtocol;
public void setId(String id) {
this.id = id;
}
@ -149,4 +153,12 @@ public class VpcOfferingResponse extends BaseResponse {
public void setZone(String zone) {
this.zone = zone;
}
public String getInternetProtocol() {
return internetProtocol;
}
public void setInternetProtocol(String internetProtocol) {
this.internetProtocol = internetProtocol;
}
}

View File

@ -18,6 +18,7 @@ package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
@ -131,6 +132,10 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
ResourceIconResponse icon;
@SerializedName(ApiConstants.IPV6_ROUTES)
@Param(description = "The routes for the network to ease adding route in upstream router", since = "4.17.0")
private Set<Ipv6RouteResponse> ipv6Routes;
public void setId(final String id) {
this.id = id;
}
@ -244,4 +249,8 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
public void setResourceIconResponse(ResourceIconResponse icon) {
this.icon = icon;
}
public void setIpv6Routes(Set<Ipv6RouteResponse> ipv6Routes) {
this.ipv6Routes = ipv6Routes;
}
}

View File

@ -19,7 +19,7 @@
package org.apache.cloudstack.diagnostics;
public enum DiagnosticsType {
PING("ping"), TRACEROUTE("traceroute"), ARPING("arping");
PING("ping"), PING6("ping6"), TRACEROUTE("traceroute"), TRACEROUTE6("traceroute6"), ARPING("arping");
private String value;

View File

@ -27,9 +27,14 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
String networkDomain;
String defaultDns1 = null;
String defaultDns2 = null;
String defaultIp6Dns1 = null;
String defaultIp6Dns2 = null;
boolean isRedundant = false;
boolean add = true;
NicTO nic;
String routerIpv6 = null;
String routerIpv6Gateway = null;
String routerIpv6Cidr = null;
public NicTO getNic() {
return nic;
@ -43,6 +48,14 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
return defaultDns2;
}
public String getDefaultIp6Dns1() {
return defaultIp6Dns1;
}
public String getDefaultIp6Dns2() {
return defaultIp6Dns2;
}
public String getNetworkDomain() {
return networkDomain;
}
@ -69,4 +82,36 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
this.add = add;
this.nic = nic;
}
public String getRouterIpv6() {
return routerIpv6;
}
public void setRouterIpv6(String routerIpv6) {
this.routerIpv6 = routerIpv6;
}
public String getRouterIpv6Gateway() {
return routerIpv6Gateway;
}
public void setRouterIpv6Gateway(String routerIpv6Gateway) {
this.routerIpv6Gateway = routerIpv6Gateway;
}
public String getRouterIpv6Cidr() {
return routerIpv6Cidr;
}
public void setRouterIpv6Cidr(String routerIpv6Cidr) {
this.routerIpv6Cidr = routerIpv6Cidr;
}
public void setDefaultIp6Dns1(String defaultIp6Dns1) {
this.defaultIp6Dns1 = defaultIp6Dns1;
}
public void setDefaultIp6Dns2(String defaultIp6Dns2) {
this.defaultIp6Dns2 = defaultIp6Dns2;
}
}

View File

@ -0,0 +1,39 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.routing;
import com.cloud.agent.api.Answer;
public class SetIpv6FirewallRulesAnswer extends Answer {
String[] results;
protected SetIpv6FirewallRulesAnswer() {
}
public SetIpv6FirewallRulesAnswer(SetIpv6FirewallRulesCommand cmd, boolean success, String[] results) {
super(cmd, success, null);
assert (cmd.getRules().length == results.length) : "rules and their results should be the same length don't you think?";
this.results = results;
}
public String[] getResults() {
return results;
}
}

View File

@ -0,0 +1,49 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.api.routing;
import java.util.List;
import com.cloud.agent.api.to.FirewallRuleTO;
/**
*
* AccessDetails allow different components to put in information about
* how to access the components inside the command.
*/
public class SetIpv6FirewallRulesCommand extends NetworkElementCommand {
FirewallRuleTO[] rules;
protected SetIpv6FirewallRulesCommand() {
}
public SetIpv6FirewallRulesCommand(List<FirewallRuleTO> rules) {
this.rules = rules.toArray(new FirewallRuleTO[rules.size()]);
}
public FirewallRuleTO[] getRules() {
return rules;
}
@Override
public int getAnswersCount() {
return rules.length;
}
}

View File

@ -26,8 +26,11 @@ import java.util.List;
import com.cloud.agent.api.to.NetworkACLTO;
import com.cloud.agent.api.to.NicTO;
import com.cloud.utils.net.NetUtils;
public class SetNetworkACLCommand extends NetworkElementCommand {
public static final String RULE_DETAIL_SEPARATOR = ";";
NetworkACLTO[] rules;
NicTO nic;
@ -58,7 +61,8 @@ public class SetNetworkACLCommand extends NetworkElementCommand {
if (aclTO.revoked() == true) {
final StringBuilder sb = new StringBuilder();
/* This entry is added just to make sure atleast there will one entry in the list to get the ipaddress */
sb.append(aclTO.getTrafficType().toString()).append(":reverted:0:0:0:");
List<String> revertRuleItems = Arrays.asList("", "reverted", "0", "0", "0", "");
sb.append(aclTO.getTrafficType().toString()).append(String.join(RULE_DETAIL_SEPARATOR, revertRuleItems));
final String aclRuleEntry = sb.toString();
result[0][i++] = aclRuleEntry;
continue;
@ -66,15 +70,15 @@ public class SetNetworkACLCommand extends NetworkElementCommand {
List<String> cidr;
final StringBuilder sb = new StringBuilder();
sb.append(aclTO.getTrafficType().toString()).append(":").append(aclTO.getProtocol()).append(":");
sb.append(aclTO.getTrafficType().toString()).append(RULE_DETAIL_SEPARATOR).append(aclTO.getProtocol()).append(RULE_DETAIL_SEPARATOR);
if ("icmp".compareTo(aclTO.getProtocol()) == 0) {
sb.append(aclTO.getIcmpType()).append(":").append(aclTO.getIcmpCode()).append(":");
sb.append(aclTO.getIcmpType()).append(RULE_DETAIL_SEPARATOR).append(aclTO.getIcmpCode()).append(RULE_DETAIL_SEPARATOR);
} else {
sb.append(aclTO.getStringPortRange()).append(":");
sb.append(aclTO.getStringPortRange().replace(":", RULE_DETAIL_SEPARATOR)).append(RULE_DETAIL_SEPARATOR);
}
cidr = aclTO.getSourceCidrList();
if (cidr == null || cidr.isEmpty()) {
sb.append("0.0.0.0/0");
sb.append(String.format("%s,%s", NetUtils.ALL_IP4_CIDRS, NetUtils.ALL_IP6_CIDRS));
} else {
Boolean firstEntry = true;
for (final String tag : cidr) {
@ -85,7 +89,7 @@ public class SetNetworkACLCommand extends NetworkElementCommand {
firstEntry = false;
}
}
sb.append(":").append(aclTO.getAction()).append(":");
sb.append(RULE_DETAIL_SEPARATOR).append(aclTO.getAction()).append(RULE_DETAIL_SEPARATOR);
final String aclRuleEntry = sb.toString();
result[0][i++] = aclRuleEntry;
}

View File

@ -31,6 +31,7 @@ public class VRScripts {
public final static String VM_PASSWORD_CONFIG = "vm_password.json";
public static final String FORWARDING_RULES_CONFIG = "forwarding_rules.json";
public static final String FIREWALL_RULES_CONFIG = "firewall_rules.json";
public static final String IPV6_FIREWALL_RULES_CONFIG = "ipv6_firewall_rules.json";
public static final String VPN_USER_LIST_CONFIG = "vpn_user_list.json";
public static final String STATICNAT_RULES_CONFIG = "staticnat_rules.json";
public static final String SITE_2_SITE_VPN_CONFIG = "site_2_site_vpn.json";

View File

@ -23,6 +23,7 @@ import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import org.apache.log4j.Logger;
import com.cloud.agent.api.BumpUpPriorityCommand;
@ -38,6 +39,7 @@ import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesCommand;
import com.cloud.agent.api.routing.SetMonitorServiceCommand;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
@ -84,6 +86,7 @@ public abstract class AbstractConfigItemFacade {
flyweight.put(DeleteIpAliasCommand.class, new DeleteIpAliasConfigItem());
flyweight.put(VmDataCommand.class, new VmDataConfigItem());
flyweight.put(SetFirewallRulesCommand.class, new SetFirewallRulesConfigItem());
flyweight.put(SetIpv6FirewallRulesCommand.class, new SetIpv6FirewallRulesConfigItem());
flyweight.put(BumpUpPriorityCommand.class, new BumpUpPriorityConfigItem());
flyweight.put(RemoteAccessVpnCfgCommand.class, new RemoteAccessVpnConfigItem());
flyweight.put(VpnUsersCfgCommand.class, new VpnUsersConfigItem());

View File

@ -21,6 +21,8 @@ package com.cloud.agent.resource.virtualnetwork.facade;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.cloud.agent.api.SetupGuestNetworkCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.to.NicTO;
@ -53,8 +55,28 @@ public class SetGuestNetworkConfigItem extends AbstractConfigItemFacade {
}
}
String dns6 = command.getDefaultIp6Dns1();
if (StringUtils.isEmpty(dns6)) {
dns6 = command.getDefaultIp6Dns2();
} else {
final String dns2 = command.getDefaultIp6Dns2();
if (StringUtils.isNotEmpty(dns2)) {
dns6 += "," + dns2;
}
}
final GuestNetwork guestNetwork = new GuestNetwork(command.isAdd(), nic.getMac(), "eth" + nic.getDeviceId(), routerGIP, netmask, gateway,
cidr, dns, domainName);
cidr, dns, dns6, domainName);
guestNetwork.setRouterGuestIp6(nic.getIp6Address());
guestNetwork.setRouterGuestIp6Gateway(nic.getIp6Gateway());
guestNetwork.setRouterGuestIp6Cidr(nic.getIp6Cidr());
if (nic.getIp6Cidr() != null) {
guestNetwork.setCidr6(String.valueOf(NetUtils.getIp6CidrSize(nic.getIp6Cidr())));
}
guestNetwork.setRouterIp6(command.getRouterIpv6());
guestNetwork.setRouterIp6Gateway(command.getRouterIpv6Gateway());
guestNetwork.setRouterIp6Cidr(command.getRouterIpv6Cidr());
return generateConfigItems(guestNetwork);
}

View File

@ -0,0 +1,59 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
package com.cloud.agent.resource.virtualnetwork.facade;
import java.util.ArrayList;
import java.util.List;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesCommand;
import com.cloud.agent.api.to.FirewallRuleTO;
import com.cloud.agent.resource.virtualnetwork.ConfigItem;
import com.cloud.agent.resource.virtualnetwork.VRScripts;
import com.cloud.agent.resource.virtualnetwork.model.ConfigBase;
import com.cloud.agent.resource.virtualnetwork.model.FirewallRule;
import com.cloud.agent.resource.virtualnetwork.model.FirewallRules;
public class SetIpv6FirewallRulesConfigItem extends AbstractConfigItemFacade{
@Override
public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
final SetIpv6FirewallRulesCommand command = (SetIpv6FirewallRulesCommand) cmd;
final List<FirewallRule> rules = new ArrayList<FirewallRule>();
for (final FirewallRuleTO rule : command.getRules()) {
final FirewallRule fwRule = new FirewallRule(rule.getId(), rule.getSrcVlanTag(), rule.getSrcIp(), rule.getProtocol(), rule.getSrcPortRange(), rule.revoked(),
rule.isAlreadyAdded(), rule.getSourceCidrList(), rule.getDestCidrList(), rule.getPurpose().toString(), rule.getIcmpType(), rule.getIcmpCode(), rule.getTrafficType().toString(),
rule.getGuestCidr(), rule.isDefaultEgressPolicy());
rules.add(fwRule);
}
final FirewallRules ruleSet = new FirewallRules(rules.toArray(new FirewallRule[rules.size()]));
ruleSet.setType(ConfigBase.IPV6_FIREWALL_RULES);
return generateConfigItems(ruleSet);
}
@Override
protected List<ConfigItem> generateConfigItems(final ConfigBase configuration) {
destinationFile = VRScripts.IPV6_FIREWALL_RULES_CONFIG;
return super.generateConfigItems(configuration);
}
}

View File

@ -60,7 +60,7 @@ public class SetNetworkAclConfigItem extends AbstractConfigItemFacade {
for (int i = 0; i < aclRules.length; i++) {
AclRule aclRule;
final String[] ruleParts = aclRules[i].split(":");
final String[] ruleParts = aclRules[i].split(SetNetworkACLCommand.RULE_DETAIL_SEPARATOR);
switch (ruleParts[1].toLowerCase()) {
case "icmp":
aclRule = new IcmpAclRule(ruleParts[4], "ACCEPT".equals(ruleParts[5]), Integer.parseInt(ruleParts[2]), Integer.parseInt(ruleParts[3]));
@ -94,7 +94,7 @@ public class SetNetworkAclConfigItem extends AbstractConfigItemFacade {
final NetworkACL networkACL = new NetworkACL(dev, nic.getMac(), privateGw != null, nic.getIp(), netmask, ingressRules.toArray(new AclRule[ingressRules.size()]),
egressRules.toArray(new AclRule[egressRules.size()]));
networkACL.setNicIp6Cidr(nic.getIp6Cidr());
return generateConfigItems(networkACL);
}

View File

@ -29,6 +29,7 @@ public abstract class ConfigBase {
public static final String VM_PASSWORD = "vmpassword";
public static final String FORWARDING_RULES = "forwardrules";
public static final String FIREWALL_RULES = "firewallrules";
public static final String IPV6_FIREWALL_RULES = "ipv6firewallrules";
public static final String VPN_USER_LIST = "vpnuserlist";
public static final String STATICNAT_RULES = "staticnatrules";
public static final String IP_ALIAS_CONFIG = "ipaliases";

View File

@ -27,15 +27,23 @@ public class GuestNetwork extends ConfigBase {
private String routerGuestNetmask;
private String routerGuestGateway;
private String cidr;
private String cidr6;
private String dns;
private String dns6;
private String domainName;
private String routerGuestIp6;
private String routerGuestIp6Gateway;
private String routerGuestIp6Cidr;
private String routerIp6;
private String routerIp6Gateway;
private String routerIp6Cidr;
public GuestNetwork() {
super(ConfigBase.GUEST_NETWORK);
}
public GuestNetwork(final boolean add, final String macAddress, final String device, final String routerGuestIp, final String routerGuestNetmask, final String routerGuestGateway,
final String cidr, final String dns, final String domainName) {
final String cidr, final String dns, final String dns6, final String domainName) {
super(ConfigBase.GUEST_NETWORK);
this.add = add;
this.macAddress = macAddress;
@ -45,6 +53,7 @@ public class GuestNetwork extends ConfigBase {
this.routerGuestGateway = routerGuestGateway;
this.cidr = cidr;
this.dns = dns;
this.dns6 = dns6;
this.domainName = domainName;
}
@ -104,6 +113,14 @@ public class GuestNetwork extends ConfigBase {
this.cidr = cidr;
}
public String getCidr6() {
return cidr6;
}
public void setCidr6(String cidr6) {
this.cidr6 = cidr6;
}
public String getDns() {
return dns;
}
@ -112,6 +129,14 @@ public class GuestNetwork extends ConfigBase {
this.dns = dns;
}
public String getDns6() {
return dns6;
}
public void setDns6(String dns6) {
this.dns6 = dns6;
}
public String getDomainName() {
return domainName;
}
@ -119,4 +144,52 @@ public class GuestNetwork extends ConfigBase {
public void setDomainName(final String domainName) {
this.domainName = domainName;
}
public String getRouterGuestIp6() {
return routerGuestIp6;
}
public void setRouterGuestIp6(String routerGuestIp6) {
this.routerGuestIp6 = routerGuestIp6;
}
public String getRouterGuestIp6Gateway() {
return routerGuestIp6Gateway;
}
public void setRouterGuestIp6Gateway(String routerGuestIp6Gateway) {
this.routerGuestIp6Gateway = routerGuestIp6Gateway;
}
public String getRouterGuestIp6Cidr() {
return routerGuestIp6Cidr;
}
public void setRouterGuestIp6Cidr(String routerGuestIp6Cidr) {
this.routerGuestIp6Cidr = routerGuestIp6Cidr;
}
public String getRouterIp6() {
return routerIp6;
}
public void setRouterIp6(String routerIp6) {
this.routerIp6 = routerIp6;
}
public String getRouterIp6Gateway() {
return routerIp6Gateway;
}
public void setRouterIp6Gateway(String routerIp6Gateway) {
this.routerIp6Gateway = routerIp6Gateway;
}
public String getRouterIp6Cidr() {
return routerIp6Cidr;
}
public void setRouterIp6Cidr(String routerIp6Cidr) {
this.routerIp6Cidr = routerIp6Cidr;
}
}

View File

@ -25,6 +25,7 @@ public class NetworkACL extends ConfigBase {
private boolean privateGatewayAcl;
private String nicIp;
private String nicNetmask;
private String nicIp6Cidr;
private AclRule[] ingressRules;
private AclRule[] egressRules;
@ -83,6 +84,14 @@ public class NetworkACL extends ConfigBase {
this.nicNetmask = nicNetmask;
}
public String getNicIp6Cidr() {
return nicIp6Cidr;
}
public void setNicIp6Cidr(String nicIp6Cidr) {
this.nicIp6Cidr = nicIp6Cidr;
}
public AclRule[] getIngressRules() {
return ingressRules;
}

View File

@ -277,6 +277,8 @@ public interface NetworkOrchestrationService {
Nic savePlaceholderNic(Network network, String ip4Address, String ip6Address, Type vmType);
Nic savePlaceholderNic(Network network, String ip4Address, String ip6Address, String ip6Cidr, String ip6Gateway, String reserver, Type vmType);
DhcpServiceProvider getDhcpServiceProvider(Network network);
DnsServiceProvider getDnsServiceProvider(Network network);

View File

@ -41,6 +41,12 @@ public interface AlertManager extends Manager, AlertService {
public static final ConfigKey<String> AlertSmtpEnabledSecurityProtocols = new ConfigKey<String>("Advanced", String.class, "alert.smtp.enabledSecurityProtocols", "",
"White-space separated security protocols; ex: \"TLSv1 TLSv1.1\". Supported protocols: SSLv2Hello, SSLv3, TLSv1, TLSv1.1 and TLSv1.2", true);
public static final ConfigKey<Double> Ipv6SubnetCapacityThreshold = new ConfigKey<Double>("Advanced", Double.class,
"zone.virtualnetwork.ipv6subnet.capacity.notificationthreshold",
"0.75",
"Percentage (as a value between 0 and 1) of guest network IPv6 subnet utilization above which alerts will be sent.",
true);
void clearAlert(AlertType alertType, long dataCenterId, long podId);
void recalculateCapacity();

View File

@ -42,6 +42,7 @@ import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.org.Grouping.AllocationState;
import com.cloud.user.Account;
import com.cloud.utils.net.NetUtils;
/**
* ConfigurationManager handles adding pods/zones, changing IP ranges, enabling external firewalls, and editing
@ -214,7 +215,8 @@ public interface ConfigurationManager {
NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability,
Integer networkRate, Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId,
boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent,
Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc, List<Long> domainIds, List<Long> zoneIds, boolean enableOffering);
Map<NetworkOffering.Detail, String> details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc,
List<Long> domainIds, List<Long> zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol);
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP,
String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr)
@ -252,7 +254,7 @@ public interface ConfigurationManager {
* @throws
* @throws
*/
Pod editPod(long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr);
Pod editPod(long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationState);
void checkPodCidrSubnets(long zoneId, Long podIdToBeSkipped, String cidr);

View File

@ -109,7 +109,7 @@ public interface VpcManager {
Network
createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner,
Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, long vpcId, Long aclId, Account caller,
Boolean displayNetworkEnabled, String externalId)
Boolean displayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;

View File

@ -55,7 +55,9 @@ 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.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -116,6 +118,7 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.IpAddress;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Ipv6Service;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Event;
@ -156,6 +159,7 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.RemoteAccessVpnVO;
import com.cloud.network.dao.RouterNetworkDao;
import com.cloud.network.element.AggregatedCommandExecutor;
import com.cloud.network.element.ConfigDriveNetworkElement;
import com.cloud.network.element.DhcpServiceProvider;
@ -169,6 +173,7 @@ import com.cloud.network.element.UserDataServiceProvider;
import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallManager;
@ -244,7 +249,7 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.commons.lang3.StringUtils;
import com.googlecode.ipv6.IPv6Address;
/**
* NetworkManagerImpl implements NetworkManager.
@ -324,6 +329,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public ManagementServer mgr;
@Inject
NetworkPermissionDao networkPermissionDao;
@Inject
Ipv6Service ipv6Service;
@Inject
RouterNetworkDao routerNetworkDao;
List<NetworkGuru> networkGurus;
@ -482,21 +491,21 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true, Network.GuestType.Shared, false, null, true, null, true,
false, null, false, null, true, false, null, null, true);
false, null, false, null, true, false, null, null, true, null);
}
//#2 - SG enabled network offering
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks",
TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true,
null, true, false, null, false, null, true, false, null, null, true);
null, true, false, null, false, null, true, false, null, null, true, null);
}
//#3 - shared network offering with no SG service
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true,
Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false,
null, true, false, null, null, true);
null, true, false, null, null, true, null);
}
//#4 - default isolated offering with Source nat service
@ -504,14 +513,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
"Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null,
defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null,
true, false, null, null, true);
true, false, null, null, true, null);
}
//#5 - default vpc offering with LB service
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
"Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null,
defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true);
defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true, null);
}
//#6 - default vpc offering with no LB service
@ -520,14 +529,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
defaultVPCOffProviders.remove(Service.Lb);
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
"Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional,
null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true);
null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true, null);
}
//#7 - isolated offering with source nat disabled
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service",
TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null,
true, null, true, false, null, false, null, true, false, null, null, true);
true, null, true, false, null, false, null, true, false, null, null, true, null);
}
//#8 - network offering with internal lb service
@ -549,7 +558,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB,
"Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders,
true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true);
true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, null, null, true, null);
offering.setInternalLb(true);
offering.setPublicLb(false);
_networkOfferingDao.update(offering.getId(), offering);
@ -580,7 +589,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) {
offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
"Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null,
netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, null, null, true);
netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, null, null, true, null);
offering.setDedicatedLB(false);
_networkOfferingDao.update(offering.getId(), offering);
}
@ -2348,6 +2357,25 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
s_logger.debug("Removed nic id=" + nic.getId());
// release assigned IPv6 for Isolated Network VR NIC
if (Type.DomainRouter.equals(vm.getType()) && PublicNetworkGuru.class.getSimpleName().equals(nic.getReserver())
&& StringUtils.isNotEmpty(nic.getIPv6Address())) {
List<Long> routerNetworks = routerNetworkDao.getRouterNetworks(vm.getId());
if (CollectionUtils.isNotEmpty(routerNetworks)) {
Network guestNetwork = _networksDao.findById(routerNetworks.get(0));
ipv6Service.releasePublicIpv6ForNic(guestNetwork, nic.getIPv6Address());
}
}
if (Type.User.equals(vm.getType()) && GuestType.Isolated.equals(network.getGuestType())
&& _networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId()) && StringUtils.isNotEmpty(nic.getIPv6Address())) {
final boolean usageHidden = networkDetailsDao.isNetworkUsageHidden(network.getId());
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP6_RELEASE, network.getAccountId(), network.getDataCenterId(), 0L,
nic.getIPv6Address(), false, Vlan.VlanType.VirtualNetwork.toString(), false, usageHidden,
IPv6Address.class.getName(), null);
}
//remove the secondary ip addresses corresponding to to this nic
if (!removeVmSecondaryIpsOfNic(nic.getId())) {
s_logger.debug("Removing nic " + nic.getId() + " secondary ip addreses failed");
@ -3125,6 +3153,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
throw new CloudRuntimeException("Failed to delete network " + networkFinal + "; was unable to cleanup corresponding ip ranges");
} else {
// commit transaction only when ips and vlans for the network are released successfully
ipv6Service.releaseIpv6SubnetForNetwork(networkId);
ipv6Service.removePublicIpv6PlaceholderNics(networkFinal);
try {
stateTransitTo(networkFinal, Event.DestroyNetwork);
} catch (final NoTransitionException e) {
@ -4343,10 +4374,20 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Override
public NicVO savePlaceholderNic(final Network network, final String ip4Address, final String ip6Address, final Type vmType) {
return savePlaceholderNic(network, ip4Address, ip6Address, null, null, null, vmType);
}
@Override
public NicVO savePlaceholderNic(final Network network, final String ip4Address, final String ip6Address, final String ip6Cidr, final String ip6Gateway, final String reserver, final Type vmType) {
final NicVO nic = new NicVO(null, null, network.getId(), null);
nic.setIPv4Address(ip4Address);
nic.setIPv6Address(ip6Address);
nic.setIPv6Cidr(ip6Cidr);
nic.setIPv6Gateway(ip6Gateway);
nic.setReservationStrategy(ReservationStrategy.PlaceHolder);
if (reserver != null) {
nic.setReserver(reserver);
}
nic.setState(Nic.State.Reserved);
nic.setVmType(vmType);
return _nicDao.persist(nic);

View File

@ -241,6 +241,7 @@ public class CapacityVO implements Capacity {
capacityNames.put(CAPACITY_TYPE_LOCAL_STORAGE, "LOCAL_STORAGE");
capacityNames.put(CAPACITY_TYPE_GPU, "GPU");
capacityNames.put(CAPACITY_TYPE_CPU_CORE, "CPU_CORE");
capacityNames.put(CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, "VIRTUAL_NETWORK_IPV6_SUBNET");
}
public static String getCapacityName (Short capacityType) {

View File

@ -0,0 +1,99 @@
// 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.dc;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.db.GenericDao;
@Entity
@Table(name = "dc_ip6_guest_prefix")
public class DataCenterGuestIpv6PrefixVO implements DataCenterGuestIpv6Prefix {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "uuid")
String uuid;
@Column(name = "data_center_id")
private long dataCenterId;
@Column(name = "prefix")
private String prefix;
@Column(name = GenericDao.CREATED_COLUMN)
private Date created;
@Column(name= GenericDao.REMOVED_COLUMN)
private Date removed;
public DataCenterGuestIpv6PrefixVO(long dcId, String prefix) {
this();
this.dataCenterId = dcId;
this.prefix = prefix;
this.created = new Date();
}
protected DataCenterGuestIpv6PrefixVO() {
this.uuid = UUID.randomUUID().toString();
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
}
@Override
public Long getDataCenterId() {
return dataCenterId;
}
public void setDataCenterId(long dcId) {
this.dataCenterId = dcId;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
@Override
public Date getCreated() {
return created;
}
}

View File

@ -0,0 +1,28 @@
// 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.dc.dao;
import java.util.List;
import com.cloud.dc.DataCenterGuestIpv6PrefixVO;
import com.cloud.utils.db.GenericDao;
public interface DataCenterGuestIpv6PrefixDao extends GenericDao<DataCenterGuestIpv6PrefixVO, Long> {
List<DataCenterGuestIpv6PrefixVO> listByDataCenterId(long dcId);
}

View File

@ -0,0 +1,43 @@
// 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.dc.dao;
import java.util.List;
import org.springframework.stereotype.Component;
import com.cloud.dc.DataCenterGuestIpv6PrefixVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
@DB
public class DataCenterGuestIpv6PrefixDaoImpl extends GenericDaoBase<DataCenterGuestIpv6PrefixVO, Long> implements DataCenterGuestIpv6PrefixDao {
public DataCenterGuestIpv6PrefixDaoImpl() {
}
@Override
public List<DataCenterGuestIpv6PrefixVO> listByDataCenterId(long dcId) {
QueryBuilder<DataCenterGuestIpv6PrefixVO> sc = QueryBuilder.create(DataCenterGuestIpv6PrefixVO.class);
sc.and(sc.entity().getDataCenterId(), SearchCriteria.Op.EQ, dcId);
return sc.list();
}
}

View File

@ -60,4 +60,8 @@ public interface VlanDao extends GenericDao<VlanVO, Long> {
List<VlanVO> listVlansByNetworkIdAndGateway(long networkid, String gateway);
List<VlanVO> listDedicatedVlans(long accountId);
List<VlanVO> listIpv6RangeByPhysicalNetworkIdAndVlanId(long physicalNetworkId, String vlanId);
List<VlanVO> listIpv6SupportingVlansByZone(long zoneId);
}

View File

@ -26,6 +26,8 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import com.cloud.dc.AccountVlanMapVO;
@ -62,6 +64,9 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
protected SearchBuilder<VlanVO> ZoneWideNonDedicatedVlanSearch;
protected SearchBuilder<VlanVO> VlanGatewaysearch;
protected SearchBuilder<VlanVO> DedicatedVlanSearch;
protected SearchBuilder<VlanVO> PhysicalNetworkVlanIp6Search;
protected SearchBuilder<VlanVO> ZoneIp6Search;
protected SearchBuilder<VlanVO> ZoneVlansSearch;
protected SearchBuilder<AccountVlanMapVO> AccountVlanMapSearch;
protected SearchBuilder<DomainVlanMapVO> DomainVlanMapSearch;
@ -255,6 +260,23 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
DedicatedVlanSearch.done();
AccountVlanMapSearch.done();
PhysicalNetworkVlanIp6Search = createSearchBuilder();
PhysicalNetworkVlanIp6Search.and("physicalNetworkId", PhysicalNetworkVlanIp6Search.entity().getPhysicalNetworkId(), SearchCriteria.Op.EQ);
PhysicalNetworkVlanIp6Search.and("vlanId", PhysicalNetworkVlanIp6Search.entity().getVlanTag(), SearchCriteria.Op.EQ);
PhysicalNetworkVlanIp6Search.and("ip6Gateway", PhysicalNetworkVlanIp6Search.entity().getIp6Gateway(), SearchCriteria.Op.NNULL);
PhysicalNetworkVlanIp6Search.and("ip6Cidr", PhysicalNetworkVlanIp6Search.entity().getIp6Cidr(), SearchCriteria.Op.NNULL);
PhysicalNetworkVlanIp6Search.done();
ZoneIp6Search = createSearchBuilder();
ZoneIp6Search.and("zoneId", ZoneIp6Search.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneIp6Search.and("ip6Gateway", ZoneIp6Search.entity().getIp6Gateway(), SearchCriteria.Op.NNULL);
ZoneIp6Search.and("ip6Cidr", ZoneIp6Search.entity().getIp6Cidr(), SearchCriteria.Op.NNULL);
ZoneIp6Search.done();
ZoneVlansSearch = createSearchBuilder();
ZoneVlansSearch.and("zoneId", ZoneVlansSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
ZoneVlansSearch.and("vlan", ZoneVlansSearch.entity().getVlanTag(), SearchCriteria.Op.IN);
ZoneVlansSearch.done();
return result;
}
@ -387,4 +409,29 @@ public class VlanDaoImpl extends GenericDaoBase<VlanVO, Long> implements VlanDao
return listBy(sc);
}
@Override
public List<VlanVO> listIpv6RangeByPhysicalNetworkIdAndVlanId(long physicalNetworkId, String vlanId) {
SearchCriteria<VlanVO> sc = PhysicalNetworkVlanIp6Search.create();
sc.setParameters("physicalNetworkId", physicalNetworkId);
if(StringUtils.isNotEmpty(vlanId)) {
sc.setParameters("vlanId", vlanId);
}
return listBy(sc);
}
@Override
public List<VlanVO> listIpv6SupportingVlansByZone(long zoneId) {
SearchCriteria<VlanVO> sc = ZoneIp6Search.create();
sc.setParameters("zoneId", zoneId);
List<VlanVO> vlanVOS = listBy(sc);
Object[] vlanIds = vlanVOS.stream().map(VlanVO::getVlanTag).toArray();
if (ArrayUtils.isEmpty(vlanIds)) {
return new ArrayList<>();
}
sc = ZoneVlansSearch.create();
sc.setParameters("zoneId", zoneId);
sc.setParameters("vlan", vlanIds);
return listBy(sc);
}
}

View File

@ -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 com.cloud.network;
import java.util.Date;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.cloud.utils.db.GenericDao;
@Entity
@Table(name = "ip6_guest_prefix_subnet_network_map")
public class Ipv6GuestPrefixSubnetNetworkMapVO implements Ipv6GuestPrefixSubnetNetworkMap {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
long id;
@Column(name = "uuid")
private String uuid;
@Column(name = "prefix_id")
private Long prefixId;
@Column(name = "subnet")
private String subnet;
@Column(name = "network_id")
private Long networkId;
@Column(name = "state")
private State state;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated")
Date updated;
@Column(name = GenericDao.CREATED_COLUMN)
private Date created;
@Column(name= GenericDao.REMOVED_COLUMN)
private Date removed;
protected Ipv6GuestPrefixSubnetNetworkMapVO() {
uuid = UUID.randomUUID().toString();
}
protected Ipv6GuestPrefixSubnetNetworkMapVO(long prefixId, String subnet, Long networkId, Ipv6GuestPrefixSubnetNetworkMap.State state) {
this.prefixId = prefixId;
this.subnet = subnet;
this.networkId = networkId;
this.state = state;
uuid = UUID.randomUUID().toString();
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
}
@Override
public long getPrefixId() {
return prefixId;
}
@Override
public String getSubnet() {
return subnet;
}
@Override
public Long getNetworkId() {
return networkId;
}
public void setNetworkId(Long networkId) {
this.networkId = networkId;
}
@Override
public State getState() {
return state;
}
public void setState(Ipv6GuestPrefixSubnetNetworkMap.State state) {
this.state = state;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public Date getUpdated() {
return updated;
}
public Date getCreated() {
return created;
}
}

View File

@ -0,0 +1,33 @@
// 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.dao;
import java.util.List;
import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMap;
import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMapVO;
import com.cloud.utils.db.GenericDao;
public interface Ipv6GuestPrefixSubnetNetworkMapDao extends GenericDao<Ipv6GuestPrefixSubnetNetworkMapVO, Long> {
List<Ipv6GuestPrefixSubnetNetworkMapVO> listUsedByPrefix(long prefixId);
Ipv6GuestPrefixSubnetNetworkMapVO findFirstAvailable(long prefixId);
Ipv6GuestPrefixSubnetNetworkMapVO findByNetworkId(long networkId);
Ipv6GuestPrefixSubnetNetworkMapVO findBySubnet(String subnet);
List<Ipv6GuestPrefixSubnetNetworkMapVO> findPrefixesInStates(Ipv6GuestPrefixSubnetNetworkMap.State... states);
void deleteByPrefixId(long prefixId);
}

View File

@ -0,0 +1,111 @@
// 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.dao;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMap;
import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMapVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
@DB
public class Ipv6GuestPrefixSubnetNetworkMapDaoImpl extends GenericDaoBase<Ipv6GuestPrefixSubnetNetworkMapVO, Long> implements Ipv6GuestPrefixSubnetNetworkMapDao {
protected SearchBuilder<Ipv6GuestPrefixSubnetNetworkMapVO> PrefixStateSearch;
protected SearchBuilder<Ipv6GuestPrefixSubnetNetworkMapVO> PrefixIdSearch;
protected SearchBuilder<Ipv6GuestPrefixSubnetNetworkMapVO> NetworkIdSearch;
protected SearchBuilder<Ipv6GuestPrefixSubnetNetworkMapVO> SubnetSearch;
protected SearchBuilder<Ipv6GuestPrefixSubnetNetworkMapVO> StatesSearch;
@PostConstruct
public void init() {
PrefixStateSearch = createSearchBuilder();
PrefixStateSearch.and("prefixId", PrefixStateSearch.entity().getPrefixId(), SearchCriteria.Op.EQ);
PrefixStateSearch.and("state", PrefixStateSearch.entity().getState(), SearchCriteria.Op.IN);
PrefixStateSearch.done();
PrefixIdSearch = createSearchBuilder();
PrefixIdSearch.and("prefixId", PrefixIdSearch.entity().getPrefixId(), SearchCriteria.Op.EQ);
PrefixIdSearch.done();
NetworkIdSearch = createSearchBuilder();
NetworkIdSearch.and("networkId", NetworkIdSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
NetworkIdSearch.done();
SubnetSearch = createSearchBuilder();
SubnetSearch.and("subnet", SubnetSearch.entity().getSubnet(), SearchCriteria.Op.EQ);
SubnetSearch.done();
StatesSearch = createSearchBuilder();
StatesSearch.and("state", StatesSearch.entity().getState(), SearchCriteria.Op.IN);
StatesSearch.done();
}
@Override
public List<Ipv6GuestPrefixSubnetNetworkMapVO> listUsedByPrefix(long prefixId) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = PrefixStateSearch.create();
sc.setParameters("prefixId", prefixId);
sc.setParameters("state", (Object[]) new Ipv6GuestPrefixSubnetNetworkMap.State[]{Ipv6GuestPrefixSubnetNetworkMap.State.Allocated, Ipv6GuestPrefixSubnetNetworkMap.State.Allocating});
Filter searchFilter = new Filter(Ipv6GuestPrefixSubnetNetworkMapVO.class, "id", true, null, 1L);
return listBy(sc, searchFilter);
}
@Override
public Ipv6GuestPrefixSubnetNetworkMapVO findFirstAvailable(long prefixId) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = PrefixStateSearch.create();
sc.setParameters("prefixId", prefixId);
sc.setParameters("state", (Object[]) new Ipv6GuestPrefixSubnetNetworkMap.State[]{Ipv6GuestPrefixSubnetNetworkMap.State.Free});
Filter searchFilter = new Filter(Ipv6GuestPrefixSubnetNetworkMapVO.class, "id", true, null, 1L);
List<Ipv6GuestPrefixSubnetNetworkMapVO> list = listBy(sc, searchFilter);
return CollectionUtils.isNotEmpty(list) ? list.get(0) : null;
}
@Override
public Ipv6GuestPrefixSubnetNetworkMapVO findByNetworkId(long networkId) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = NetworkIdSearch.create();
sc.setParameters("networkId", networkId);
return findOneBy(sc);
}
@Override
public Ipv6GuestPrefixSubnetNetworkMapVO findBySubnet(String subnet) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = SubnetSearch.create();
sc.setParameters("subnet", subnet);
return findOneBy(sc);
}
@Override
public List<Ipv6GuestPrefixSubnetNetworkMapVO> findPrefixesInStates(Ipv6GuestPrefixSubnetNetworkMap.State... states) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = StatesSearch.create();
sc.setParameters("state", (Object[])states);
return listBy(sc);
}
@Override
public void deleteByPrefixId(long prefixId) {
SearchCriteria<Ipv6GuestPrefixSubnetNetworkMapVO> sc = PrefixIdSearch.create();
sc.setParameters("prefixId", prefixId);
remove(sc);
}
}

View File

@ -21,5 +21,5 @@ import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
import com.cloud.utils.db.GenericDao;
public interface NetworkDetailsDao extends GenericDao<NetworkDetailVO, Long>, ResourceDetailsDao<NetworkDetailVO> {
boolean isNetworkUsageHidden(long networkId);
}

View File

@ -21,6 +21,8 @@ import org.springframework.stereotype.Component;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import com.cloud.network.Network;
@Component
public class NetworkDetailsDaoImpl extends ResourceDetailsDaoBase<NetworkDetailVO> implements NetworkDetailsDao {
@ -29,4 +31,9 @@ public class NetworkDetailsDaoImpl extends ResourceDetailsDaoBase<NetworkDetailV
super.addDetail(new NetworkDetailVO(resourceId, key, value, display));
}
@Override
public boolean isNetworkUsageHidden(long networkId) {
NetworkDetailVO networkDetail = findDetail(networkId, Network.hideIpAddressUsage);
return networkDetail != null && "true".equals(networkDetail.getValue());
}
}

View File

@ -549,9 +549,7 @@ public class NetworkVO implements Network {
@Override
public String toString() {
StringBuilder buf = new StringBuilder("Ntwk[");
buf.append(id).append("|").append(trafficType).append("|").append(networkOfferingId).append("]");
return buf.toString();
return String.format("Network {\"id\": %s, \"name\": \"%s\", \"uuid\": \"%s\", \"networkofferingid\": %d}", id, name, uuid, networkOfferingId);
}
@Override

View File

@ -18,6 +18,7 @@ package com.cloud.network.vpc.dao;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils;
public interface VpcOfferingDao extends GenericDao<VpcOfferingVO, Long> {
/**
@ -28,4 +29,8 @@ public interface VpcOfferingDao extends GenericDao<VpcOfferingVO, Long> {
* @return VpcOfferingVO
*/
VpcOfferingVO findByUniqueName(String uniqueName);
NetUtils.InternetProtocol getVpcOfferingInternetProtocol(long offeringId);
boolean isIpv6Supported(long offeringId);
}

View File

@ -17,6 +17,9 @@
package com.cloud.network.vpc.dao;
import javax.inject.Inject;
import org.apache.cloudstack.api.ApiConstants;
import org.springframework.stereotype.Component;
import com.cloud.network.vpc.VpcOfferingVO;
@ -26,12 +29,16 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.net.NetUtils;
@Component
@DB()
public class VpcOfferingDaoImpl extends GenericDaoBase<VpcOfferingVO, Long> implements VpcOfferingDao {
final SearchBuilder<VpcOfferingVO> AllFieldsSearch;
@Inject
VpcOfferingDetailsDao detailsDao;
protected VpcOfferingDaoImpl() {
super();
@ -65,4 +72,16 @@ public class VpcOfferingDaoImpl extends GenericDaoBase<VpcOfferingVO, Long> impl
sc.setParameters("uName", uniqueName);
return findOneBy(sc);
}
@Override
public NetUtils.InternetProtocol getVpcOfferingInternetProtocol(long offeringId) {
String internetProtocolStr = detailsDao.getDetail(offeringId, ApiConstants.INTERNET_PROTOCOL);
return NetUtils.InternetProtocol.fromValue(internetProtocolStr);
}
@Override
public boolean isIpv6Supported(long offeringId) {
NetUtils.InternetProtocol internetProtocol = getVpcOfferingInternetProtocol(offeringId);
return NetUtils.InternetProtocol.isIpv6EnabledProtocol(internetProtocol);
}
}

View File

@ -27,4 +27,5 @@ import com.cloud.utils.db.GenericDao;
public interface VpcOfferingDetailsDao extends GenericDao<VpcOfferingDetailsVO, Long>, ResourceDetailsDao<VpcOfferingDetailsVO> {
List<Long> findDomainIds(final long resourceId);
List<Long> findZoneIds(final long resourceId);
String getDetail(long offeringId, String detailName);
}

View File

@ -22,10 +22,23 @@ import java.util.List;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.apache.commons.collections.CollectionUtils;
import com.cloud.network.vpc.VpcOfferingDetailsVO;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
public class VpcOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<VpcOfferingDetailsVO> implements VpcOfferingDetailsDao {
private final SearchBuilder<VpcOfferingDetailsVO> ValueSearch;
public VpcOfferingDetailsDaoImpl() {
ValueSearch = createSearchBuilder();
ValueSearch.select(null, SearchCriteria.Func.DISTINCT, ValueSearch.entity().getValue());
ValueSearch.and("resourceId", ValueSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
ValueSearch.and("name", ValueSearch.entity().getName(), SearchCriteria.Op.EQ);
ValueSearch.and("display", ValueSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
ValueSearch.done();
}
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
@ -55,4 +68,17 @@ public class VpcOfferingDetailsDaoImpl extends ResourceDetailsDaoBase<VpcOfferin
}
return zoneIds;
}
@Override
public String getDetail(long offeringId, String detailName) {
SearchCriteria<VpcOfferingDetailsVO> sc = ValueSearch.create();
sc.setParameters("name", detailName);
sc.setParameters("resourceId", offeringId);
List<VpcOfferingDetailsVO> results = search(sc, null);
if (CollectionUtils.isEmpty(results)) {
return null;
} else {
return results.get(0).getValue();
}
}
}

View File

@ -26,6 +26,7 @@ import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils;
/**
* NetworkOfferingDao deals with searches and operations done on the
@ -69,4 +70,8 @@ public interface NetworkOfferingDao extends GenericDao<NetworkOfferingVO, Long>
* Create default L2 network offerings
*/
void persistDefaultL2NetworkOfferings();
NetUtils.InternetProtocol getNetworkOfferingInternetProtocol(long offeringId);
boolean isIpv6Supported(long offeringId);
}

View File

@ -42,6 +42,7 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.net.NetUtils;
@Component
@DB()
@ -51,6 +52,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
final SearchBuilder<NetworkOfferingVO> AvailabilitySearch;
final SearchBuilder<NetworkOfferingVO> AllFieldsSearch;
private final GenericSearchBuilder<NetworkOfferingVO, Long> UpgradeSearch;
@Inject
NetworkOfferingDetailsDao _detailsDao;
@Inject
@ -269,4 +271,16 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
"Offering for L2 networks with config drive user data VLAN",
true, true);
}
@Override
public NetUtils.InternetProtocol getNetworkOfferingInternetProtocol(long offeringId) {
String internetProtocolStr = _detailsDao.getDetail(offeringId, NetworkOffering.Detail.internetProtocol);
return NetUtils.InternetProtocol.fromValue(internetProtocolStr);
}
@Override
public boolean isIpv6Supported(long offeringId) {
NetUtils.InternetProtocol internetProtocol = getNetworkOfferingInternetProtocol(offeringId);
return NetUtils.InternetProtocol.isIpv6EnabledProtocol(internetProtocol);
}
}

View File

@ -88,4 +88,6 @@ public interface NicDao extends GenericDao<NicVO, Long> {
List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword);
NicVO findByInstanceIdAndMacAddress(long instanceId, String macAddress);
List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, String ipv6Cidr, String reserverName);
}

View File

@ -70,6 +70,8 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
AllFieldsSearch.and("reserverName",AllFieldsSearch.entity().getReserver(),Op.EQ);
AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.EQ);
AllFieldsSearch.and("deviceid", AllFieldsSearch.entity().getDeviceId(), Op.EQ);
AllFieldsSearch.and("ipv6Gateway", AllFieldsSearch.entity().getIPv6Gateway(), Op.EQ);
AllFieldsSearch.and("ipv6Cidr", AllFieldsSearch.entity().getIPv6Cidr(), Op.EQ);
AllFieldsSearch.done();
IpSearch = createSearchBuilder(String.class);
@ -372,4 +374,13 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
sc.setParameters("macAddress", macAddress);
return findOneBy(sc);
}
@Override
public List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, String ipv6Cidr, String reserverName) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("ipv6Gateway", ipv6Gateway);
sc.setParameters("ipv6Cidr", ipv6Cidr);
sc.setParameters("reserverName", reserverName);
return listBy(sc);
}
}

View File

@ -108,6 +108,7 @@
<bean id="hostTagsDaoImpl" class="com.cloud.host.dao.HostTagsDaoImpl" />
<bean id="hostTransferMapDaoImpl" class="com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl" />
<bean id="iPAddressDaoImpl" class="com.cloud.network.dao.IPAddressDaoImpl" />
<bean id="ip6GuestPrefixSubnetNetworkMapDaoImpl" class="com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDaoImpl" />
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
<bean id="imageStoreJoinDaoImpl" class="com.cloud.api.query.dao.ImageStoreJoinDaoImpl" />
@ -199,6 +200,7 @@
<bean id="snapshotScheduleDaoImpl" class="com.cloud.storage.dao.SnapshotScheduleDaoImpl" />
<bean id="sslCertDao" class="com.cloud.network.dao.SslCertDaoImpl" />
<bean id="staticRouteDaoImpl" class="com.cloud.network.vpc.dao.StaticRouteDaoImpl" />
<bean id="dataCenterGuestIpv6PrefixDaoImpl" class="com.cloud.dc.dao.DataCenterGuestIpv6PrefixDaoImpl" />
<bean id="storageNetworkIpAddressDaoImpl" class="com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl" />
<bean id="storageNetworkIpRangeDaoImpl" class="com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl" />
<bean id="storagePoolDetailsDaoImpl" class="com.cloud.storage.dao.StoragePoolDetailsDaoImpl" />

View File

@ -700,6 +700,145 @@ CREATE VIEW `cloud`.`domain_router_view` AS
and async_job.instance_type = 'DomainRouter'
and async_job.job_status = 0;
-- For IPv6 guest prefixes.
CREATE TABLE `cloud`.`dc_ip6_guest_prefix` (
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
`uuid` varchar(40) DEFAULT NULL,
`data_center_id` bigint(20) unsigned NOT NULL COMMENT 'zone it belongs to',
`prefix` varchar(255) NOT NULL COMMENT 'prefix of the ipv6 network',
`created` datetime default NULL,
`removed` datetime default NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_dc_ip6_guest_prefix__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`),
CONSTRAINT `uc_dc_ip6_guest_prefix__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`ip6_guest_prefix_subnet_network_map` (
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
`uuid` varchar(40) DEFAULT NULL,
`prefix_id` bigint(20) unsigned NOT NULL COMMENT 'ip6 guest prefix to which subnet belongs to',
`subnet` varchar(255) NOT NULL COMMENT 'subnet of the ipv6 network',
`network_id` bigint(20) unsigned DEFAULT NULL COMMENT 'network to which subnet is associated to',
`state` varchar(255) NOT NULL COMMENT 'state of the subnet network',
`updated` datetime default NULL,
`created` datetime default NULL,
`removed` datetime default NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_ip6_guest_prefix_subnet_network_map__prefix_id` FOREIGN KEY (`prefix_id`) REFERENCES `dc_ip6_guest_prefix`(`id`),
CONSTRAINT `fk_ip6_guest_prefix_subnet_network_map__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
CONSTRAINT `uc_ip6_guest_prefix_subnet_network_map__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Network offering with internet protocol
DROP VIEW IF EXISTS `cloud`.`network_offering_view`;
CREATE VIEW `cloud`.`network_offering_view` AS
SELECT
`network_offerings`.`id` AS `id`,
`network_offerings`.`uuid` AS `uuid`,
`network_offerings`.`name` AS `name`,
`network_offerings`.`unique_name` AS `unique_name`,
`network_offerings`.`display_text` AS `display_text`,
`network_offerings`.`nw_rate` AS `nw_rate`,
`network_offerings`.`mc_rate` AS `mc_rate`,
`network_offerings`.`traffic_type` AS `traffic_type`,
`network_offerings`.`tags` AS `tags`,
`network_offerings`.`system_only` AS `system_only`,
`network_offerings`.`specify_vlan` AS `specify_vlan`,
`network_offerings`.`service_offering_id` AS `service_offering_id`,
`network_offerings`.`conserve_mode` AS `conserve_mode`,
`network_offerings`.`created` AS `created`,
`network_offerings`.`removed` AS `removed`,
`network_offerings`.`default` AS `default`,
`network_offerings`.`availability` AS `availability`,
`network_offerings`.`dedicated_lb_service` AS `dedicated_lb_service`,
`network_offerings`.`shared_source_nat_service` AS `shared_source_nat_service`,
`network_offerings`.`sort_key` AS `sort_key`,
`network_offerings`.`redundant_router_service` AS `redundant_router_service`,
`network_offerings`.`state` AS `state`,
`network_offerings`.`guest_type` AS `guest_type`,
`network_offerings`.`elastic_ip_service` AS `elastic_ip_service`,
`network_offerings`.`eip_associate_public_ip` AS `eip_associate_public_ip`,
`network_offerings`.`elastic_lb_service` AS `elastic_lb_service`,
`network_offerings`.`specify_ip_ranges` AS `specify_ip_ranges`,
`network_offerings`.`inline` AS `inline`,
`network_offerings`.`is_persistent` AS `is_persistent`,
`network_offerings`.`internal_lb` AS `internal_lb`,
`network_offerings`.`public_lb` AS `public_lb`,
`network_offerings`.`egress_default_policy` AS `egress_default_policy`,
`network_offerings`.`concurrent_connections` AS `concurrent_connections`,
`network_offerings`.`keep_alive_enabled` AS `keep_alive_enabled`,
`network_offerings`.`supports_streched_l2` AS `supports_streched_l2`,
`network_offerings`.`supports_public_access` AS `supports_public_access`,
`network_offerings`.`for_vpc` AS `for_vpc`,
`network_offerings`.`service_package_id` AS `service_package_id`,
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name,
`offering_details`.value AS internet_protocol
FROM
`cloud`.`network_offerings`
LEFT JOIN
`cloud`.`network_offering_details` AS `domain_details` ON `domain_details`.`network_offering_id` = `network_offerings`.`id` AND `domain_details`.`name`='domainid'
LEFT JOIN
`cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
LEFT JOIN
`cloud`.`network_offering_details` AS `zone_details` ON `zone_details`.`network_offering_id` = `network_offerings`.`id` AND `zone_details`.`name`='zoneid'
LEFT JOIN
`cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
LEFT JOIN
`cloud`.`network_offering_details` AS `offering_details` ON `offering_details`.`network_offering_id` = `network_offerings`.`id` AND `offering_details`.`name`='internetProtocol'
GROUP BY
`network_offerings`.`id`;
-- VPC offering with multi-domains and multi-zones
DROP VIEW IF EXISTS `cloud`.`vpc_offering_view`;
CREATE VIEW `cloud`.`vpc_offering_view` AS
SELECT
`vpc_offerings`.`id` AS `id`,
`vpc_offerings`.`uuid` AS `uuid`,
`vpc_offerings`.`name` AS `name`,
`vpc_offerings`.`unique_name` AS `unique_name`,
`vpc_offerings`.`display_text` AS `display_text`,
`vpc_offerings`.`state` AS `state`,
`vpc_offerings`.`default` AS `default`,
`vpc_offerings`.`created` AS `created`,
`vpc_offerings`.`removed` AS `removed`,
`vpc_offerings`.`service_offering_id` AS `service_offering_id`,
`vpc_offerings`.`supports_distributed_router` AS `supports_distributed_router`,
`vpc_offerings`.`supports_region_level_vpc` AS `supports_region_level_vpc`,
`vpc_offerings`.`redundant_router_service` AS `redundant_router_service`,
`vpc_offerings`.`sort_key` AS `sort_key`,
GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name,
`offering_details`.value AS internet_protocol
FROM
`cloud`.`vpc_offerings`
LEFT JOIN
`cloud`.`vpc_offering_details` AS `domain_details` ON `domain_details`.`offering_id` = `vpc_offerings`.`id` AND `domain_details`.`name`='domainid'
LEFT JOIN
`cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
LEFT JOIN
`cloud`.`vpc_offering_details` AS `zone_details` ON `zone_details`.`offering_id` = `vpc_offerings`.`id` AND `zone_details`.`name`='zoneid'
LEFT JOIN
`cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
LEFT JOIN
`cloud`.`vpc_offering_details` AS `offering_details` ON `offering_details`.`offering_id` = `vpc_offerings`.`id` AND `offering_details`.`name`='internetprotocol'
GROUP BY
`vpc_offerings`.`id`;
-- Allow storing IPv6 CIDRs
ALTER TABLE `cloud`.`firewall_rules_cidrs` MODIFY COLUMN `source_cidr` varchar(43) DEFAULT NULL;
ALTER TABLE `cloud`.`firewall_rules_dcidrs` MODIFY COLUMN `destination_cidr` varchar(43) DEFAULT NULL;
--
-- Management Server Status
--

View File

@ -36,6 +36,7 @@ import com.cloud.agent.api.routing.IpAssocCommand;
import com.cloud.agent.api.routing.IpAssocVpcCommand;
import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesCommand;
import com.cloud.agent.api.routing.SetNetworkACLAnswer;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
@ -58,6 +59,8 @@ public interface MockNetworkManager extends Manager {
Answer SetFirewallRules(SetFirewallRulesCommand cmd);
Answer SetIpv6FirewallRules(SetIpv6FirewallRulesCommand cmd);
Answer getNetworkUsage(NetworkUsageCommand cmd);
Answer IpAssoc(IpAssocCommand cmd);

View File

@ -43,6 +43,8 @@ import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesAnswer;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesCommand;
import com.cloud.agent.api.routing.SetNetworkACLAnswer;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
@ -96,6 +98,16 @@ public class MockNetworkManagerImpl extends ManagerBase implements MockNetworkMa
return new SetFirewallRulesAnswer(cmd, true, results);
}
@Override
public SetIpv6FirewallRulesAnswer SetIpv6FirewallRules(SetIpv6FirewallRulesCommand cmd) {
String[] results = new String[cmd.getRules().length];
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
if (routerIp == null) {
return new SetIpv6FirewallRulesAnswer(cmd, false, results);
}
return new SetIpv6FirewallRulesAnswer(cmd, true, results);
}
@Override
public NetworkUsageAnswer getNetworkUsage(NetworkUsageCommand cmd) {
return new NetworkUsageAnswer(cmd, null, 100L, 100L);

View File

@ -26,20 +26,16 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import org.apache.cloudstack.ca.SetupCertificateCommand;
import org.apache.cloudstack.ca.SetupKeyStoreCommand;
import org.apache.cloudstack.diagnostics.DiagnosticsCommand;
import org.apache.cloudstack.storage.command.DeleteCommand;
import org.apache.cloudstack.storage.command.DownloadCommand;
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
import org.apache.cloudstack.storage.command.UploadStatusCommand;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.AttachIsoCommand;
@ -102,6 +98,7 @@ import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
import com.cloud.agent.api.routing.SetIpv6FirewallRulesCommand;
import com.cloud.agent.api.routing.SetMonitorServiceCommand;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
@ -139,6 +136,8 @@ import com.cloud.utils.db.DB;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine.PowerState;
import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
@Component
public class SimulatorManagerImpl extends ManagerBase implements SimulatorManager, PluggableService {
@ -313,6 +312,8 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage
answer = _mockNetworkMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd);
} else if (cmd instanceof SetFirewallRulesCommand) {
answer = _mockNetworkMgr.SetFirewallRules((SetFirewallRulesCommand)cmd);
} else if (cmd instanceof SetIpv6FirewallRulesCommand) {
answer = _mockNetworkMgr.SetIpv6FirewallRules((SetIpv6FirewallRulesCommand)cmd);
} else if (cmd instanceof SetPortForwardingRulesCommand) {
answer = _mockNetworkMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd);
} else if (cmd instanceof NetworkUsageCommand) {

View File

@ -34,15 +34,6 @@ import java.util.TimerTask;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import net.juniper.contrail.api.ApiConnector;
import net.juniper.contrail.api.ApiConnectorFactory;
import net.juniper.contrail.api.ApiPropertyBase;
import net.juniper.contrail.api.ObjectReference;
import net.juniper.contrail.api.types.FloatingIp;
import net.juniper.contrail.api.types.FloatingIpPool;
import net.juniper.contrail.api.types.NetworkPolicy;
import net.juniper.contrail.api.types.VirtualNetwork;
import org.apache.cloudstack.network.contrail.model.FloatingIpModel;
import org.apache.cloudstack.network.contrail.model.FloatingIpPoolModel;
import org.apache.cloudstack.network.contrail.model.ModelController;
@ -99,6 +90,15 @@ import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.google.common.collect.ImmutableList;
import net.juniper.contrail.api.ApiConnector;
import net.juniper.contrail.api.ApiConnectorFactory;
import net.juniper.contrail.api.ApiPropertyBase;
import net.juniper.contrail.api.ObjectReference;
import net.juniper.contrail.api.types.FloatingIp;
import net.juniper.contrail.api.types.FloatingIpPool;
import net.juniper.contrail.api.types.NetworkPolicy;
import net.juniper.contrail.api.types.VirtualNetwork;
public class ContrailManagerImpl extends ManagerBase implements ContrailManager {
@Inject
public ConfigurationService _configService;
@ -219,7 +219,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
ConfigurationManager configMgr = (ConfigurationManager) _configService;
NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText,
TrafficType.Public, null, true, Availability.Optional, null, serviceProviderMap, true,
Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, null, null, true);
Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, null, null, true, null);
long id = voffer.getId();
_networkOfferingDao.update(id, voffer);
return _networkOfferingDao.findById(id);
@ -254,7 +254,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
ConfigurationManager configMgr = (ConfigurationManager)_configService;
NetworkOfferingVO voffer =
configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true,
Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), null, null, true);
Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), null, null, true, null);
if (offeringName.equals(vpcRouterOfferingName)) {
voffer.setInternalLb(true);
}
@ -295,7 +295,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
}
serviceProviderMap.put(svc, providerSet);
}
vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, null, VpcOffering.State.Enabled);
vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, null, null, VpcOffering.State.Enabled);
long id = vpcOffer.getId();
_vpcOffDao.update(id, (VpcOfferingVO)vpcOffer);
return _vpcOffDao.findById(id);

View File

@ -34,6 +34,7 @@ addVlan() {
if [ ! -d /sys/class/net/$vlanDev ]
then
ip link add link $pif name $vlanDev type vlan id $vlanId > /dev/null
echo 1 > /proc/sys/net/ipv6/conf/$vlanDev/disable_ipv6
ip link set $vlanDev up
if [ $? -gt 0 ]
@ -47,12 +48,15 @@ addVlan() {
fi
fi
# disable IPv6
echo 1 > /proc/sys/net/ipv6/conf/$vlanDev/disable_ipv6
# is up?
ip link set $vlanDev up > /dev/null 2>/dev/null
if [ ! -d /sys/class/net/$vlanBr ]
then
ip link add name $vlanBr type bridge
echo 1 > /proc/sys/net/ipv6/conf/$vlanBr/disable_ipv6
ip link set $vlanBr up
if [ $? -gt 0 ]
@ -80,6 +84,8 @@ addVlan() {
fi
fi
fi
# disable IPv6
echo 1 > /proc/sys/net/ipv6/conf/$vlanBr/disable_ipv6
# is vlanBr up?
ip link set $vlanBr up > /dev/null 2>/dev/null

View File

@ -21,8 +21,10 @@ import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -38,6 +40,11 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextTimerTask;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.utils.mailing.MailAddress;
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;
import com.cloud.alert.dao.AlertDao;
@ -64,22 +71,17 @@ import com.cloud.event.AlertGenerator;
import com.cloud.event.EventTypes;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.network.Ipv6Service;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.org.Grouping.AllocationState;
import com.cloud.resource.ResourceManager;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.StorageManager;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.SearchCriteria;
import java.util.HashSet;
import java.util.Set;
import org.apache.cloudstack.utils.mailing.MailAddress;
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.math.NumberUtils;
public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
protected Logger logger = Logger.getLogger(AlertManagerImpl.class.getName());
@ -119,6 +121,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
protected ConfigDepot _configDepot;
@Inject
ServiceOfferingDao _offeringsDao;
@Inject
Ipv6Service ipv6Service;
private Timer _timer = null;
private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default.
@ -196,6 +200,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
_capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VLAN, _vlanCapacityThreshold);
_capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, _directNetworkPublicIpCapacityThreshold);
_capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_LOCAL_STORAGE, _localStorageCapacityThreshold);
_capacityTypeThresholdMap.put(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, Ipv6SubnetCapacityThreshold.value());
String capacityCheckPeriodStr = configs.get("capacity.check.period");
if (capacityCheckPeriodStr != null) {
@ -314,6 +319,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
// Calculate new Public IP capacity for Virtual Network
if (datacenter.getNetworkType() == NetworkType.Advanced) {
createOrUpdateIpCapacity(dcId, null, Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, datacenter.getAllocationState());
createOrUpdateIpv6Capacity(dcId, datacenter.getAllocationState());
}
// Calculate new Public IP capacity for Direct Attached Network
@ -416,6 +422,31 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
}
}
public void createOrUpdateIpv6Capacity(Long dcId, AllocationState capacityState) {
final short capacityType = Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET;
SearchCriteria<CapacityVO> capacitySC = _capacityDao.createSearchCriteria();
capacitySC.addAnd("dataCenterId", SearchCriteria.Op.EQ, dcId);
capacitySC.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
List<CapacityVO> capacities = _capacityDao.search(capacitySC, null);
Pair<Integer, Integer> usedTotal = ipv6Service.getUsedTotalIpv6SubnetForZone(dcId);
int total = usedTotal.second();
int allocated = usedTotal.first();
CapacityState state = (capacityState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled;
if (capacities.size() == 0) {
CapacityVO capacityVO = new CapacityVO(null, dcId, null, null, allocated, total, capacityType);
capacityVO.setCapacityState(state);
_capacityDao.persist(capacityVO);
} else if (!(capacities.get(0).getUsedCapacity() == allocated && capacities.get(0).getTotalCapacity() == total
&& capacities.get(0).getCapacityState() == state)) {
CapacityVO capacity = capacities.get(0);
capacity.setUsedCapacity(allocated);
capacity.setTotalCapacity(total);
capacity.setCapacityState(state);
_capacityDao.update(capacity.getId(), capacity);
}
}
class CapacityChecker extends ManagedContextTimerTask {
@Override
protected void runInContext() {
@ -626,6 +657,13 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
alertType = AlertManager.AlertType.ALERT_TYPE_VLAN;
break;
case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET:
msgSubject = "System Alert: Number of unallocated virtual network guest IPv6 subnets is low in availability zone " + dc.getName();
totalStr = Double.toString(totalCapacity);
usedStr = Double.toString(usedCapacity);
msgContent = "Number of unallocated virtual network guest IPv6 subnets is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)";
alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET;
break;
}
try {
@ -646,6 +684,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP);
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE);
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VLAN);
dataCenterCapacityTypes.add(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET);
return dataCenterCapacityTypes;
}
@ -760,7 +799,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {CPUCapacityThreshold, MemoryCapacityThreshold, StorageAllocatedCapacityThreshold, StorageCapacityThreshold, AlertSmtpEnabledSecurityProtocols,
AlertSmtpUseStartTLS};
AlertSmtpUseStartTLS, Ipv6SubnetCapacityThreshold};
}
@Override

View File

@ -28,6 +28,7 @@ import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -36,7 +37,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import com.cloud.utils.security.CertificateHelper;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.affinity.AffinityGroup;
@ -71,6 +71,8 @@ import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
import org.apache.cloudstack.api.response.CounterResponse;
import org.apache.cloudstack.api.response.CreateCmdResponse;
import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
import org.apache.cloudstack.api.response.DataCenterGuestIpv6PrefixResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainResponse;
@ -93,6 +95,7 @@ import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
import org.apache.cloudstack.api.response.IpRangeResponse;
import org.apache.cloudstack.api.response.Ipv6RouteResponse;
import org.apache.cloudstack.api.response.IsolationMethodResponse;
import org.apache.cloudstack.api.response.LBHealthCheckPolicyResponse;
import org.apache.cloudstack.api.response.LBHealthCheckResponse;
@ -125,7 +128,6 @@ import org.apache.cloudstack.api.response.ResourceCountResponse;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.ResourceLimitResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.DirectDownloadCertificateHostStatusResponse;
import org.apache.cloudstack.api.response.RollingMaintenanceHostSkippedResponse;
import org.apache.cloudstack.api.response.RollingMaintenanceHostUpdatedResponse;
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
@ -168,6 +170,7 @@ import org.apache.cloudstack.backup.BackupSchedule;
import org.apache.cloudstack.backup.dao.BackupOfferingDao;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMap;
import org.apache.cloudstack.direct.download.DirectDownloadManager;
import org.apache.cloudstack.direct.download.DirectDownloadManager.HostCertificateStatus.CertificateStatus;
@ -176,7 +179,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.direct.download.DirectDownloadCertificate;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.management.ManagementServerHost;
@ -192,6 +194,7 @@ import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.usage.UsageService;
import org.apache.cloudstack.usage.UsageTypes;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.api.VgpuTypesInfo;
@ -231,6 +234,7 @@ import com.cloud.configuration.ResourceLimit;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Pod;
@ -250,6 +254,7 @@ import com.cloud.hypervisor.HypervisorCapabilities;
import com.cloud.network.GuestVlan;
import com.cloud.network.GuestVlanRange;
import com.cloud.network.IpAddress;
import com.cloud.network.Ipv6Service;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
@ -312,6 +317,7 @@ import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.org.Cluster;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount;
@ -362,6 +368,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Dhcp;
import com.cloud.utils.net.Ip;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.security.CertificateHelper;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.InstanceGroup;
import com.cloud.vm.Nic;
@ -377,7 +384,7 @@ import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import org.apache.commons.lang3.StringUtils;
import sun.security.x509.X509CertImpl;
public class ApiResponseHelper implements ResponseGenerator {
@ -431,6 +438,10 @@ public class ApiResponseHelper implements ResponseGenerator {
private UserStatisticsDao userStatsDao;
@Inject
private NetworkDao networkDao;
@Inject
NetworkOfferingDao networkOfferingDao;
@Inject
Ipv6Service ipv6Service;
@Override
public UserResponse createUserResponse(User user) {
@ -791,8 +802,13 @@ public class ApiResponseHelper implements ResponseGenerator {
}
}
vlanResponse.setGateway(vlan.getVlanGateway());
vlanResponse.setNetmask(vlan.getVlanNetmask());
String gateway = vlan.getVlanGateway();
String netmask = vlan.getVlanNetmask();
vlanResponse.setGateway(gateway);
vlanResponse.setNetmask(netmask);
if (StringUtils.isNotEmpty(gateway) && StringUtils.isNotEmpty(netmask)) {
vlanResponse.setCidr(NetUtils.getCidrFromGatewayAndNetmask(gateway, netmask));
}
// get start ip and end ip of corresponding vlan
String ipRange = vlan.getIpRange();
@ -864,7 +880,7 @@ public class ApiResponseHelper implements ResponseGenerator {
SearchCriteria<IPAddressVO> sc = sb.create();
sc.setParameters("vlanId", vlanId);
IPAddressVO userIpAddresVO = userIpAddressDao.findOneBy(sc);
return userIpAddresVO.isForSystemVms();
return userIpAddresVO != null ? userIpAddresVO.isForSystemVms() : false;
}
@Override
@ -1182,6 +1198,7 @@ public class ApiResponseHelper implements ResponseGenerator {
capacityResponses.addAll(getStatsCapacityresponse(null, null, pod.getId(), pod.getDataCenterId()));
podResponse.setCapacities(new ArrayList<CapacityResponse>(capacityResponses));
}
podResponse.setHasAnnotation(annotationDao.hasAnnotations(pod.getUuid(), AnnotationService.EntityType.POD.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
podResponse.setObjectName("pod");
@ -1248,6 +1265,23 @@ public class ApiResponseHelper implements ResponseGenerator {
return capacityResponses;
}
@Override
public DataCenterGuestIpv6PrefixResponse createDataCenterGuestIpv6PrefixResponse(DataCenterGuestIpv6Prefix prefix) {
DataCenterGuestIpv6PrefixResponse response = new DataCenterGuestIpv6PrefixResponse();
response.setId(prefix.getUuid());
response.setPrefix(prefix.getPrefix());
DataCenter dc = ApiDBUtils.findZoneById(prefix.getDataCenterId());
response.setZoneId(dc.getUuid());
Pair<Integer, Integer> usedTotal = ipv6Service.getUsedTotalIpv6SubnetForPrefix(prefix);
int used = usedTotal.first();
int total = usedTotal.second();
response.setUsedSubnets(used);
response.setAvailableSubnets(total - used);
response.setTotalSubnets(total);
response.setCreated(prefix.getCreated());
return response;
}
@Override
public VolumeResponse createVolumeResponse(ResponseView view, Volume volume) {
List<VolumeJoinVO> viewVrs = ApiDBUtils.newVolumeView(volume);
@ -2498,6 +2532,19 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setBytesReceived(bytesReceived);
response.setBytesSent(bytesSent);
if (networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId())) {
response.setInternetProtocol(networkOfferingDao.getNetworkOfferingInternetProtocol(network.getNetworkOfferingId()).toString());
response.setIpv6Routing(Network.Routing.Static.toString());
response.setIpv6Routes(new LinkedHashSet<>());
if (Network.GuestType.Isolated.equals(networkOffering.getGuestType())) {
List<String> ipv6Addresses = ipv6Service.getPublicIpv6AddressesForNetwork(network);
for (String address : ipv6Addresses) {
Ipv6RouteResponse route = new Ipv6RouteResponse(network.getIp6Cidr(), address);
response.addIpv6Route(route);
}
}
}
response.setObjectName("network");
return response;
}
@ -3186,6 +3233,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setTags(tagResponses);
response.setHasAnnotation(annotationDao.hasAnnotations(vpc.getUuid(), AnnotationService.EntityType.VPC.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
ipv6Service.updateIpv6RoutesForVpcResponse(vpc, response);
response.setObjectName("vpc");
return response;
}
@ -4749,4 +4797,46 @@ public class ApiResponseHelper implements ResponseGenerator {
CertificateStatus status = result != null && result.first() ? CertificateStatus.UPLOADED : CertificateStatus.FAILED;
return getDirectDownloadHostStatusResponseInternal(host, status, result != null ? result.second() : "provision certificate failure");
}
@Override
public FirewallResponse createIpv6FirewallRuleResponse(FirewallRule fwRule) {
FirewallResponse response = new FirewallResponse();
response.setId(fwRule.getUuid());
response.setProtocol(fwRule.getProtocol());
List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
response.setCidrList(StringUtils.join(cidrs, ","));
List<String> destinationCidrs = ApiDBUtils.findFirewallDestCidrs(fwRule.getId());
response.setDestCidr(StringUtils.join(destinationCidrs, ","));
response.setTrafficType(fwRule.getTrafficType().toString());
response.setProtocol(fwRule.getProtocol());
response.setStartPort(fwRule.getSourcePortStart());
response.setEndPort(fwRule.getSourcePortEnd());
response.setIcmpCode(fwRule.getIcmpCode());
response.setIcmpType(fwRule.getIcmpType());
Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
response.setNetworkId(network.getUuid());
FirewallRule.State state = fwRule.getState();
String stateToSet = state.toString();
if (state.equals(FirewallRule.State.Revoke)) {
stateToSet = "Deleting";
}
response.setForDisplay(fwRule.isDisplay());
// set tag information
List<? extends ResourceTag> tags = ApiDBUtils.listByResourceTypeAndId(ResourceObjectType.FirewallRule, fwRule.getId());
List<ResourceTagResponse> tagResponses = new ArrayList<ResourceTagResponse>();
for (ResourceTag tag : tags) {
ResourceTagResponse tagResponse = createResourceTagResponse(tag, true);
CollectionUtils.addIgnoreNull(tagResponses, tagResponse);
}
response.setTags(tagResponses);
response.setState(stateToSet);
response.setObjectName("firewallrule");
return response;
}
}

View File

@ -94,10 +94,12 @@ public class NetworkOfferingJoinDaoImpl extends GenericDaoBase<NetworkOfferingJo
}
networkOfferingResponse.setState(offering.getState().name());
if (offering instanceof NetworkOfferingJoinVO) {
networkOfferingResponse.setDomainId(((NetworkOfferingJoinVO) offering).getDomainUuid());
networkOfferingResponse.setDomain(((NetworkOfferingJoinVO) offering).getDomainPath());
networkOfferingResponse.setZoneId(((NetworkOfferingJoinVO) offering).getZoneUuid());
networkOfferingResponse.setZone(((NetworkOfferingJoinVO) offering).getZoneName());
NetworkOfferingJoinVO networkOfferingJoinVO = (NetworkOfferingJoinVO)offering;
networkOfferingResponse.setDomainId(networkOfferingJoinVO.getDomainUuid());
networkOfferingResponse.setDomain(networkOfferingJoinVO.getDomainPath());
networkOfferingResponse.setZoneId(networkOfferingJoinVO.getZoneUuid());
networkOfferingResponse.setZone(networkOfferingJoinVO.getZoneName());
networkOfferingResponse.setInternetProtocol(networkOfferingJoinVO.getInternetProtocol());
}
networkOfferingResponse.setObjectName("networkoffering");

View File

@ -70,6 +70,7 @@ public class VpcOfferingJoinDaoImpl extends GenericDaoBase<VpcOfferingJoinVO, Lo
offeringResponse.setDomain(offeringJoinVO.getDomainPath());
offeringResponse.setZoneId(offeringJoinVO.getZoneUuid());
offeringResponse.setZone(offeringJoinVO.getZoneName());
offeringResponse.setInternetProtocol(offeringJoinVO.getInternetProtocol());
}
offeringResponse.setObjectName("vpcoffering");

View File

@ -175,6 +175,9 @@ public class NetworkOfferingJoinVO extends BaseViewVO implements NetworkOffering
@Column(name = "zone_name")
private String zoneName = null;
@Column(name = "internet_protocol")
private String internetProtocol = null;
public NetworkOfferingJoinVO() {
}
@ -395,4 +398,7 @@ public class NetworkOfferingJoinVO extends BaseViewVO implements NetworkOffering
this.zoneName = zoneName;
}
public String getInternetProtocol() {
return internetProtocol;
}
}

View File

@ -98,6 +98,9 @@ public class VpcOfferingJoinVO implements VpcOffering {
@Column(name = "zone_name")
private String zoneName = null;
@Column(name = "internet_protocol")
private String internetProtocol = null;
public VpcOfferingJoinVO() {
}
@ -197,6 +200,10 @@ public class VpcOfferingJoinVO implements VpcOffering {
return zoneName;
}
public String getInternetProtocol() {
return internetProtocol;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder("[VPC Offering [");

View File

@ -39,6 +39,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.Vector;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
@ -54,10 +55,13 @@ import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.config.ResetCfgCmd;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
import org.apache.cloudstack.api.command.admin.network.UpdatePodManagementNetworkIpRangeCmd;
import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
@ -134,6 +138,8 @@ import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.DataCenterGuestIpv6PrefixVO;
import com.cloud.dc.DataCenterIpAddressVO;
import com.cloud.dc.DataCenterLinkLocalIpAddressVO;
import com.cloud.dc.DataCenterVO;
@ -149,6 +155,7 @@ import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterDetailsDao;
import com.cloud.dc.dao.DataCenterGuestIpv6PrefixDao;
import com.cloud.dc.dao.DataCenterIpAddressDao;
import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao;
import com.cloud.dc.dao.DedicatedResourceDao;
@ -180,6 +187,8 @@ import com.cloud.host.dao.HostTagsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.IpAddress;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Ipv6GuestPrefixSubnetNetworkMapVO;
import com.cloud.network.Ipv6Service;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.GuestType;
@ -194,6 +203,7 @@ import com.cloud.network.UserIpv6AddressVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
@ -272,6 +282,7 @@ import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.googlecode.ipv6.IPv6Address;
import com.googlecode.ipv6.IPv6Network;
public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
@ -418,6 +429,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
private AnnotationDao annotationDao;
@Inject
UserIpv6AddressDao _ipv6Dao;
@Inject
DataCenterGuestIpv6PrefixDao dataCenterGuestIpv6PrefixDao;
@Inject
Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
@Inject
Ipv6Service ipv6Service;
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
@Inject
@ -1503,7 +1520,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final long zoneId = pod.getDataCenterId();
if(!NetUtils.isValidIp4(gateway)) {
if(!NetUtils.isValidIp4(gateway) && !NetUtils.isValidIp6(gateway)) {
throw new InvalidParameterValueException("The gateway IP address is invalid.");
}
@ -1897,6 +1914,83 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
@Override
@DB
public DataCenterGuestIpv6Prefix createDataCenterGuestIpv6Prefix(final CreateGuestNetworkIpv6PrefixCmd cmd) throws ConcurrentOperationException {
final long zoneId = cmd.getZoneId();
final DataCenterVO zone = _zoneDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Unable to find zone by id: " + zoneId);
}
final String prefix = cmd.getPrefix();
IPv6Network prefixNet = IPv6Network.fromString(prefix);
if (prefixNet.getNetmask().asPrefixLength() > Ipv6Service.IPV6_SLAAC_CIDR_NETMASK) {
throw new InvalidParameterValueException(String.format("IPv6 prefix must be /%d or less", Ipv6Service.IPV6_SLAAC_CIDR_NETMASK));
}
List<DataCenterGuestIpv6PrefixVO> existingPrefixes = dataCenterGuestIpv6PrefixDao.listByDataCenterId(zoneId);
for (DataCenterGuestIpv6PrefixVO existingPrefix : existingPrefixes) {
IPv6Network existingPrefixNet = IPv6Network.fromString(existingPrefix.getPrefix());
if (NetUtils.ipv6NetworksOverlap(existingPrefixNet, prefixNet)) {
throw new InvalidParameterValueException(String.format("IPv6 prefix %s overlaps with the existing IPv6 prefix %s", prefixNet, existingPrefixNet));
}
}
DataCenterGuestIpv6Prefix dataCenterGuestIpv6Prefix = null;
try {
dataCenterGuestIpv6Prefix = Transaction.execute(new TransactionCallback<DataCenterGuestIpv6Prefix>() {
@Override
public DataCenterGuestIpv6Prefix doInTransaction(TransactionStatus status) {
DataCenterGuestIpv6PrefixVO dataCenterGuestIpv6PrefixVO = new DataCenterGuestIpv6PrefixVO(zoneId, prefix);
dataCenterGuestIpv6PrefixDao.persist(dataCenterGuestIpv6PrefixVO);
return dataCenterGuestIpv6PrefixVO;
}
});
} catch (final Exception e) {
s_logger.error(String.format("Unable to add IPv6 prefix for zone: %s due to %s", zone, e.getMessage()), e);
throw new CloudRuntimeException(String.format("Unable to add IPv6 prefix for zone ID: %s. Please contact Cloud Support.", zone.getUuid()));
}
return dataCenterGuestIpv6Prefix;
}
@Override
public List<? extends DataCenterGuestIpv6Prefix> listDataCenterGuestIpv6Prefixes(final ListGuestNetworkIpv6PrefixesCmd cmd) throws ConcurrentOperationException {
final Long id = cmd.getId();
final Long zoneId = cmd.getZoneId();
if (id != null) {
DataCenterGuestIpv6PrefixVO prefix = dataCenterGuestIpv6PrefixDao.findById(id);
List<DataCenterGuestIpv6PrefixVO> prefixes = new ArrayList<>();
if (prefix != null) {
prefixes.add(prefix);
}
return prefixes;
}
if (zoneId != null) {
final DataCenterVO zone = _zoneDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Unable to find zone by id: " + zoneId);
}
return dataCenterGuestIpv6PrefixDao.listByDataCenterId(zoneId);
}
return dataCenterGuestIpv6PrefixDao.listAll();
}
@Override
public boolean deleteDataCenterGuestIpv6Prefix(DeleteGuestNetworkIpv6PrefixCmd cmd) {
final long prefixId = cmd.getId();
final DataCenterGuestIpv6PrefixVO prefix = dataCenterGuestIpv6PrefixDao.findById(prefixId);
if (prefix == null) {
throw new InvalidParameterValueException("Unable to find guest network IPv6 prefix by id: " + prefixId);
}
List<Ipv6GuestPrefixSubnetNetworkMapVO> prefixSubnets = ipv6GuestPrefixSubnetNetworkMapDao.listUsedByPrefix(prefixId);
if (CollectionUtils.isNotEmpty(prefixSubnets)) {
List<String> usedSubnets = prefixSubnets.stream().map(Ipv6GuestPrefixSubnetNetworkMapVO::getSubnet).collect(Collectors.toList());
s_logger.error(String.format("Subnets for guest IPv6 prefix {ID: %s, %s} are in use: %s", prefix.getUuid(), prefix.getPrefix(), String.join(", ", usedSubnets)));
throw new CloudRuntimeException(String.format("Unable to delete guest network IPv6 prefix ID: %s. Prefix subnets are in use.", prefix.getUuid()));
}
ipv6GuestPrefixSubnetNetworkMapDao.deleteByPrefixId(prefixId);
dataCenterGuestIpv6PrefixDao.remove(prefixId);
return true;
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_POD_EDIT, eventDescription = "updating pod", async = false)
public Pod editPod(final UpdatePodCmd cmd) {
@ -4043,6 +4137,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (endIPv6 == null && startIPv6 != null) {
endIPv6 = startIPv6;
}
IPv6Network iPv6Network = IPv6Network.fromString(ip6Cidr);
if (iPv6Network.getNetmask().asPrefixLength() > Ipv6Service.IPV6_SLAAC_CIDR_NETMASK) {
throw new InvalidParameterValueException(String.format("For IPv6 range, prefix must be /%d or less", Ipv6Service.IPV6_SLAAC_CIDR_NETMASK));
}
}
if (projectId != null) {
@ -4086,8 +4185,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
zoneId = network.getDataCenterId();
physicalNetworkId = network.getPhysicalNetworkId();
}
} else if (ipv6) {
throw new InvalidParameterValueException("Only support IPv6 on extending existed network");
}
// Verify that zone exists
@ -4096,11 +4193,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new InvalidParameterValueException("Unable to find zone by id " + zoneId);
}
if (ipv6) {
if (network.getGuestType() != GuestType.Shared || zone.isSecurityGroupEnabled()) {
throw new InvalidParameterValueException("Only support IPv6 on extending existed share network without SG");
}
}
// verify that physical network exists
PhysicalNetworkVO pNtwk = null;
if (physicalNetworkId != null) {
@ -4535,7 +4627,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
String ipv6Range = null;
if (ipv6) {
ipv6Range = startIPv6;
if (endIPv6 != null) {
if (StringUtils.isNotEmpty(ipv6Range) && StringUtils.isNotEmpty(endIPv6)) {
ipv6Range += "-" + endIPv6;
}
@ -4544,17 +4636,23 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
if (vlan.getIp6Gateway() == null) {
continue;
}
if (NetUtils.isSameIsolationId(vlanId, vlan.getVlanTag())) {
if (NetUtils.isIp6RangeOverlap(ipv6Range, vlan.getIp6Range())) {
throw new InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag()
+ " already has IPs that overlap with the new range. Please specify a different start IP/end IP.");
if ((StringUtils.isAllEmpty(ipv6Range, vlan.getIp6Range())) &&
NetUtils.ipv6NetworksOverlap(IPv6Network.fromString(vlanIp6Cidr), IPv6Network.fromString(vlan.getIp6Cidr()))) {
throw new InvalidParameterValueException(String.format("The IPv6 range with tag: %s already has IPs that overlap with the new range.",
vlan.getVlanTag()));
}
if (!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " has already been added with gateway " + vlan.getIp6Gateway()
+ ". Please specify a different tag.");
if (!StringUtils.isAllEmpty(ipv6Range, vlan.getIp6Range())) {
String r1 = StringUtils.isEmpty(ipv6Range) ? NetUtils.getIpv6RangeFromCidr(vlanIp6Cidr) : ipv6Range;
String r2 = StringUtils.isEmpty(vlan.getIp6Range()) ? NetUtils.getIpv6RangeFromCidr(vlanIp6Cidr) : vlan.getIp6Range();
if(NetUtils.isIp6RangeOverlap(r1, r2)) {
throw new InvalidParameterValueException(String.format("The IPv6 range with tag: %s already has IPs that overlap with the new range.",
vlan.getVlanTag()));
}
}
if (NetUtils.isSameIsolationId(vlanId, vlan.getVlanTag()) && !vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
throw new InvalidParameterValueException(String.format("The IP range with tag: %s has already been added with gateway %s. Please specify a different tag.",
vlan.getVlanTag(), vlan.getIp6Gateway()));
}
}
}
@ -4829,25 +4927,30 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final Boolean forSystemVms) {
final List<UserIpv6AddressVO> listAllocatedIPs = _ipv6Dao.listByVlanIdAndState(id, IpAddress.State.Allocated);
if (ip6Gateway != null && !ip6Gateway.equals(vlanRange.getIp6Gateway()) && CollectionUtils.isNotEmpty(listAllocatedIPs)) {
if (ip6Gateway != null && !ip6Gateway.equals(vlanRange.getIp6Gateway()) && (CollectionUtils.isNotEmpty(listAllocatedIPs) || CollectionUtils.isNotEmpty(ipv6Service.getAllocatedIpv6FromVlanRange(vlanRange)))) {
throw new InvalidParameterValueException(String.format("Unable to change ipv6 gateway to %s because some IPs are in use", ip6Gateway));
}
if (ip6Cidr != null && !ip6Cidr.equals(vlanRange.getIp6Cidr()) && CollectionUtils.isNotEmpty(listAllocatedIPs)) {
if (ip6Cidr != null && !ip6Cidr.equals(vlanRange.getIp6Cidr()) && (CollectionUtils.isNotEmpty(listAllocatedIPs) || CollectionUtils.isNotEmpty(ipv6Service.getAllocatedIpv6FromVlanRange(vlanRange)))) {
throw new InvalidParameterValueException(String.format("Unable to change ipv6 cidr to %s because some IPs are in use", ip6Cidr));
}
ip6Gateway = MoreObjects.firstNonNull(ip6Gateway, vlanRange.getIp6Gateway());
ip6Cidr = MoreObjects.firstNonNull(ip6Cidr, vlanRange.getIp6Cidr());
final String[] existingVlanIPRangeArray = vlanRange.getIp6Range().split("-");
final String currentStartIPv6 = existingVlanIPRangeArray[0];
final String currentEndIPv6 = existingVlanIPRangeArray[1];
final String[] existingVlanIPRangeArray = StringUtils.isNotEmpty(vlanRange.getIp6Range()) ? vlanRange.getIp6Range().split("-") : null;
final String currentStartIPv6 = existingVlanIPRangeArray != null ? existingVlanIPRangeArray[0] : null;
final String currentEndIPv6 = existingVlanIPRangeArray != null ? existingVlanIPRangeArray[1] : null;
startIpv6 = MoreObjects.firstNonNull(startIpv6, currentStartIPv6);
endIpv6 = MoreObjects.firstNonNull(endIpv6, currentEndIPv6);
startIpv6 = ObjectUtils.allNull(startIpv6, currentStartIPv6) ? null : MoreObjects.firstNonNull(startIpv6, currentStartIPv6);
endIpv6 = ObjectUtils.allNull(endIpv6, currentEndIPv6) ? null : MoreObjects.firstNonNull(endIpv6, currentEndIPv6);
if (startIpv6 != currentStartIPv6 || endIpv6 != currentEndIPv6) {
_networkModel.checkIp6Parameters(startIpv6, endIpv6, ip6Gateway, ip6Cidr);
if (!ObjectUtils.allNull(startIpv6, endIpv6) && ObjectUtils.anyNull(startIpv6, endIpv6)) {
throw new InvalidParameterValueException(String.format("Invalid IPv6 range %s-%s", startIpv6, endIpv6));
}
if (ObjectUtils.allNotNull(startIpv6, endIpv6) && (!startIpv6.equals(currentStartIPv6) || !endIpv6.equals(currentEndIPv6))) {
checkAllocatedIpv6sAreWithinVlanRange(listAllocatedIPs, startIpv6, endIpv6);
}
try {
VlanVO range = _vlanDao.acquireInLockTable(id, 30);
@ -4868,7 +4971,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
_vlanDao.releaseFromLockTable(id);
}
}
}
private VlanVO commitUpdateVlanAndIpRange(final Long id, final String newStartIP, final String newEndIP, final String currentStartIP, final String currentEndIP,
final String gateway, final String netmask,
@ -4888,7 +4990,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new CloudRuntimeException("Failed to update IPv4 range. Please contact Cloud Support.");
}
} else {
if (ObjectUtils.allNotNull(newStartIP, newEndIP)) {
vlanRange.setIp6Range(newStartIP + "-" + newEndIP);
} else {
vlanRange.setIp6Range(null);
}
vlanRange.setIp6Gateway(gateway);
vlanRange.setIp6Cidr(netmask);
_vlanDao.update(vlanRange.getId(), vlanRange);
@ -4900,6 +5006,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
private boolean checkIfVlanRangeIsForSystemVM(final long vlanId) {
List<IPAddressVO> existingPublicIPs = _publicIpAddressDao.listByVlanId(vlanId);
if (CollectionUtils.isEmpty(existingPublicIPs)) {
return false;
}
boolean initialIsSystemVmValue = existingPublicIPs.get(0).isForSystemVms();
for (IPAddressVO existingIPs : existingPublicIPs) {
if (initialIsSystemVmValue != existingIPs.isForSystemVms()) {
@ -5033,6 +5142,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new InvalidParameterValueException(allocIpCount + " Ips are in use. Cannot delete this vlan");
}
}
List<String> ipAddresses = ipv6Service.getAllocatedIpv6FromVlanRange(vlanRange);
if (CollectionUtils.isNotEmpty(ipAddresses)) {
throw new InvalidParameterValueException(String.format("%d IPv6 addresses are in use. Cannot delete this vlan", ipAddresses.size()));
}
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
@ -5603,6 +5716,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) {
final String name = cmd.getNetworkOfferingName();
final String displayText = cmd.getDisplayText();
final NetUtils.InternetProtocol internetProtocol = NetUtils.InternetProtocol.fromValue(cmd.getInternetProtocol());
final String tags = cmd.getTags();
final String trafficTypeString = cmd.getTraffictype();
final boolean specifyVlan = cmd.getSpecifyVlan();
@ -5668,6 +5782,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
throw new InvalidParameterValueException("Invalid \"type\" parameter is given; can have Shared and Isolated values");
}
if (internetProtocol != null) {
if (!GuestType.Isolated.equals(guestType)) {
throw new InvalidParameterValueException(String.format("%s is supported only for %s guest type", ApiConstants.INTERNET_PROTOCOL, GuestType.Isolated));
}
if (!Ipv6Service.Ipv6OfferingCreationEnabled.value() && !NetUtils.InternetProtocol.IPv4.equals(internetProtocol)) {
throw new InvalidParameterValueException(String.format("Configuration %s needs to be enabled for creating IPv6 supported network offering", Ipv6Service.Ipv6OfferingCreationEnabled.key()));
}
}
// Verify availability
for (final Availability avlb : Availability.values()) {
if (avlb.name().equalsIgnoreCase(availabilityStr)) {
@ -5896,7 +6020,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
final NetworkOfferingVO offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false,
serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, domainIds, zoneIds, enable);
serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, domainIds, zoneIds, enable, internetProtocol);
CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
CallContext.current().putContextParameter(NetworkOffering.class, offering.getId());
return offering;
@ -6035,7 +6159,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final Long serviceOfferingId,
final boolean conserveMode, final Map<Service, Map<Capability, String>> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent,
final Map<Detail, String> details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive, Boolean forVpc,
final List<Long> domainIds, final List<Long> zoneIds, final boolean enableOffering) {
final List<Long> domainIds, final List<Long> zoneIds, final boolean enableOffering, final NetUtils.InternetProtocol internetProtocol) {
String servicePackageUuid;
String spDescription = null;
@ -6280,6 +6404,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.zoneid, String.valueOf(zoneId), false));
}
}
if (internetProtocol != null) {
detailsVO.add(new NetworkOfferingDetailsVO(offering.getId(), Detail.internetProtocol, String.valueOf(internetProtocol), true));
}
if (!detailsVO.isEmpty()) {
networkOfferingDetailsDao.saveDetails(detailsVO);
}

View File

@ -137,6 +137,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setName(profile.getName());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
to.setIp6Address(profile.getIPv6Address());
to.setIp6Gateway(profile.getIPv6Gateway());
to.setIp6Cidr(profile.getIPv6Cidr());
NetworkVO network = _networkDao.findById(profile.getNetworkId());

View File

@ -544,7 +544,7 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl
if (!add) {
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
for (NicVO nic : nics) {
if (nic.getVmType() == null && nic.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && nic.getIPv4Address().equals(network.getGateway())) {
if (nic.getVmType() == null && ReservationStrategy.PlaceHolder.equals(nic.getReservationStrategy()) && nic.getIPv4Address().equals(network.getGateway())) {
s_logger.debug("Removing placeholder nic " + nic + " for the network " + network);
_nicDao.remove(nic.getId());
}

View File

@ -1300,7 +1300,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
List<NicVO> guestIps = _nicDao.listByNetworkId(network.getId());
for (NicVO guestIp : guestIps) {
// only external firewall and external load balancer will create NicVO with PlaceHolder reservation strategy
if (guestIp.getReservationStrategy().equals(ReservationStrategy.PlaceHolder) && guestIp.getVmType() == null && guestIp.getReserver() == null &&
if (ReservationStrategy.PlaceHolder.equals(guestIp.getReservationStrategy()) && guestIp.getVmType() == null && guestIp.getReserver() == null &&
!guestIp.getIPv4Address().equals(network.getGateway())) {
return guestIp;
}

View File

@ -27,6 +27,7 @@ import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.Collections;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -46,6 +47,7 @@ import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpDao;
import org.apache.cloudstack.region.PortableIpVO;
import org.apache.cloudstack.region.Region;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@ -131,6 +133,7 @@ import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.PrivateIpDao;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpn.RemoteAccessVpnService;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Availability;
@ -293,6 +296,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
@Inject
VpcDao _vpcDao;
@Inject
VpcOfferingDao vpcOfferingDao;
@Inject
DataCenterIpAddressDao _privateIPAddressDao;
@Inject
HostPodDao _hpDao;
@ -311,6 +316,17 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
private Random rand = new Random(System.currentTimeMillis());
private List<Long> getIpv6SupportingVlanRangeIds(long dcId) throws InsufficientAddressCapacityException {
List<VlanVO> vlans = _vlanDao.listIpv6SupportingVlansByZone(dcId);
if (CollectionUtils.isEmpty(vlans)) {
s_logger.error("Unable to find VLAN IP range that support both IPv4 and IPv6");
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId);
ex.addProxyObject(ApiDBUtils.findZoneById(dcId).getUuid());
throw ex;
}
return vlans.stream().map(VlanVO::getId).collect(Collectors.toList());
}
@DB
private IPAddressVO assignAndAllocateIpAddressEntry(final Account owner, final VlanType vlanUse, final Long guestNetworkId,
final boolean sourceNat, final boolean allocate, final boolean isSystem,
@ -1035,15 +1051,22 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
if (s_logger.isDebugEnabled()) {
s_logger.debug("lock account " + ownerId + " is acquired");
}
List<Long> vlanDbIds = null;
boolean displayIp = true;
if (guestNtwkId != null) {
Network ntwk = _networksDao.findById(guestNtwkId);
if (_networkOfferingDao.isIpv6Supported(ntwk.getNetworkOfferingId())) {
vlanDbIds = getIpv6SupportingVlanRangeIds(dcId);
}
displayIp = ntwk.getDisplayNetwork();
} else if (vpcId != null) {
VpcVO vpc = _vpcDao.findById(vpcId);
if (vpcOfferingDao.isIpv6Supported(vpc.getVpcOfferingId())) {
vlanDbIds = getIpv6SupportingVlanRangeIds(dcId);
}
displayIp = vpc.isDisplay();
}
return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, null, false, vpcId, displayIp, false);
return fetchNewPublicIp(dcId, null, vlanDbIds, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, null, false, vpcId, displayIp, false);
}
});
if (ip.getState() != State.Allocated) {

View File

@ -22,29 +22,33 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.vm.NicProfile;
import com.googlecode.ipv6.IPv6Address;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import com.cloud.configuration.Config;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventUtils;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.IpAddress.State;
import com.cloud.network.Network.IpAddresses;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.user.Account;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.NicProfile;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.googlecode.ipv6.IPv6Address;
public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressManager {
public static final Logger s_logger = Logger.getLogger(Ipv6AddressManagerImpl.class.getName());
@ -68,6 +72,8 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa
NicSecondaryIpDao nicSecondaryIpDao;
@Inject
IPAddressDao ipAddressDao;
@Inject
NetworkDetailsDao networkDetailsDao;
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@ -213,6 +219,12 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa
} else {
nic.setFormat(Networks.AddressFormat.Ip6);
}
if (Network.GuestType.Isolated.equals(network.getGuestType())) {
final boolean usageHidden = networkDetailsDao.isNetworkUsageHidden(network.getId());
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP6_ASSIGN, network.getAccountId(), network.getDataCenterId(), 0L,
ipv6addr.toString(), false, Vlan.VlanType.VirtualNetwork.toString(), false, usageHidden,
IPv6Address.class.getName(), null);
}
}
nic.setIPv6Dns1(dc.getIp6Dns1());
nic.setIPv6Dns2(dc.getIp6Dns2());

View File

@ -0,0 +1,708 @@
// 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 java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
import org.apache.cloudstack.api.command.user.ipv6.CreateIpv6FirewallRuleCmd;
import org.apache.cloudstack.api.command.user.ipv6.DeleteIpv6FirewallRuleCmd;
import org.apache.cloudstack.api.command.user.ipv6.ListIpv6FirewallRulesCmd;
import org.apache.cloudstack.api.command.user.ipv6.UpdateIpv6FirewallRuleCmd;
import org.apache.cloudstack.api.response.Ipv6RouteResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.configuration.Resource;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterGuestIpv6Prefix;
import com.cloud.dc.DataCenterGuestIpv6PrefixVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterGuestIpv6PrefixDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.event.UsageEventUtils;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.firewall.FirewallService;
import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.rules.FirewallManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLifecycleBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionCallbackWithException;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.googlecode.ipv6.IPv6Address;
import com.googlecode.ipv6.IPv6Network;
import com.googlecode.ipv6.IPv6NetworkMask;
public class Ipv6ServiceImpl extends ComponentLifecycleBase implements Ipv6Service {
public static final Logger s_logger = Logger.getLogger(Ipv6ServiceImpl.class.getName());
private static final String s_publicNetworkReserver = PublicNetworkGuru.class.getSimpleName();
ScheduledExecutorService _ipv6GuestPrefixSubnetNetworkMapStateScanner;
@Inject
NetworkOfferingDao networkOfferingDao;
@Inject
VlanDao vlanDao;
@Inject
DataCenterGuestIpv6PrefixDao dataCenterGuestIpv6PrefixDao;
@Inject
Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
@Inject
FirewallRulesDao firewallDao;
@Inject
FirewallService firewallService;
@Inject
NetworkDetailsDao networkDetailsDao;
@Inject
NicDao nicDao;
@Inject
DomainRouterDao domainRouterDao;
@Inject
AccountManager accountManager;
@Inject
NetworkModel networkModel;
@Inject
IPAddressDao ipAddressDao;
@Inject
FirewallManager firewallManager;
@Inject
NetworkOrchestrationService networkOrchestrationService;
private boolean isPublicIpv6PlaceholderNic(NicVO nic) {
return ObjectUtils.allNotNull(nic.getIPv6Address(), nic.getIPv6Cidr(), nic.getIPv6Gateway()) &&
s_publicNetworkReserver.equals(nic.getReserver());
}
private Pair<String, ? extends Vlan> getPublicIpv6FromNetworkPlaceholder(Network network, List<VlanVO> ranges) {
List<NicVO> placeholderNics = nicDao.listPlaceholderNicsByNetworkIdAndVmType(network.getId(), VirtualMachine.Type.DomainRouter);
if (CollectionUtils.isEmpty(placeholderNics)) {
return null;
}
Optional<NicVO> nicOptional = placeholderNics.stream().filter(this::isPublicIpv6PlaceholderNic).findFirst();
if (nicOptional.isEmpty()) {
return null;
}
NicVO nic = nicOptional.get();
Optional<VlanVO> vlanOptional = ranges.stream().filter(v -> nic.getIPv6Cidr().equals(v.getIp6Cidr()) && nic.getIPv6Gateway().equals(v.getIp6Gateway())).findFirst();
if (vlanOptional.isEmpty()) {
s_logger.error(String.format("Public IPv6 placeholder NIC with cidr: %s, gateway: %s for network ID: %d is not present in the allocated VLAN: %s",
nic.getIPv6Cidr(), nic.getIPv6Gateway(),network.getId(), ranges.get(0).getVlanTag()));
return null;
}
return new Pair<>(nic.getIPv6Address(), vlanOptional.get());
}
private Pair<String, ? extends Vlan> assignPublicIpv6ToNetworkInternal(Network network, String vlanId, String nicMacAddress) throws InsufficientAddressCapacityException {
Pair<String, ? extends Vlan> result = Transaction.execute((TransactionCallbackWithException<Pair<String, ? extends Vlan>, InsufficientAddressCapacityException>) status -> {
final List<VlanVO> ranges = vlanDao.listIpv6RangeByPhysicalNetworkIdAndVlanId(network.getPhysicalNetworkId(), vlanId);
if (CollectionUtils.isEmpty(ranges)) {
s_logger.error(String.format("Unable to find IPv6 address for zone ID: %d, physical network ID: %d, VLAN: %s", network.getDataCenterId(), network.getPhysicalNetworkId(), vlanId));
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, network.getDataCenterId());
ex.addProxyObject(ApiDBUtils.findZoneById(network.getDataCenterId()).getUuid());
throw ex;
}
Pair<String, ? extends Vlan> placeholderResult = getPublicIpv6FromNetworkPlaceholder(network, ranges);
if (placeholderResult != null) {
return placeholderResult;
}
removePublicIpv6PlaceholderNics(network);
Collections.shuffle(ranges);
VlanVO selectedVlan = ranges.get(0);
IPv6Network ipv6Network = IPv6Network.fromString(selectedVlan.getIp6Cidr());
if (ipv6Network.getNetmask().asPrefixLength() < IPV6_SLAAC_CIDR_NETMASK) {
Iterator<IPv6Network> splits = ipv6Network.split(IPv6NetworkMask.fromPrefixLength(IPV6_SLAAC_CIDR_NETMASK));
if (splits.hasNext()) {
ipv6Network = splits.next();
}
}
IPv6Address ipv6Addr = NetUtils.EUI64Address(ipv6Network, nicMacAddress);
networkOrchestrationService.savePlaceholderNic(network, null, ipv6Addr.toString(), selectedVlan.getIp6Cidr(), selectedVlan.getIp6Gateway(), s_publicNetworkReserver, VirtualMachine.Type.DomainRouter);
return new Pair<>(ipv6Addr.toString(), selectedVlan);
});
final String ipv6Address = result.first();
final String event = EventTypes.EVENT_NET_IP6_ASSIGN;
final String description = String.format("Assigned public IPv6 address: %s for network ID: %s", ipv6Address, network.getUuid());
ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, event, description, network.getId(), ApiCommandResourceType.Network.toString(), 0);
final boolean usageHidden = networkDetailsDao.isNetworkUsageHidden(network.getId());
final String guestType = result.second().getVlanType().toString();
UsageEventUtils.publishUsageEvent(event, network.getAccountId(), network.getDataCenterId(), 0L,
ipv6Address, false, guestType, false, usageHidden,
IPv6Network.class.getName(), null);
return result;
}
private Ipv6GuestPrefixSubnetNetworkMapVO preallocatePrefixSubnetRandomly(DataCenterGuestIpv6PrefixVO prefix) {
Ipv6GuestPrefixSubnetNetworkMapVO ip6Subnet = null;
List<Ipv6GuestPrefixSubnetNetworkMapVO> prefixSubnetNetworkMapVOList = ipv6GuestPrefixSubnetNetworkMapDao.listUsedByPrefix(prefix.getId());
List<String> usedPrefixList = prefixSubnetNetworkMapVOList.stream().map(Ipv6GuestPrefixSubnetNetworkMap::getSubnet).collect(Collectors.toList());
final IPv6Network ip6Prefix = IPv6Network.fromString(prefix.getPrefix());
Iterator<IPv6Network> splits = ip6Prefix.split(IPv6NetworkMask.fromPrefixLength(IPV6_SLAAC_CIDR_NETMASK));
List<IPv6Network> availableSubnets = new ArrayList<>();
while (splits.hasNext()) {
IPv6Network i = splits.next();
if (!usedPrefixList.contains(i.toString())) {
availableSubnets.add(i);
}
}
if (CollectionUtils.isNotEmpty(availableSubnets)) {
Random r = new Random();
IPv6Network subnet = availableSubnets.get(r.nextInt(availableSubnets.size()));
ip6Subnet = new Ipv6GuestPrefixSubnetNetworkMapVO(prefix.getId(), subnet.toString(), null, Ipv6GuestPrefixSubnetNetworkMap.State.Allocating);
}
return ip6Subnet;
}
protected void releaseIpv6Subnet(long subnetId) {
Ipv6GuestPrefixSubnetNetworkMapVO ipv6GuestPrefixSubnetNetworkMapVO = ipv6GuestPrefixSubnetNetworkMapDao.createForUpdate(subnetId);
ipv6GuestPrefixSubnetNetworkMapVO.setState(Ipv6GuestPrefixSubnetNetworkMap.State.Free);
ipv6GuestPrefixSubnetNetworkMapVO.setNetworkId(null);
ipv6GuestPrefixSubnetNetworkMapVO.setUpdated(new Date());
ipv6GuestPrefixSubnetNetworkMapDao.update(ipv6GuestPrefixSubnetNetworkMapVO.getId(), ipv6GuestPrefixSubnetNetworkMapVO);
}
@Override
public boolean start() {
_ipv6GuestPrefixSubnetNetworkMapStateScanner.scheduleWithFixedDelay(new Ipv6GuestPrefixSubnetNetworkMapStateScanner(), 300, 30*60, TimeUnit.SECONDS);
return true;
}
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
_configParams = params;
_ipv6GuestPrefixSubnetNetworkMapStateScanner = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Ipv6GuestPrefixSubnet-State-Scanner"));
return true;
}
@Override
public List<Class<?>> getCommands() {
final List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(CreateGuestNetworkIpv6PrefixCmd.class);
cmdList.add(ListGuestNetworkIpv6PrefixesCmd.class);
cmdList.add(DeleteGuestNetworkIpv6PrefixCmd.class);
cmdList.add(CreateIpv6FirewallRuleCmd.class);
cmdList.add(ListIpv6FirewallRulesCmd.class);
cmdList.add(UpdateIpv6FirewallRuleCmd.class);
cmdList.add(DeleteIpv6FirewallRuleCmd.class);
return cmdList;
}
@Override
public String getConfigComponentName() {
return Ipv6Service.class.getSimpleName();
}
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {
Ipv6OfferingCreationEnabled,
Ipv6PrefixSubnetCleanupInterval
};
}
@Override
public Pair<Integer, Integer> getUsedTotalIpv6SubnetForPrefix(DataCenterGuestIpv6Prefix prefix) {
List<Ipv6GuestPrefixSubnetNetworkMapVO> usedSubnets = ipv6GuestPrefixSubnetNetworkMapDao.listUsedByPrefix(prefix.getId());
final IPv6Network ip6Prefix = IPv6Network.fromString(prefix.getPrefix());
Iterator<IPv6Network> splits = ip6Prefix.split(IPv6NetworkMask.fromPrefixLength(IPV6_SLAAC_CIDR_NETMASK));
int total = 0;
while(splits.hasNext()) {
total++;
splits.next();
}
return new Pair<>(usedSubnets.size(), total);
}
@Override
public Pair<Integer, Integer> getUsedTotalIpv6SubnetForZone(long zoneId) {
int used = 0;
int total = 0;
List<DataCenterGuestIpv6PrefixVO> prefixes = dataCenterGuestIpv6PrefixDao.listByDataCenterId(zoneId);
for (DataCenterGuestIpv6PrefixVO prefix : prefixes) {
Pair<Integer, Integer> usedTotal = getUsedTotalIpv6SubnetForPrefix(prefix);
used += usedTotal.first();
total += usedTotal.second();
}
return new Pair<>(used, total);
}
public Pair<String, String> preAllocateIpv6SubnetForNetwork(long zoneId) throws ResourceAllocationException {
return Transaction.execute((TransactionCallbackWithException<Pair<String, String>, ResourceAllocationException>) status -> {
List<DataCenterGuestIpv6PrefixVO> prefixes = dataCenterGuestIpv6PrefixDao.listByDataCenterId(zoneId);
if (CollectionUtils.isEmpty(prefixes)) {
s_logger.error(String.format("IPv6 prefixes not found for the zone ID: %d", zoneId));
throw new ResourceAllocationException("Unable to allocate IPv6 network", Resource.ResourceType.network);
}
Ipv6GuestPrefixSubnetNetworkMapVO ip6Subnet = null;
for (DataCenterGuestIpv6PrefixVO prefix : prefixes) {
ip6Subnet = ipv6GuestPrefixSubnetNetworkMapDao.findFirstAvailable(prefix.getId());
if (ip6Subnet == null) {
ip6Subnet = preallocatePrefixSubnetRandomly(prefix);
}
if (ip6Subnet != null) {
break;
}
}
if (ip6Subnet == null) {
throw new ResourceAllocationException("Unable to allocate IPv6 guest subnet for the network", Resource.ResourceType.network);
}
ip6Subnet.setUpdated(new Date());
if (Ipv6GuestPrefixSubnetNetworkMap.State.Free.equals(ip6Subnet.getState())) {
ip6Subnet.setState(Ipv6GuestPrefixSubnetNetworkMap.State.Allocating);
ipv6GuestPrefixSubnetNetworkMapDao.update(ip6Subnet.getId(), ip6Subnet);
} else {
ipv6GuestPrefixSubnetNetworkMapDao.persist(ip6Subnet);
}
IPv6Network network = IPv6Network.fromString(ip6Subnet.getSubnet());
IPv6Address gateway = network.getFirst().add(1);
return new Pair<>(gateway.toString(), network.toString());
});
}
@Override
public void assignIpv6SubnetToNetwork(String subnet, long networkId) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
Ipv6GuestPrefixSubnetNetworkMapVO ipv6GuestPrefixSubnetNetworkMapVO = ipv6GuestPrefixSubnetNetworkMapDao.findBySubnet(subnet);
if (ipv6GuestPrefixSubnetNetworkMapVO != null) {
ipv6GuestPrefixSubnetNetworkMapVO = ipv6GuestPrefixSubnetNetworkMapDao.createForUpdate(ipv6GuestPrefixSubnetNetworkMapVO.getId());
ipv6GuestPrefixSubnetNetworkMapVO.setState(Ipv6GuestPrefixSubnetNetworkMap.State.Allocated);
ipv6GuestPrefixSubnetNetworkMapVO.setNetworkId(networkId);
ipv6GuestPrefixSubnetNetworkMapVO.setUpdated(new Date());
ipv6GuestPrefixSubnetNetworkMapDao.update(ipv6GuestPrefixSubnetNetworkMapVO.getId(), ipv6GuestPrefixSubnetNetworkMapVO);
}
}
});
}
@Override
public void releaseIpv6SubnetForNetwork(long networkId) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
Ipv6GuestPrefixSubnetNetworkMapVO ipv6GuestPrefixSubnetNetworkMapVO = ipv6GuestPrefixSubnetNetworkMapDao.findByNetworkId(networkId);
if (ipv6GuestPrefixSubnetNetworkMapVO != null) {
releaseIpv6Subnet(ipv6GuestPrefixSubnetNetworkMapVO.getId());
}
}
});
}
@Override
public List<String> getAllocatedIpv6FromVlanRange(Vlan vlan) {
if (ObjectUtils.allNull(vlan.getIp6Cidr(), vlan.getIp6Gateway())) {
return null;
}
List<NicVO> nics = nicDao.findNicsByIpv6GatewayIpv6CidrAndReserver(vlan.getIp6Gateway(), vlan.getIp6Cidr(), s_publicNetworkReserver);
if (CollectionUtils.isNotEmpty(nics)) {
return nics.stream().map(NicVO::getIPv6Address).collect(Collectors.toList());
}
return null;
}
@Override
public Nic assignPublicIpv6ToNetwork(Network network, Nic nic) {
if (StringUtils.isNotEmpty(nic.getIPv6Address())) {
return nic;
}
try {
Pair<String, ? extends Vlan> publicIpv6AddressVlanPair = assignPublicIpv6ToNetworkInternal(network, nic.getBroadcastUri().toString(), nic.getMacAddress());
Vlan vlan = publicIpv6AddressVlanPair.second();
final String ipv6Address = publicIpv6AddressVlanPair.first();
final String ipv6Gateway = vlan.getIp6Gateway();
final String ipv6Cidr = vlan.getIp6Cidr();
NicVO nicVO = nicDao.createForUpdate(nic.getId());
nicVO.setIPv6Address(ipv6Address);
nicVO.setIPv6Gateway(ipv6Gateway);
nicVO.setIPv6Cidr(ipv6Cidr);
nicDao.update(nic.getId(), nicVO);
return nicVO;
} catch (InsufficientAddressCapacityException ex) {
throw new CloudRuntimeException(ex.getMessage());
}
}
@Override
public void updateNicIpv6(NicProfile nic, DataCenter dc, Network network) throws InsufficientAddressCapacityException {
boolean isIpv6Supported = networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId());
if (nic.getIPv6Address() == null && isIpv6Supported) {
Pair<String, ? extends Vlan> publicIpv6AddressVlanPair = assignPublicIpv6ToNetworkInternal(network, nic.getBroadCastUri().toString(), nic.getMacAddress());
final Vlan vlan = publicIpv6AddressVlanPair.second();
final String routerIpv6 = publicIpv6AddressVlanPair.first();
final String routerIpv6Gateway = vlan.getIp6Gateway();
final String routerIpv6Cidr = vlan.getIp6Cidr();
nic.setIPv6Address(routerIpv6);
nic.setIPv6Gateway(routerIpv6Gateway);
nic.setIPv6Cidr(routerIpv6Cidr);
if (nic.getIPv4Address() != null) {
nic.setFormat(Networks.AddressFormat.DualStack);
} else {
nic.setFormat(Networks.AddressFormat.Ip6);
}
nic.setIPv6Dns1(dc.getIp6Dns1());
nic.setIPv6Dns2(dc.getIp6Dns2());
}
}
@Override
public void releasePublicIpv6ForNic(Network network, String nicIpv6Address) {
String event = EventTypes.EVENT_NET_IP6_RELEASE;
String description = String.format("Releasing public IPv6 address: %s from network ID: %s", nicIpv6Address, network.getUuid());
ActionEventUtils.onCompletedActionEvent(CallContext.current().getCallingUserId(), network.getAccountId(), EventVO.LEVEL_INFO, event, description, network.getId(), ApiCommandResourceType.Network.toString(), 0);
final boolean usageHidden = networkDetailsDao.isNetworkUsageHidden(network.getId());
UsageEventUtils.publishUsageEvent(event, network.getAccountId(), network.getDataCenterId(), 0L,
nicIpv6Address, false, Vlan.VlanType.VirtualNetwork.toString(), false, usageHidden,
IPv6Address.class.getName(), null);
}
@Override
public List<String> getPublicIpv6AddressesForNetwork(Network network) {
List<String> addresses = new ArrayList<>();
List<DomainRouterVO> routers = domainRouterDao.findByNetwork(network.getId());
for (DomainRouterVO router : routers) {
List<NicVO> nics = nicDao.listByVmId(router.getId());
for (NicVO nic : nics) {
String address = nic.getIPv6Address();
if (!s_publicNetworkReserver.equals(nic.getReserver()) ||
StringUtils.isEmpty(address) ||
addresses.contains(address)) {
continue;
}
addresses.add(address);
}
}
return addresses;
}
@Override
public void updateIpv6RoutesForVpcResponse(Vpc vpc, VpcResponse response) {
Set<Ipv6RouteResponse> ipv6Routes = new LinkedHashSet<>();
List<? extends Network> networks = networkModel.listNetworksByVpc(vpc.getId());
for (Network network : networks) {
if (networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId())) {
List<String> networkPublicIpv6 = getPublicIpv6AddressesForNetwork(network);
for (String address : networkPublicIpv6) {
Ipv6RouteResponse route = new Ipv6RouteResponse(network.getIp6Cidr(), address);
ipv6Routes.add(route);
}
}
}
if (CollectionUtils.isNotEmpty(ipv6Routes)) {
response.setIpv6Routes(ipv6Routes);
}
}
@Override
public void checkNetworkIpv6Upgrade(Network network) throws InsufficientAddressCapacityException, ResourceAllocationException {
List<DataCenterGuestIpv6PrefixVO> prefixes = dataCenterGuestIpv6PrefixDao.listByDataCenterId(network.getDataCenterId());
if (CollectionUtils.isEmpty(prefixes)) {
s_logger.error(String.format("IPv6 prefixes not found for the zone ID: %d", network.getDataCenterId()));
throw new ResourceAllocationException("Unable to allocate IPv6 network", Resource.ResourceType.network);
}
List<IPAddressVO> addresses = network.getVpcId() == null ?
ipAddressDao.listByAssociatedNetwork(network.getId(), true) :
ipAddressDao.listByAssociatedVpc(network.getVpcId(), true);
for (IPAddressVO address : addresses) {
VlanVO vlan = vlanDao.findById(address.getVlanId());
final List<VlanVO> ranges = vlanDao.listIpv6RangeByPhysicalNetworkIdAndVlanId(network.getPhysicalNetworkId(), vlan.getVlanTag());
if (CollectionUtils.isEmpty(ranges)) {
s_logger.error(String.format("Unable to find IPv6 address for zone ID: %d, physical network ID: %d, VLAN: %s", network.getDataCenterId(), network.getPhysicalNetworkId(), vlan.getVlanTag()));
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, network.getDataCenterId());
ex.addProxyObject(ApiDBUtils.findZoneById(network.getDataCenterId()).getUuid());
throw ex;
}
}
}
@Override
public Pair<List<? extends FirewallRule>, Integer> listIpv6FirewallRules(ListIpv6FirewallRulesCmd listIpv6FirewallRulesCmd) {
return firewallService.listFirewallRules(listIpv6FirewallRulesCmd);
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating IPv6 firewall rule", create = true)
public FirewallRule createIpv6FirewallRule(CreateIpv6FirewallRuleCmd cmd) throws NetworkRuleConflictException {
final Account caller = CallContext.current().getCallingAccount();
final long networkId = cmd.getNetworkId();
final Integer portStart = cmd.getSourcePortStart();
final Integer portEnd = cmd.getSourcePortEnd();
final FirewallRule.TrafficType trafficType = cmd.getTrafficType();
final String protocol = cmd.getProtocol();
final Integer icmpCode = cmd.getIcmpCode();
final Integer icmpType = cmd.getIcmpType();
final boolean forDisplay = cmd.isDisplay();
final FirewallRule.FirewallRuleType type = FirewallRule.FirewallRuleType.User;
final List<String> sourceCidrList = cmd.getSourceCidrList();
final List<String> destinationCidrList = cmd.getDestinationCidrList();
for (String cidr : sourceCidrList) {
if (!NetUtils.isValidIp6Cidr(cidr)) {
throw new InvalidParameterValueException(String.format("Invalid source IPv6 CIDR: %s", cidr));
}
}
for (String cidr : destinationCidrList) {
if (!NetUtils.isValidIp6Cidr(cidr)) {
throw new InvalidParameterValueException(String.format("Invalid destination IPv6 CIDR: %s", cidr));
}
}
if (portStart != null && !NetUtils.isValidPort(portStart)) {
throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
}
if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
}
if (ObjectUtils.allNotNull(portStart, portEnd) && portStart > portEnd) {
throw new InvalidParameterValueException("Start port can't be bigger than end port");
}
Network network = networkModel.getNetwork(networkId);
assert network != null : "Can't create rule as network is null?";
final long accountId = network.getAccountId();
final long domainId = network.getDomainId();
if (FirewallRule.TrafficType.Egress.equals(trafficType)) {
accountManager.checkAccess(caller, null, true, network);
}
// Verify that the network guru supports the protocol specified
Map<Network.Capability, String> caps = networkModel.getNetworkServiceCapabilities(network.getId(), Network.Service.Firewall);
if (caps != null) {
String supportedProtocols;
String supportedTrafficTypes = null;
supportedTrafficTypes = caps.get(Network.Capability.SupportedTrafficDirection).toLowerCase();
if (trafficType == FirewallRule.TrafficType.Egress) {
supportedProtocols = caps.get(Network.Capability.SupportedEgressProtocols).toLowerCase();
} else {
supportedProtocols = caps.get(Network.Capability.SupportedProtocols).toLowerCase();
}
if (!supportedProtocols.contains(protocol.toLowerCase())) {
throw new InvalidParameterValueException(String.format("Protocol %s is not supported in zone", protocol));
} else if (!supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId);
}
}
// icmp code and icmp type can't be passed in for any other protocol rather than icmp
if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
}
if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
}
return Transaction.execute(new TransactionCallbackWithException<FirewallRuleVO, NetworkRuleConflictException>() {
@Override
public FirewallRuleVO doInTransaction(TransactionStatus status) throws NetworkRuleConflictException {
FirewallRuleVO newRule =
new FirewallRuleVO(null, null, portStart, portEnd, protocol.toLowerCase(), networkId, accountId, domainId, FirewallRule.Purpose.Ipv6Firewall,
sourceCidrList, destinationCidrList, icmpCode, icmpType, null, trafficType);
newRule.setType(type);
newRule.setDisplay(forDisplay);
newRule = firewallDao.persist(newRule);
if (FirewallRule.FirewallRuleType.User.equals(type)) {
firewallManager.detectRulesConflict(newRule);
}
if (!firewallDao.setStateToAdd(newRule)) {
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
}
CallContext.current().setEventDetails("Rule Id: " + newRule.getId());
return newRule;
}
});
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking IPv6 firewall rule", async = true)
public boolean revokeIpv6FirewallRule(Long id) {
FirewallRuleVO rule = firewallDao.findById(id);
if (rule == null) {
throw new InvalidParameterValueException(String.format("Unable to find IPv6 firewall rule with id %d", id));
}
if (FirewallRule.TrafficType.Ingress.equals(rule.getTrafficType())) {
return firewallManager.revokeIngressFirewallRule(rule.getId(), true);
}
return firewallManager.revokeEgressFirewallRule(rule.getId(), true);
}
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_UPDATE, eventDescription = "updating IPv6 firewall rule", async = true)
public FirewallRule updateIpv6FirewallRule(UpdateIpv6FirewallRuleCmd cmd) {
final long id = cmd.getId();
final boolean forDisplay = cmd.isDisplay();
FirewallRuleVO rule = firewallDao.findById(id);
if (rule == null) {
throw new InvalidParameterValueException(String.format("Unable to find IPv6 firewall rule with id %d", id));
}
if (FirewallRule.TrafficType.Ingress.equals(rule.getTrafficType())) {
return firewallManager.updateIngressFirewallRule(rule.getId(), null, forDisplay);
}
return firewallManager.updateEgressFirewallRule(rule.getId(), null, forDisplay);
}
@Override
public FirewallRule getIpv6FirewallRule(Long entityId) {
return firewallDao.findById(entityId);
}
@Override
public boolean applyIpv6FirewallRule(long id) {
FirewallRuleVO rule = firewallDao.findById(id);
if (rule == null) {
s_logger.error(String.format("Unable to find IPv6 firewall rule with ID: %d", id));
return false;
}
if (!FirewallRule.Purpose.Ipv6Firewall.equals(rule.getPurpose())) {
s_logger.error(String.format("Cannot apply IPv6 firewall rule with ID: %d as purpose %s is not %s", id, rule.getPurpose(), FirewallRule.Purpose.Ipv6Firewall));
}
s_logger.debug(String.format("Applying IPv6 firewall rules for rule with ID: %s", rule.getUuid()));
List<FirewallRuleVO> rules = firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), rule.getPurpose(), FirewallRule.TrafficType.Egress);
rules.addAll(firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), FirewallRule.Purpose.Ipv6Firewall, FirewallRule.TrafficType.Ingress));
return firewallManager.applyFirewallRules(rules, false, CallContext.current().getCallingAccount());
}
@Override
public void removePublicIpv6PlaceholderNics(Network network) {
try {
List<NicVO> nics = nicDao.listPlaceholderNicsByNetworkId(network.getId())
.stream().filter(this::isPublicIpv6PlaceholderNic).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(nics)) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
for (Nic nic : nics) {
s_logger.debug("Removing placeholder nic " + nic);
nicDao.remove(nic.getId());
}
}
});
}
} catch (Exception e) {
String msg = String.format("IPv6 Placeholder Nics trash. Exception: %s", e.getMessage());
s_logger.error(msg);
throw new CloudRuntimeException(msg, e);
}
}
public class Ipv6GuestPrefixSubnetNetworkMapStateScanner extends ManagedContextRunnable {
@Override
protected void runInContext() {
GlobalLock gcLock = GlobalLock.getInternLock("Ipv6GuestPrefixSubnetNetworkMap.State.Scanner.Lock");
try {
if (gcLock.lock(3)) {
try {
reallyRun();
} finally {
gcLock.unlock();
}
}
} finally {
gcLock.releaseRef();
}
}
public void reallyRun() {
try {
List<Ipv6GuestPrefixSubnetNetworkMapVO> subnets = ipv6GuestPrefixSubnetNetworkMapDao.findPrefixesInStates(Ipv6GuestPrefixSubnetNetworkMap.State.Allocating);
for (Ipv6GuestPrefixSubnetNetworkMapVO subnet : subnets) {
if (s_logger.isInfoEnabled()) {
s_logger.info(String.format("Running state scanned on Ipv6GuestPrefixSubnetNetworkMap : %s", subnet.getSubnet()));
}
try {
if ((new Date()).getTime() - subnet.getUpdated().getTime() < Ipv6PrefixSubnetCleanupInterval.value()*1000) {
continue;
}
releaseIpv6Subnet(subnet.getId());
} catch (CloudRuntimeException e) {
s_logger.warn(String.format("Failed to release IPv6 guest prefix subnet : %s during state scan", subnet.getSubnet()), e);
}
}
} catch (Exception e) {
s_logger.warn("Caught exception while running Ipv6GuestPrefixSubnetNetworkMap state scanner: ", e);
}
}
}
}

View File

@ -582,10 +582,9 @@ public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
//For each nic in the old network check if the nic belongs to a guest vm and migrate it to the new network.
for (NicVO originalNic : nics) {
if (originalNic.getVmType() != VirtualMachine.Type.User) {
if (!VirtualMachine.Type.User.equals(originalNic.getVmType())) {
continue;
}
Transaction.execute((TransactionCallback<Boolean>)
(status) -> migrateNicsInDB(originalNic, networkInNewPhysicalNet, dc, context));
}

View File

@ -16,8 +16,6 @@
// 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;
@ -75,6 +73,7 @@ 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.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -131,6 +130,7 @@ import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkAccountDao;
import com.cloud.network.dao.NetworkDao;
@ -227,6 +227,7 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.googlecode.ipv6.IPv6Address;
/**
* NetworkServiceImpl implements NetworkService.
@ -359,6 +360,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
NetworkAccountDao _networkAccountDao;
@Inject
VirtualMachineManager vmManager;
@Inject
Ipv6Service ipv6Service;
@Inject
Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@ -1472,6 +1477,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
validateRouterIps(routerIp, routerIpv6, startIP, endIP, gateway, netmask, startIPv6, endIPv6, ip6Cidr);
Pair<String, String> ip6GatewayCidr = null;
if (zone.getNetworkType() == NetworkType.Advanced && ntwkOff.getGuestType() == GuestType.Isolated) {
ipv6 = _networkOfferingDao.isIpv6Supported(ntwkOff.getId());
if (ipv6) {
ip6GatewayCidr = ipv6Service.preAllocateIpv6SubnetForNetwork(zone.getId());
ip6Gateway = ip6GatewayCidr.first();
ip6Cidr = ip6GatewayCidr.second();
}
}
if (StringUtils.isNotBlank(isolatedPvlan)) {
if (!_accountMgr.isRootAdmin(caller.getId())) {
@ -1552,7 +1566,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
if (!createVlan) {
// Only support advance shared network in IPv6, which means createVlan is a must
if (ipv6) {
if (ipv6 && ntwkOff.getGuestType() != GuestType.Isolated) {
createVlan = true;
}
}
@ -1584,6 +1598,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
}
if (ip6GatewayCidr != null) {
ipv6Service.assignIpv6SubnetToNetwork(ip6Cidr, network.getId());
}
// if the network offering has persistent set to true, implement the network
if (ntwkOff.isPersistent()) {
return implementedNetworkInCreation(caller, zone, network);
@ -1775,7 +1793,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
}
network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType,
subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId);
subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId, ip6Gateway, ip6Cidr);
} else {
if (_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
@ -2502,6 +2520,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
Network updatedNetwork = getNetwork(network.getId());
for (NicVO nic : nics) {
if (Nic.ReservationStrategy.PlaceHolder.equals(nic.getReservationStrategy())) {
continue;
}
long vmId = nic.getInstanceId();
VMInstanceVO vm = _vmDao.findById(vmId);
if (vm == null) {
@ -2658,6 +2679,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) {
throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNtwkOff.getUuid() + " to " + networkOffering.getUuid() + "; check logs for more information");
}
boolean isIpv6Supported = _networkOfferingDao.isIpv6Supported(oldNetworkOfferingId);
boolean isIpv6SupportedNew = _networkOfferingDao.isIpv6Supported(networkOfferingId);
if (!isIpv6Supported && isIpv6SupportedNew) {
try {
ipv6Service.checkNetworkIpv6Upgrade(network);
} catch (ResourceAllocationException | InsufficientAddressCapacityException ex) {
throw new CloudRuntimeException(String.format("Failed to upgrade network offering to '%s' as unable to allocate IPv6 network", networkOffering.getDisplayText()), ex);
}
}
restartNetwork = true;
networkOfferingChanged = true;
@ -2746,6 +2776,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
s_logger.info("The specified guest vm cidr has " + range + " IPs");
for (NicVO nic : nicsPresent) {
if (nic.getIPv4Address() == null) {
continue;
}
long nicIp = NetUtils.ip2Long(nic.getIPv4Address());
//check if nic IP is outside the guest vm cidr
if ((nicIp < startIp || nicIp > endIp) && nic.getState() != Nic.State.Deallocating) {
@ -2875,6 +2908,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
updateNetworkIpv6(network, networkOfferingId);
network.setNetworkOfferingId(networkOfferingId);
_networksDao.update(networkId, network, newSvcProviders);
// get all nics using this network
@ -2882,7 +2916,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
// log assign usage events for new offering
List<NicVO> nics = _nicDao.listByNetworkId(networkId);
for (NicVO nic : nics) {
if (nic.getReservationStrategy() == Nic.ReservationStrategy.PlaceHolder) {
if (Nic.ReservationStrategy.PlaceHolder.equals(nic.getReservationStrategy())) {
continue;
}
long vmId = nic.getInstanceId();
@ -2953,7 +2987,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
if (updateInSequence) {
_networkMgr.finalizeUpdateInSequence(network, false);
}
throw new CloudRuntimeException("failed to update network " + network.getUuid() + " due to " + exception.getMessage());
throw new CloudRuntimeException("failed to update network " + network.getUuid() + " due to " + exception.getMessage(), exception);
} finally {
if (updateInSequence) {
if (_networkDetailsDao.findDetail(networkId, Network.updatingInSequence) != null) {
@ -2964,6 +2998,50 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return getNetwork(network.getId());
}
private void updateNetworkIpv6(NetworkVO network, Long networkOfferingId) {
boolean isIpv6Supported = _networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId());
boolean isIpv6SupportedNew = _networkOfferingDao.isIpv6Supported(networkOfferingId);
if (isIpv6Supported && ! isIpv6SupportedNew) {
// _ipv6AddressDao.unmark(network.getId(), network.getDomainId(), network.getAccountId());
network.setIp6Gateway(null);
network.setIp6Cidr(null);
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
for (NicVO nic : nics) {
if (Nic.ReservationStrategy.PlaceHolder.equals(nic.getReservationStrategy())) {
continue;
}
nic.setIPv6Address(null);
nic.setIPv6Cidr(null);
nic.setIPv6Gateway(null);
_nicDao.update(nic.getId(), nic);
}
} else if (!isIpv6Supported && isIpv6SupportedNew) {
Pair<String, String> ip6GatewayCidr;
try {
ip6GatewayCidr = ipv6Service.preAllocateIpv6SubnetForNetwork(network.getDataCenterId());
ipv6Service.assignIpv6SubnetToNetwork(ip6GatewayCidr.second(), network.getId());
} catch (ResourceAllocationException ex) {
throw new CloudRuntimeException("unable to allocate IPv6 network", ex);
}
String ip6Gateway = ip6GatewayCidr.first();
String ip6Cidr = ip6GatewayCidr.second();
network.setIp6Gateway(ip6Gateway);
network.setIp6Cidr(ip6Cidr);
Ipv6GuestPrefixSubnetNetworkMapVO map = ipv6GuestPrefixSubnetNetworkMapDao.findByNetworkId(network.getId());
List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
for (NicVO nic : nics) {
if (Nic.ReservationStrategy.PlaceHolder.equals(nic.getReservationStrategy())) {
continue;
}
IPv6Address iPv6Address = NetUtils.EUI64Address(map.getSubnet(), nic.getMacAddress());
nic.setIPv6Address(iPv6Address.toString());
nic.setIPv6Cidr(ip6Cidr);
nic.setIPv6Gateway(ip6Gateway);
_nicDao.update(nic.getId(), nic);
}
}
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_MIGRATE, eventDescription = "migrating network", async = true)
public Network migrateGuestNetwork(long networkId, long networkOfferingId, Account callerAccount, User callerUser, boolean resume) {
@ -5308,5 +5386,4 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress};
}
}

View File

@ -17,6 +17,7 @@
package com.cloud.network.firewall;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@ -28,6 +29,7 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.command.user.firewall.IListFirewallRulesCmd;
import org.apache.cloudstack.api.command.user.ipv6.ListIpv6FirewallRulesCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@ -341,8 +343,15 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
sc.setParameters("networkId", networkId);
}
if (cmd instanceof ListIpv6FirewallRulesCmd) {
sc.setParameters("purpose", Purpose.Ipv6Firewall);
} else {
sc.setParameters("purpose", Purpose.Firewall);
}
if (trafficType != null) {
sc.setParameters("trafficType", trafficType);
}
Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
@ -555,7 +564,14 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
return true;
}
Purpose purpose = rules.get(0).getPurpose();
if (!_ipAddrMgr.applyRules(rules, purpose, this, continueOnError)) {
boolean applied;
if (purpose.equals(Purpose.Ipv6Firewall)) {
Network network = _networkDao.findById(rules.get(0).getNetworkId());
applied = applyRules(network, purpose, rules);
} else {
applied = _ipAddrMgr.applyRules(rules, purpose, this, continueOnError);
}
if (!applied) {
s_logger.warn("Rules are not completely applied");
return false;
} else {
@ -594,6 +610,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
/* StaticNatRule would be applied by Firewall provider, since the incompatible of two object */
case StaticNat:
case Firewall:
case Ipv6Firewall:
for (FirewallServiceProvider fwElement : _firewallElements) {
Network.Provider provider = fwElement.getProvider();
boolean isFwProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider);
@ -726,10 +743,9 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
}
protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {
FirewallRuleVO rule = _firewallDao.findById(ruleId);
if (rule == null || rule.getPurpose() != Purpose.Firewall) {
throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
if (rule == null || !Arrays.asList(Purpose.Firewall, Purpose.Ipv6Firewall).contains(rule.getPurpose())) {
throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Arrays.asList(Purpose.Firewall, Purpose.Ipv6Firewall));
}
if (rule.getType() == FirewallRuleType.System && !_accountMgr.isRootAdmin(caller.getId())) {
@ -751,7 +767,11 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
return applyFirewallRules(rules, false, caller);
//egress firewall rule
} else if (networkId != null) {
List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
boolean isIpv6 = Purpose.Ipv6Firewall.equals(rule.getPurpose());
List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), rule.getPurpose(), FirewallRule.TrafficType.Egress);
if (isIpv6) {
rules.addAll(_firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Ipv6Firewall, FirewallRule.TrafficType.Ingress));
}
return applyFirewallRules(rules, false, caller);
}
} else {

View File

@ -36,6 +36,7 @@ import com.cloud.event.EventTypes;
import com.cloud.event.EventVO;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
@ -122,6 +123,20 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
/* In order to revert userSpecified network setup */
config.setState(State.Allocated);
}
if (userSpecified == null) {
return config;
}
if ((userSpecified.getIp6Cidr() == null && userSpecified.getIp6Gateway() != null) ||
(userSpecified.getIp6Cidr() != null && userSpecified.getIp6Gateway() == null)) {
throw new InvalidParameterValueException("ip6gateway and ip6cidr must be specified together.");
}
if (userSpecified.getIp6Cidr() != null) {
config.setIp6Cidr(userSpecified.getIp6Cidr());
config.setIp6Gateway(userSpecified.getIp6Gateway());
}
if (userSpecified.getRouterIpv6() != null) {
config.setRouterIpv6(userSpecified.getRouterIpv6());
}
return config;
}

View File

@ -44,6 +44,7 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Ipv6AddressManager;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.Provider;
@ -51,6 +52,7 @@ import com.cloud.network.Network.Service;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks;
import com.cloud.network.Networks.AddressFormat;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
@ -66,6 +68,7 @@ import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.server.ConfigurationServer;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@ -76,12 +79,14 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGuru, Configurable {
@ -111,6 +116,13 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
ConfigurationServer _configServer;
@Inject
IpAddressManager _ipAddrMgr;
@Inject
NetworkOfferingDao networkOfferingDao;
@Inject
Ipv6AddressManager ipv6AddressManager;
@Inject
DomainRouterDao domainRouterDao;
Random _rand = new Random(System.currentTimeMillis());
public static final ConfigKey<Boolean> UseSystemGuestVlans =
@ -135,6 +147,29 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
_isolationMethods = null;
}
private void updateNicIpv6(Network network, NicProfile nic, VirtualMachineProfile vm, DataCenter dc, boolean isGateway) throws InsufficientAddressCapacityException {
boolean isIpv6Supported = networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId());
if (!isIpv6Supported || nic.getIPv6Address() != null || network.getIp6Cidr() == null || network.getIp6Gateway() == null) {
return;
}
if (isGateway) {
nic.setIPv6Cidr(network.getIp6Cidr());
nic.setIPv6Gateway(network.getIp6Gateway());
if (nic.getIPv4Address() != null) {
nic.setFormat(Networks.AddressFormat.DualStack);
} else {
nic.setFormat(Networks.AddressFormat.Ip6);
}
DomainRouterVO router = domainRouterDao.findById(vm.getId());
if (router != null &&
router.getIsRedundantRouter()) {
return;
}
nic.setIPv6Address(network.getIp6Gateway());
}
ipv6AddressManager.setNicIp6Address(nic, dc, network);
}
@Override
public boolean isMyTrafficType(final TrafficType type) {
for (final TrafficType t : TrafficTypes) {
@ -349,17 +384,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
final DataCenter dc = _dcDao.findById(network.getDataCenterId());
if (nic.getIPv4Address() == null) {
nic.setBroadcastUri(network.getBroadcastUri());
nic.setIsolationUri(network.getBroadcastUri());
nic.setIPv4Gateway(network.getGateway());
String guestIp = null;
if (network.getSpecifyIpRanges()) {
_ipAddrMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIPv4(), null);
} else {
//if Vm is router vm and source nat is enabled in the network, set ip4 to the network gateway
boolean isGateway = false;
//if Vm is router vm and source nat is enabled in the network, set ip4 to the network gateway
if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
if (network.getVpcId() != null) {
final Vpc vpc = _vpcDao.findById(network.getVpcId());
@ -374,6 +400,15 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
}
}
if (nic.getIPv4Address() == null) {
nic.setBroadcastUri(network.getBroadcastUri());
nic.setIsolationUri(network.getBroadcastUri());
nic.setIPv4Gateway(network.getGateway());
String guestIp = null;
if (network.getSpecifyIpRanges()) {
_ipAddrMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIPv4(), null);
} else {
if (isGateway) {
guestIp = network.getGateway();
} else {
@ -416,7 +451,7 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());
}
}
updateNicIpv6(network, nic, vm, dc, isGateway);
return nic;
}

View File

@ -31,6 +31,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Ipv6Service;
import com.cloud.network.Network;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkProfile;
@ -70,6 +71,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
IPAddressDao _ipAddressDao;
@Inject
IpAddressManager _ipAddrMgr;
@Inject
Ipv6Service ipv6Service;
private static final TrafficType[] TrafficTypes = {TrafficType.Public};
@ -139,6 +142,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
ipv6Service.updateNicIpv6(nic, dc, network);
}
@Override

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