GutoVeronezi commented on a change in pull request #5594: URL: https://github.com/apache/cloudstack/pull/5594#discussion_r732828215
########## File path: api/src/main/java/com/cloud/network/Ipv6Address.java ########## @@ -0,0 +1,95 @@ +// 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 com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.api.Displayable; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +import org.apache.commons.lang.StringUtils; Review comment: Recently we finished a voting defining `commons.lang3` as the default string lib ([VOTE thread](https://lists.apache.org/thread.html/r806cd10b3de645c150e5e0e3d845c5a380a700197143f57f0834d758%40%3Cdev.cloudstack.apache.org%3E) & [RESULT thread](https://lists.apache.org/thread.html/r5898f717d506a0e160b9dc766b65769e2fe2f07f9cba70825843e272%40%3Cdev.cloudstack.apache.org%3E)). The code is being changed with PR 5386 and the docs were changed (https://cwiki.apache.org/confluence/display/CLOUDSTACK/Coding+conventions). In this case, `org.apache.commons.lang.StringUtils` should be replaced with `org.apache.commons.lang3.StringUtils`, as we're only using method `isBlank`. ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,221 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.utils.net.NetUtils; + +@APICommand(name = "createIpv6FirewallRule", 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()); + + private static final String s_name = "createipv6firewallruleresponse"; + + // /////////////////////////////////////////////////// + // ////////////// 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 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.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the Ipv6 firewall rule will be created for") + 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", since = "4.4", 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.trim(); + // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code + if (StringUtils.isNumeric(p)) { + int protoNumber = Integer.parseInt(p); + if (protoNumber == 1) { + p = "icmp"; + } + } + return p; + } + + public List<String> getSourceCidrList() { + if (cidrlist != null) { + return cidrlist; + } else { Review comment: We could remove the `else` statements, as the condition already returns something. ########## File path: server/src/main/java/com/cloud/network/router/CommandSetupHelper.java ########## @@ -179,6 +183,10 @@ private RouterControlHelper _routerControlHelper; @Inject private HostDao _hostDao; + @Inject + Ipv6Service _ipv6Service; + @Inject + DataCenterIpv6AddressDao _ipv6AddressDao; Review comment: Is this prefix `_` needed? ########## File path: api/src/main/java/org/apache/cloudstack/api/command/admin/ipv6/CreateIpv6RangeCmd.java ########## @@ -0,0 +1,136 @@ +// 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.ipv6; + +import com.cloud.network.Ipv6Address; +import com.cloud.utils.net.NetUtils; +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; + +import org.apache.cloudstack.api.response.PhysicalNetworkResponse; +import org.apache.cloudstack.api.response.Ipv6RangeResponse; +import org.apache.cloudstack.api.response.ZoneResponse; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.user.Account; + +@APICommand(name = "createIpv6Range", description = "Creates an IPv6 range.", responseObject = Ipv6RangeResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class CreateIpv6RangeCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(CreateIpv6RangeCmd.class.getName()); + + public static final String APINAME = "createIpv6Range"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, required = true, entityType = ZoneResponse.class, description = "the Zone ID of the IPv6 range") + private Long zoneId; + + @Parameter(name = ApiConstants.PHYSICAL_NETWORK_ID, type = CommandType.UUID, required = true, entityType = PhysicalNetworkResponse.class, description = "the physical network id") + private Long physicalNetworkId; + + @Parameter(name = ApiConstants.IP6_GATEWAY, type = CommandType.STRING, required = true, description = "the gateway of the IPv6 network.") + private String ip6Gateway; + + @Parameter(name = ApiConstants.IP6_CIDR, type = CommandType.STRING, required = true, description = "the CIDR of IPv6 network, must be at least /64") + private String ip6Cidr; + + @Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, required = false, description = "the Management IPv6 address of virtual router") + private String routerIpv6; + + @Parameter(name = ApiConstants.ROUTER_IPV6_GATEWAY, type = CommandType.STRING, required = true, description = "the gateway of Management IPv6 network of virtual router") + private String routerIpv6Gateway; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getZoneId() { + return zoneId; + } + + public Long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getIp6Gateway() { + if (ip6Gateway == null) { + return null; + } + return NetUtils.standardizeIp6Address(ip6Gateway); + } + + public String getIp6Cidr() { + if (ip6Cidr == null) { + return null; + } + return NetUtils.standardizeIp6Cidr(ip6Cidr); + } + + public String getRouterIpv6() { + if (routerIpv6 == null) { + return null; + } + return NetUtils.standardizeIp6Address(routerIpv6); + } + + public String getRouterIpv6Gateway() { + if (routerIpv6Gateway == null) { + return null; + } + return NetUtils.standardizeIp6Address(routerIpv6Gateway); + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; Review comment: Seems like this code repeats along several classes, could we extract it to a method? ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,221 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.utils.net.NetUtils; + +@APICommand(name = "createIpv6FirewallRule", 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()); + + private static final String s_name = "createipv6firewallruleresponse"; + + // /////////////////////////////////////////////////// + // ////////////// 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 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.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the Ipv6 firewall rule will be created for") + 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", since = "4.4", 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.trim(); + // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code + if (StringUtils.isNumeric(p)) { + int protoNumber = Integer.parseInt(p); + if (protoNumber == 1) { + p = "icmp"; + } + } + return p; + } + + public List<String> getSourceCidrList() { + if (cidrlist != null) { + return cidrlist; + } else { + List<String> oneCidrList = new ArrayList<String>(); + oneCidrList.add(NetUtils.ALL_IP4_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 s_name; + } + + 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() { + Account caller = CallContext.current().getCallingAccount(); + return caller.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; Review comment: This code could be extracted to a method, as it repeats right below, but changing the parameter. ########## File path: api/src/main/java/com/cloud/network/Ipv6Address.java ########## @@ -0,0 +1,95 @@ +// 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 com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.api.Displayable; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +import org.apache.commons.lang.StringUtils; + +/** + * + * - Allocated = null + * - AccountId = null + * - DomainId = null + * + * - State = Allocated + * - AccountId = account owner. + * - DomainId = domain of the account owner. + * - Allocated = time it was allocated. + */ +public interface Ipv6Address extends Identity, InternalIdentity, Displayable { + + enum InternetProtocol { + IPv4, IPv6, DualStack; + + public static InternetProtocol fromValue(String protocol) { + if (StringUtils.isBlank(protocol)) { + return null; + } else if (protocol.equalsIgnoreCase("IPv4")) { + return IPv4; + } else if (protocol.equalsIgnoreCase("IPv6")) { + return IPv6; + } else if (protocol.equalsIgnoreCase("DualStack")) { + return DualStack; + } else { + throw new InvalidParameterValueException("Unexpected Internet Protocol : " + protocol); + } + } + } + + enum IPv6Routing { + Static, Dynamic; + + public static IPv6Routing fromValue(String mode) { + if (StringUtils.isBlank(mode)) { + return null; + } else if (mode.equalsIgnoreCase("Static")) { + return Static; + } else if (mode.equalsIgnoreCase("Dynamic")) { + return Dynamic; + } else { + throw new InvalidParameterValueException("Unexpected IPv6 routing mode : " + mode); + } Review comment: We could remove the `else` statements, as every condition already returns something. ########## File path: server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java ########## @@ -18,19 +18,23 @@ import javax.inject.Inject; + Review comment: Is this extra line necessary? ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,221 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.utils.net.NetUtils; + +@APICommand(name = "createIpv6FirewallRule", 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()); + + private static final String s_name = "createipv6firewallruleresponse"; + + // /////////////////////////////////////////////////// + // ////////////// 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 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.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the Ipv6 firewall rule will be created for") + 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", since = "4.4", 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.trim(); + // Deal with ICMP(protocol number 1) specially because it need to be paired with icmp type and code Review comment: Could you add this comment as javadoc or extract the code to a method with an intuitive name? ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,221 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; +import com.cloud.utils.net.NetUtils; + +@APICommand(name = "createIpv6FirewallRule", 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()); + + private static final String s_name = "createipv6firewallruleresponse"; + + // /////////////////////////////////////////////////// + // ////////////// 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 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.NETWORK_ID, type = CommandType.UUID, entityType = NetworkResponse.class, description = "The network of the VM the Ipv6 firewall rule will be created for") + 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", since = "4.4", authorized = { + RoleType.Admin}) + private Boolean display; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + @Override + public boolean isDisplay() { + if (display != null) { + return display; + } else { + return true; + } Review comment: We could use `org.apache.commons.lang3.BooleanUtils` here: ```suggestion return BooleanUtils.toBooleanDefaultIfNull(display, true); ``` ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/ListIpv6FirewallRulesCmd.java ########## @@ -0,0 +1,130 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.user.ipv6; + +import java.util.ArrayList; +import java.util.List; + +import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.Pair; +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.ListResponse; +import org.apache.cloudstack.api.response.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.log4j.Logger; + +@APICommand(name = "listIpv6FirewallRules", 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()); + + private static final String s_name = "listipv6firewallrulesresponse"; + + ///////////////////////////////////////////////////// + //////////////// 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.PROTOCOL, type = CommandType.STRING, description = "list ipv6 firewall rules by protocol") + private String protocol; + + @Parameter(name = ApiConstants.ACTION, type = CommandType.STRING, description = "list ipv6 firewall rules by action: allow or deny") + private String action; + + @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "list resources by display flag; only ROOT admin is eligible to pass this parameter", since = "4.4", 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; + } + + public String getProtocol() { + return protocol; + } + + public String getAction() { + return action; + } + + @Override + public Boolean getDisplay() { + if (display != null) { + return display; + } + return super.getDisplay(); Review comment: We could use `org.apache.commons.lang3.BooleanUtils` here: ```suggestion return BooleanUtils.toBooleanDefaultIfNull(display, super.getDisplay()); ``` ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/CreateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,221 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.FirewallRuleResponse; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.commons.lang.StringUtils; Review comment: Having in mind PR #5386, we should use `commons.lang3`. ########## File path: api/src/main/java/com/cloud/network/Ipv6Address.java ########## @@ -0,0 +1,95 @@ +// 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 com.cloud.exception.InvalidParameterValueException; +import org.apache.cloudstack.api.Displayable; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +import org.apache.commons.lang.StringUtils; + +/** + * + * - Allocated = null + * - AccountId = null + * - DomainId = null + * + * - State = Allocated + * - AccountId = account owner. + * - DomainId = domain of the account owner. + * - Allocated = time it was allocated. + */ +public interface Ipv6Address extends Identity, InternalIdentity, Displayable { + + enum InternetProtocol { + IPv4, IPv6, DualStack; + + public static InternetProtocol fromValue(String protocol) { + if (StringUtils.isBlank(protocol)) { + return null; + } else if (protocol.equalsIgnoreCase("IPv4")) { + return IPv4; + } else if (protocol.equalsIgnoreCase("IPv6")) { + return IPv6; + } else if (protocol.equalsIgnoreCase("DualStack")) { + return DualStack; + } else { + throw new InvalidParameterValueException("Unexpected Internet Protocol : " + protocol); + } Review comment: We could remove the `else` statements, as every condition already returns something. ########## File path: engine/schema/src/main/java/com/cloud/dc/DataCenterIpv6AddressVO.java ########## @@ -0,0 +1,176 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.dc; + +import com.cloud.network.Ipv6Address; + +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 java.util.Date; +import java.util.UUID; + +@Entity +@Table(name = "dc_ipv6_range") +public class DataCenterIpv6AddressVO implements Ipv6Address { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name = "uuid") + String uuid = UUID.randomUUID().toString(); + + @Column(name = "data_center_id", updatable = false, nullable = false) + long dataCenterId; + + @Column(name = "physical_network_id") + Long physicalNetworkId; + + @Column(name = "ip6_gateway") + String ip6Gateway; + + @Column(name = "ip6_cidr") + String ip6Cidr; + + @Column(name = "router_ipv6") + String routerIpv6; + + @Column(name = "router_ipv6_gateway") + String routerIpv6Gateway; + + @Column(name = "network_id") + Long networkId; + + @Column(name = "domain_id") + Long domainId; + + @Column(name = "account_id") + Long accountId; + + @Column(name = "taken") + @Temporal(value = TemporalType.TIMESTAMP) + private Date takenAt; + + public DataCenterIpv6AddressVO() { + } + + public DataCenterIpv6AddressVO(long dcId, long physicalNetworkId, String ip6Gateway, String ip6Cidr, String routerIpv6, String routerIpv6Gateway) { + this.dataCenterId = dcId; + this.physicalNetworkId = physicalNetworkId; + this.ip6Gateway = ip6Gateway; + this.ip6Cidr = ip6Cidr; + this.routerIpv6 = routerIpv6; + this.routerIpv6Gateway = routerIpv6Gateway; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { return uuid; }; + + @Override + public long getDataCenterId() { + return dataCenterId; + } + + @Override + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + @Override + public String getIp6Gateway() { + return ip6Gateway; + } + + public void setIp6Gateway(String ip6Gateway) { + this.ip6Gateway = ip6Gateway; + } + + @Override + public String getIp6Cidr() { + return ip6Cidr; + } + + public void setIp6Cidr(String ip6Cidr) { + this.ip6Cidr = ip6Cidr; + } + + @Override + public String getRouterIpv6() { + return routerIpv6; + } + + public void setRouterIpv6(String routerIpv6) { + this.routerIpv6 = routerIpv6; + } + + @Override + public String getRouterIpv6Gateway() { + return routerIpv6Gateway; + } + + public void setRouterIpv6Gateway(String routerIpv6Gateway) { + this.routerIpv6Gateway = routerIpv6Gateway; + } + + @Override + public Long getDomainId() { + return domainId; + } + + @Override + public Long getAccountId() { + return accountId; + } + + public Long getNetworkId() { return networkId; } + + public void setNetworkId(Long networkId) { this.networkId = networkId; } Review comment: Is this block according to our coding convention? ########## File path: server/src/main/java/com/cloud/network/Ipv6ServiceImpl.java ########## @@ -0,0 +1,382 @@ +// 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 com.cloud.api.ApiDBUtils; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterIpv6AddressVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterIpv6AddressDao; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Ipv6Address.IPv6Routing; +import com.cloud.network.Ipv6Address.InternetProtocol; +import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.firewall.FirewallService; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.vpc.VpcVO; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDetailsDao; +import com.cloud.projects.Project; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.PluggableService; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.NicProfile; +import com.googlecode.ipv6.IPv6Address; +import org.apache.cloudstack.api.command.admin.ipv6.CreateIpv6RangeCmd; +import org.apache.cloudstack.api.command.admin.ipv6.DedicateIpv6RangeCmd; +import org.apache.cloudstack.api.command.admin.ipv6.DeleteIpv6RangeCmd; +import org.apache.cloudstack.api.command.admin.ipv6.ListIpv6RangesCmd; +import org.apache.cloudstack.api.command.admin.ipv6.ReleaseIpv6RangeCmd; +import org.apache.cloudstack.api.command.admin.ipv6.UpdateIpv6RangeCmd; +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.Ipv6RangeResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.log4j.Logger; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +public class Ipv6ServiceImpl implements Ipv6Service, PluggableService, Configurable { + + public static final Logger s_logger = Logger.getLogger(Ipv6ServiceImpl.class.getName()); + + @Inject + AccountManager _accountMgr; + @Inject + DataCenterIpv6AddressDao _ipv6AddressDao; + @Inject + AccountDao _accountDao; + @Inject + DomainDao _domainDao; + @Inject + NetworkOfferingDetailsDao _networkOfferingDetailsDao; + @Inject + FirewallRulesDao _firewallDao; + @Inject + public FirewallService _firewallService; Review comment: Is the prefix `_` needed? ########## File path: engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java ########## @@ -321,6 +323,10 @@ ResourceManager resourceManager; @Inject private AnnotationDao annotationDao; + @Inject + Ipv6Service _ipv6Service; Review comment: Is the prefix `_` needed? ########## File path: server/src/main/java/com/cloud/network/guru/ExternalGuestNetworkGuru.java ########## @@ -120,6 +121,20 @@ public Network design(NetworkOffering offering, DeploymentPlan plan, Network use config.setState(State.Allocated); } + if (userSpecified != null) { Review comment: We could invert this condition to void code indentation. ########## File path: engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java ########## @@ -321,6 +323,10 @@ ResourceManager resourceManager; @Inject private AnnotationDao annotationDao; + @Inject + Ipv6Service _ipv6Service; + @Inject + DataCenterIpv6AddressDao _ipv6AddressDao; Review comment: Is the prefix `_` needed? ########## File path: server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java ########## @@ -110,6 +113,11 @@ ConfigurationServer _configServer; @Inject IpAddressManager _ipAddrMgr; + @Inject + Ipv6Service _ipv6Service; + @Inject + Ipv6AddressManager _ipv6Mgr; Review comment: Is this prefix `_` needed? ########## File path: server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java ########## @@ -5623,8 +5628,24 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) forVpc = false; } + if ((guestType == GuestType.Shared) && (internetProtocol != null || ipv6Routing != null)) { + throw new InvalidParameterValueException("internetProtocol and ipv6Routing are only available for isolated networks and VPCs"); + } else if (guestType == GuestType.Isolated) { Review comment: We could remove the `else` statement, as the condition already throws something. ########## File path: api/src/main/java/org/apache/cloudstack/api/command/user/ipv6/UpdateIpv6FirewallRuleCmd.java ########## @@ -0,0 +1,170 @@ +// 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 com.cloud.network.rules.FirewallRule; +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.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.user.Account; + +@APICommand(name = "updateIpv6FirewallRule", 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()); + + private static final String s_name = "createipv6firewallruleresponse"; + + // /////////////////////////////////////////////////// + // ////////////// 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; + } Review comment: We could use `org.apache.commons.lang3.BooleanUtils` here: ```suggestion return BooleanUtils.toBooleanDefaultIfNull(display, true); ``` ########## File path: engine/schema/src/main/java/com/cloud/dc/DataCenterIpv6AddressVO.java ########## @@ -0,0 +1,176 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.dc; + +import com.cloud.network.Ipv6Address; + +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 java.util.Date; +import java.util.UUID; + +@Entity +@Table(name = "dc_ipv6_range") +public class DataCenterIpv6AddressVO implements Ipv6Address { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name = "uuid") + String uuid = UUID.randomUUID().toString(); + + @Column(name = "data_center_id", updatable = false, nullable = false) + long dataCenterId; + + @Column(name = "physical_network_id") + Long physicalNetworkId; + + @Column(name = "ip6_gateway") + String ip6Gateway; + + @Column(name = "ip6_cidr") + String ip6Cidr; + + @Column(name = "router_ipv6") + String routerIpv6; + + @Column(name = "router_ipv6_gateway") + String routerIpv6Gateway; + + @Column(name = "network_id") + Long networkId; + + @Column(name = "domain_id") + Long domainId; + + @Column(name = "account_id") + Long accountId; + + @Column(name = "taken") + @Temporal(value = TemporalType.TIMESTAMP) + private Date takenAt; + + public DataCenterIpv6AddressVO() { + } + + public DataCenterIpv6AddressVO(long dcId, long physicalNetworkId, String ip6Gateway, String ip6Cidr, String routerIpv6, String routerIpv6Gateway) { + this.dataCenterId = dcId; + this.physicalNetworkId = physicalNetworkId; + this.ip6Gateway = ip6Gateway; + this.ip6Cidr = ip6Cidr; + this.routerIpv6 = routerIpv6; + this.routerIpv6Gateway = routerIpv6Gateway; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { return uuid; }; + + @Override + public long getDataCenterId() { + return dataCenterId; + } + + @Override + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + @Override + public String getIp6Gateway() { + return ip6Gateway; + } + + public void setIp6Gateway(String ip6Gateway) { + this.ip6Gateway = ip6Gateway; + } + + @Override + public String getIp6Cidr() { + return ip6Cidr; + } + + public void setIp6Cidr(String ip6Cidr) { + this.ip6Cidr = ip6Cidr; + } + + @Override + public String getRouterIpv6() { + return routerIpv6; + } + + public void setRouterIpv6(String routerIpv6) { + this.routerIpv6 = routerIpv6; + } + + @Override + public String getRouterIpv6Gateway() { + return routerIpv6Gateway; + } + + public void setRouterIpv6Gateway(String routerIpv6Gateway) { + this.routerIpv6Gateway = routerIpv6Gateway; + } + + @Override + public Long getDomainId() { + return domainId; + } + + @Override + public Long getAccountId() { + return accountId; + } + + public Long getNetworkId() { return networkId; } Review comment: Is this block according to our coding convention? ########## File path: server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java ########## @@ -5623,8 +5628,24 @@ public NetworkOffering createNetworkOffering(final CreateNetworkOfferingCmd cmd) forVpc = false; } + if ((guestType == GuestType.Shared) && (internetProtocol != null || ipv6Routing != null)) { Review comment: Unnecessary parentheses on `(guestType == GuestType.Shared)`. ########## File path: engine/schema/src/main/java/com/cloud/dc/dao/DataCenterIpv6AddressDaoImpl.java ########## @@ -0,0 +1,196 @@ +// 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.Date; +import java.util.List; + +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.dc.DataCenterIpv6AddressVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Component Review comment: As you already added this class to bean, this annotation is necessary? ########## File path: server/src/main/java/com/cloud/network/router/CommandSetupHelper.java ########## @@ -1041,6 +1058,34 @@ public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRoute return setupCmd; } + private void updateSetupGuestNetworkCommandIpv6(SetupGuestNetworkCommand setupCmd, Network network, String macAddress, String defaultIp6Dns1, String defaultIp6Dns2) { + boolean isIpv6Supported = _ipv6Service.isIpv6Supported(network.getNetworkOfferingId()); + if (isIpv6Supported) { Review comment: We could invert this condition to reduce code indentation. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
