Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ envDSLTree
test/zstack-integration-test-result/
premium/test-premium/zstack-api.log
**/bin/
CLAUDE.md
110 changes: 106 additions & 4 deletions compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.zstack.header.message.APIMessage;
import org.zstack.header.message.MessageReply;
import org.zstack.header.network.l3.*;
import org.zstack.network.l3.L3NetworkSystemTags;
import org.zstack.header.tag.SystemTagCreateMessageValidator;
import org.zstack.header.tag.SystemTagVO;
import org.zstack.header.tag.SystemTagVO_;
Expand All @@ -30,6 +31,7 @@

import javax.persistence.Tuple;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -134,6 +136,17 @@ public Map<String, NicIpAddressInfo> getNicNetworkInfoBySystemTag(List<String> s
}
ret.get(l3Uuid).ipv6Prefix = token.get(VmSystemTags.IPV6_PREFIX_TOKEN);
}
if(L3NetworkSystemTags.STATIC_DNS.isMatch(sysTag)) {
Map<String, String> token = TagUtils.parse(L3NetworkSystemTags.STATIC_DNS.getTagFormat(), sysTag);
String l3Uuid = token.get(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN);
if (ret.get(l3Uuid) == null) {
continue;
}
String dnsStr = token.get(L3NetworkSystemTags.STATIC_DNS_TOKEN);
if (dnsStr != null && !dnsStr.isEmpty()) {
ret.get(l3Uuid).dnsAddresses = Arrays.asList(dnsStr.split(","));
}
Comment on lines +139 to +148
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

DNS 入参需 trim 且 IPv6 需做 tag 编码/解码

dnsAddresses 可能含空格/换行,直接校验会误判;另外 IPv6 若直接写入 system tag,含 “::” 的地址在解析时可能被截断,建议写入前编码、读取时解码。

🔧 建议修改
-        // Validate DNS addresses
-        for (String dns : dnsAddresses) {
-            if (!NetworkUtils.isIpv4Address(dns) && !IPv6NetworkUtils.isIpv6Address(dns)) {
-                throw new ApiMessageInterceptionException(argerr(
-                        "invalid DNS address[%s], must be a valid IPv4 or IPv6 address", dns));
-            }
-        }
-
-        String dnsStr = String.join(",", dnsAddresses);
+        // Validate DNS addresses
+        List<String> normalizedDns = new ArrayList<>();
+        for (String dns : dnsAddresses) {
+            String trimmed = dns == null ? null : dns.trim();
+            if (StringUtils.isEmpty(trimmed)) {
+                continue;
+            }
+            if (!NetworkUtils.isIpv4Address(trimmed) && !IPv6NetworkUtils.isIpv6Address(trimmed)) {
+                throw new ApiMessageInterceptionException(argerr(
+                        "invalid DNS address[%s], must be a valid IPv4 or IPv6 address", trimmed));
+            }
+            if (IPv6NetworkUtils.isIpv6Address(trimmed)) {
+                trimmed = IPv6NetworkUtils.ipv6AddessToTagValue(trimmed);
+            }
+            normalizedDns.add(trimmed);
+        }
+
+        String dnsStr = String.join(",", normalizedDns);
-                if (dnsStr != null && !dnsStr.isEmpty()) {
-                    ret.get(l3Uuid).dnsAddresses = Arrays.asList(dnsStr.split(","));
-                }
+                if (dnsStr != null && !dnsStr.isEmpty()) {
+                    List<String> dnsList = new ArrayList<>();
+                    for (String dns : dnsStr.split(",")) {
+                        dnsList.add(IPv6NetworkUtils.ipv6TagValueToAddress(dns));
+                    }
+                    ret.get(l3Uuid).dnsAddresses = dnsList;
+                }
-                    return Arrays.asList(dnsStr.split(","));
+                    List<String> dnsList = new ArrayList<>();
+                    for (String dns : dnsStr.split(",")) {
+                        dnsList.add(IPv6NetworkUtils.ipv6TagValueToAddress(dns));
+                    }
+                    return dnsList;

As per coding guidelines: 注意检查来自 Message 的参数是否做过 trim,用户可能在浏览器上复制粘贴的数据带有空格、换行符等。

Also applies to: 244-275, 289-292

🤖 Prompt for AI Agents
In `@compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java` around
lines 139 - 148, In StaticIpOperator (the block handling
L3NetworkSystemTags.STATIC_DNS), trim and sanitize the parsed dns string before
splitting: after obtaining dnsStr from the tag, run a trim, remove any internal
newlines/extra whitespace, split on commas, then trim each token and filter out
empty strings before assigning to dnsAddresses; additionally, support IPv6-safe
storage by decoding the tag value when reading (and ensure callers encode IPv6
addresses when writing) using the project’s system-tag encode/decode utilities
so addresses containing "::" are preserved. Apply the same trimming/decoding
logic for the other similar parsing sites referenced around lines 244-275 and
289-292.

}
}

return ret;
Expand Down Expand Up @@ -222,6 +235,66 @@ public void deleteStaticIpByL3NetworkUuid(String l3Uuid) {
)));
}

public void setStaticDns(String vmUuid, String l3Uuid, List<String> dnsAddresses) {
if (dnsAddresses == null || dnsAddresses.isEmpty()) {
deleteStaticDnsByVmUuidAndL3Uuid(vmUuid, l3Uuid);
return;
}

// Validate DNS addresses
for (String dns : dnsAddresses) {
if (!NetworkUtils.isIpv4Address(dns) && !IPv6NetworkUtils.isIpv6Address(dns)) {
throw new ApiMessageInterceptionException(argerr(
"invalid DNS address[%s], must be a valid IPv4 or IPv6 address", dns));
}
}

String dnsStr = String.join(",", dnsAddresses);

SimpleQuery<SystemTagVO> q = dbf.createQuery(SystemTagVO.class);
q.select(SystemTagVO_.uuid);
q.add(SystemTagVO_.resourceType, Op.EQ, VmInstanceVO.class.getSimpleName());
q.add(SystemTagVO_.resourceUuid, Op.EQ, vmUuid);
q.add(SystemTagVO_.tag, Op.LIKE, TagUtils.tagPatternToSqlPattern(L3NetworkSystemTags.STATIC_DNS.instantiateTag(
map(e(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN, l3Uuid))
)));
String tagUuid = q.findValue();

if (tagUuid == null) {
SystemTagCreator creator = L3NetworkSystemTags.STATIC_DNS.newSystemTagCreator(vmUuid);
creator.setTagByTokens(map(
e(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN, l3Uuid),
e(L3NetworkSystemTags.STATIC_DNS_TOKEN, dnsStr)
));
creator.create();
} else {
L3NetworkSystemTags.STATIC_DNS.updateByTagUuid(tagUuid, L3NetworkSystemTags.STATIC_DNS.instantiateTag(map(
e(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN, l3Uuid),
e(L3NetworkSystemTags.STATIC_DNS_TOKEN, dnsStr)
)));
}
}

public void deleteStaticDnsByVmUuidAndL3Uuid(String vmUuid, String l3Uuid) {
L3NetworkSystemTags.STATIC_DNS.delete(vmUuid, TagUtils.tagPatternToSqlPattern(L3NetworkSystemTags.STATIC_DNS.instantiateTag(
map(e(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN, l3Uuid))
)));
}

public List<String> getStaticDnsByVmUuidAndL3Uuid(String vmUuid, String l3Uuid) {
List<Map<String, String>> tokenList = L3NetworkSystemTags.STATIC_DNS.getTokensOfTagsByResourceUuid(vmUuid);
for (Map<String, String> tokens : tokenList) {
String uuid = tokens.get(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN);
if (uuid.equals(l3Uuid)) {
String dnsStr = tokens.get(L3NetworkSystemTags.STATIC_DNS_TOKEN);
if (dnsStr != null && !dnsStr.isEmpty()) {
return Arrays.asList(dnsStr.split(","));
}
}
}
return null;
}
Comment on lines +284 to +296
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

潜在空指针异常

Line 288: uuid.equals(l3Uuid)uuid 可能为 null(如果 token 中没有该 key),会导致 NPE。建议使用 l3Uuid.equals(uuid) 或进行 null 检查。

另外,Line 295 返回 null 而非空列表,与其他类似方法(如 getStaticIpbyVmUuid)返回空集合的模式不一致。

🛡️ 修复建议
 public List<String> getStaticDnsByVmUuidAndL3Uuid(String vmUuid, String l3Uuid) {
     List<Map<String, String>> tokenList = L3NetworkSystemTags.STATIC_DNS.getTokensOfTagsByResourceUuid(vmUuid);
     for (Map<String, String> tokens : tokenList) {
         String uuid = tokens.get(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN);
-        if (uuid.equals(l3Uuid)) {
+        if (l3Uuid.equals(uuid)) {
             String dnsStr = tokens.get(L3NetworkSystemTags.STATIC_DNS_TOKEN);
             if (dnsStr != null && !dnsStr.isEmpty()) {
                 return Arrays.asList(dnsStr.split(","));
             }
         }
     }
-    return null;
+    return new ArrayList<>();
 }
🤖 Prompt for AI Agents
In `@compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java` around
lines 284 - 296, In getStaticDnsByVmUuidAndL3Uuid, make the l3Uuid comparison
null-safe and return an empty list instead of null: guard against
tokens.get(L3NetworkSystemTags.STATIC_DNS_L3_UUID_TOKEN) being null by using
l3Uuid.equals(uuid) or an explicit null check before comparing, and change the
method to return Collections.emptyList() (or new ArrayList<>()) when no DNS
entries are found to match the behavior of getStaticIpbyVmUuid; update
references to L3NetworkSystemTags.STATIC_DNS_TOKEN handling accordingly.


public Map<Integer, String> getNicStaticIpMap(List<String> nicStaticIpList) {
Map<Integer, String> nicStaticIpMap = new HashMap<>();
if (nicStaticIpList != null) {
Expand Down Expand Up @@ -264,6 +337,11 @@ public boolean isIpChange(String vmUuid, String l3Uuid) {
}

public Boolean checkIpRangeConflict(VmNicVO nicVO){
// If global config allows IP outside range, skip the conflict check
if (VmGlobalConfig.ALLOW_IP_OUTSIDE_RANGE.value(Boolean.class)) {
return Boolean.FALSE;
}

if (Q.New(IpRangeVO.class).eq(IpRangeVO_.l3NetworkUuid, nicVO.getL3NetworkUuid()).list().isEmpty()) {
return Boolean.FALSE;
}
Expand Down Expand Up @@ -321,6 +399,8 @@ public void validateSystemTagInCreateMessage(APICreateMessage msg) {

public List<String> fillUpStaticIpInfoToVmNics(Map<String, NicIpAddressInfo> staticIps) {
List<String> newSystags = new ArrayList<>();
boolean allowOutsideRange = VmGlobalConfig.ALLOW_IP_OUTSIDE_RANGE.value(Boolean.class);

for (Map.Entry<String, NicIpAddressInfo> e : staticIps.entrySet()) {
String l3Uuid = e.getKey();
NicIpAddressInfo nicIp = e.getValue();
Expand All @@ -338,11 +418,22 @@ public List<String> fillUpStaticIpInfoToVmNics(Map<String, NicIpAddressInfo> sta
.eq(NormalIpRangeVO_.l3NetworkUuid, l3Uuid)
.eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4)
.limit(1).find();
if (ipRangeVO == null) {

// Check if IP is within the range
boolean ipInRange = ipRangeVO != null &&
NetworkUtils.isInRange(nicIp.ipv4Address, ipRangeVO.getStartIp(), ipRangeVO.getEndIp());

if (ipRangeVO == null || (allowOutsideRange && !ipInRange)) {
// No IP range or IP is outside range with allowOutsideRange enabled
// User must provide netmask and gateway
if (StringUtils.isEmpty(nicIp.ipv4Netmask)) {
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10310, "netmask must be set"));
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10310, "netmask must be set for IP outside range"));
}
if (StringUtils.isEmpty(nicIp.ipv4Gateway)) {
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10312, "gateway must be set for IP outside range"));
}
} else {
// IP is within range, use IpRange values or validate user-provided values
if (StringUtils.isEmpty(nicIp.ipv4Netmask)) {
newSystags.add(VmSystemTags.IPV4_NETMASK.instantiateTag(
map(e(VmSystemTags.IPV4_NETMASK_L3_UUID_TOKEN, l3Uuid),
Expand Down Expand Up @@ -370,11 +461,22 @@ public List<String> fillUpStaticIpInfoToVmNics(Map<String, NicIpAddressInfo> sta
.eq(NormalIpRangeVO_.l3NetworkUuid, l3Uuid)
.eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6)
.limit(1).find();
if (ipRangeVO == null) {

// Check if IPv6 is within the range
boolean ipInRange = ipRangeVO != null &&
IPv6NetworkUtils.isIpv6InRange(nicIp.ipv6Address, ipRangeVO.getStartIp(), ipRangeVO.getEndIp());

if (ipRangeVO == null || (allowOutsideRange && !ipInRange)) {
// No IP range or IP is outside range with allowOutsideRange enabled
// User must provide prefixLen and gateway
if (StringUtils.isEmpty(nicIp.ipv6Prefix)) {
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10313, "ipv6 prefix length must be set"));
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10313, "ipv6 prefix length must be set for IP outside range"));
}
if (StringUtils.isEmpty(nicIp.ipv6Gateway)) {
throw new ApiMessageInterceptionException(operr(ORG_ZSTACK_COMPUTE_VM_10315, "ipv6 gateway must be set for IP outside range"));
}
} else {
// IP is within range, use IpRange values or validate user-provided values
if (StringUtils.isEmpty(nicIp.ipv6Prefix)) {
newSystags.add(VmSystemTags.IPV6_PREFIX.instantiateTag(
map(e(VmSystemTags.IPV6_PREFIX_L3_UUID_TOKEN, l3Uuid),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ public class VmGlobalConfig {
@GlobalConfigValidation(validValues = {"true", "false"})
public static GlobalConfig ENABLE_VM_INTERNAL_IP_OVERWRITE = new GlobalConfig(CATEGORY, "enable.vm.internal.ip.overwrite");

@GlobalConfigValidation(validValues = {"true", "false"})
@GlobalConfigDef(defaultValue = "false", type = Boolean.class, description = "Allow VM NIC to use IP address outside of L3 network IP ranges. When enabled, users must provide netmask/gateway for IPv4 or prefixLen/gateway for IPv6.")
public static GlobalConfig ALLOW_IP_OUTSIDE_RANGE = new GlobalConfig(CATEGORY, "allow.ip.outside.range");

@GlobalConfigValidation(validValues = {"true", "false"})
public static GlobalConfig UNIQUE_VM_NAME = new GlobalConfig(CATEGORY, "uniqueVmName");

Expand Down
22 changes: 22 additions & 0 deletions compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -3475,6 +3475,7 @@ private void handle(final APISetVmStaticIpMsg msg) {
cmsg.setNetmask(msg.getNetmask());
cmsg.setIpv6Gateway(msg.getIpv6Gateway());
cmsg.setIpv6Prefix(msg.getIpv6Prefix());
cmsg.setDnsAddresses(msg.getDnsAddresses());
bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, cmsg.getVmInstanceUuid());
bus.send(cmsg, new CloudBusCallBack(msg) {
@Override
Expand Down Expand Up @@ -3646,6 +3647,10 @@ public void run(FlowTrigger trigger, Map data) {
done(new FlowDoneHandler(completion) {
@Override
public void handle(Map data) {
// Set DNS addresses if provided
if (msg.getDnsAddresses() != null) {
new StaticIpOperator().setStaticDns(self.getUuid(), msg.getL3NetworkUuid(), msg.getDnsAddresses());
}
completion.success();
}
});
Expand Down Expand Up @@ -3684,6 +3689,10 @@ public void success() {
new StaticIpOperator().setStaticIp(self.getUuid(), msg.getL3NetworkUuid(), msg.getIp6());
}
new StaticIpOperator().setIpChange(self.getUuid(), msg.getL3NetworkUuid());
// Set DNS addresses if provided
if (msg.getDnsAddresses() != null) {
new StaticIpOperator().setStaticDns(self.getUuid(), msg.getL3NetworkUuid(), msg.getDnsAddresses());
}
completion.success();
}

Expand Down Expand Up @@ -6219,6 +6228,7 @@ private void handle(APIChangeVmNicNetworkMsg msg) {
cmsg.setVmInstanceUuid(msg.getVmInstanceUuid());
cmsg.setRequiredIpMap(msg.getRequiredIpMap());
cmsg.setSystemTags(msg.getSystemTags());
cmsg.setDnsAddresses(msg.getDnsAddresses());
bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, cmsg.getVmInstanceUuid());
bus.send(cmsg, new CloudBusCallBack(msg) {
@Override
Expand Down Expand Up @@ -6246,6 +6256,7 @@ public String getSyncSignature() {
public void run(final SyncTaskChain chain) {
class SetStaticIp {
private boolean isSet = false;
private boolean isDnsSet = false;
Map<String, List<String>> staticIpMap = null;

void set() {
Expand All @@ -6266,17 +6277,28 @@ void set() {
isSet = true;
}

void setDns() {
if (msg.getDnsAddresses() != null && !msg.getDnsAddresses().isEmpty()) {
new StaticIpOperator().setStaticDns(self.getUuid(), msg.getDestL3NetworkUuid(), msg.getDnsAddresses());
isDnsSet = true;
}
}

void rollback() {
if (isSet) {
for (Map.Entry<String, List<String>> e : staticIpMap.entrySet()) {
new StaticIpOperator().deleteStaticIpByVmUuidAndL3Uuid(self.getUuid(), e.getKey());
}
}
if (isDnsSet) {
new StaticIpOperator().deleteStaticDnsByVmUuidAndL3Uuid(self.getUuid(), msg.getDestL3NetworkUuid());
}
}
}

final SetStaticIp setStaticIp = new SetStaticIp();
setStaticIp.set();
setStaticIp.setDns();
Defer.guard(new Runnable() {
@Override
public void run() {
Expand Down
40 changes: 40 additions & 0 deletions conf/db/upgrade/V5.5.7__schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-- Add prefixLen column to UsedIpVO for IPv6 addresses outside IP range
CALL ADD_COLUMN('UsedIpVO', 'prefixLen', 'INT', 1, NULL);

-- Backfill prefixLen from IpRangeVO for existing IPv6 UsedIpVO records
UPDATE UsedIpVO u
INNER JOIN IpRangeVO r ON u.ipRangeUuid = r.uuid
SET u.prefixLen = r.prefixLen
WHERE u.ipVersion = 6 AND u.ipRangeUuid IS NOT NULL AND u.prefixLen IS NULL;

-- Modify ipRangeUuid foreign key constraint to SET NULL on delete (instead of CASCADE)
-- This allows UsedIpVO records to exist without an IpRange (for IPs outside range)
DELIMITER $$

CREATE PROCEDURE ModifyUsedIpVOForeignKey()
BEGIN
DECLARE constraint_exists INT;

-- Check if the constraint exists
SELECT COUNT(*)
INTO constraint_exists
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = 'zstack'
AND TABLE_NAME = 'UsedIpVO'
AND CONSTRAINT_NAME = 'fkUsedIpVOIpRangeEO';

IF constraint_exists > 0 THEN
-- Drop the existing constraint
ALTER TABLE `zstack`.`UsedIpVO` DROP FOREIGN KEY `fkUsedIpVOIpRangeEO`;

-- Re-create with SET NULL on delete
ALTER TABLE `zstack`.`UsedIpVO`
ADD CONSTRAINT `fkUsedIpVOIpRangeEO`
FOREIGN KEY (`ipRangeUuid`) REFERENCES `IpRangeEO`(`uuid`) ON DELETE SET NULL;
END IF;
END $$

DELIMITER ;

CALL ModifyUsedIpVOForeignKey();
DROP PROCEDURE IF EXISTS ModifyUsedIpVOForeignKey;
8 changes: 8 additions & 0 deletions conf/globalConfig/vm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,14 @@
<defaultValue>false</defaultValue>
</config>

<config>
<category>vm</category>
<name>allow.ip.outside.range</name>
<description>Allow VM NIC to use IP address outside of L3 network IP ranges. When enabled, users must provide netmask/gateway for IPv4 or prefixLen/gateway for IPv6.</description>
<type>java.lang.Boolean</type>
<defaultValue>false</defaultValue>
</config>

<config>
<category>vm</category>
<name>uniqueVmName</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class UsedIpInventory implements Serializable {
private Integer ipVersion;
private String ip;
private String netmask;
private Integer prefixLen;
private String gateway;
private String usedFor;
@APINoSee
Expand All @@ -52,6 +53,7 @@ public static UsedIpInventory valueOf(UsedIpVO vo) {
inv.setL3NetworkUuid(vo.getL3NetworkUuid());
inv.setGateway(vo.getGateway());
inv.setNetmask(vo.getNetmask());
inv.setPrefixLen(vo.getPrefixLen());
inv.setUsedFor(vo.getUsedFor());
inv.setVmNicUuid(vo.getVmNicUuid());
inv.setMetaData(vo.getMetaData());
Expand Down Expand Up @@ -139,6 +141,14 @@ public void setNetmask(String netmask) {
this.netmask = netmask;
}

public Integer getPrefixLen() {
return prefixLen;
}

public void setPrefixLen(Integer prefixLen) {
this.prefixLen = prefixLen;
}

public String getGateway() {
return gateway;
}
Expand Down
13 changes: 12 additions & 1 deletion header/src/main/java/org/zstack/header/network/l3/UsedIpVO.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class UsedIpVO {
private String uuid;

@Column
@ForeignKey(parentEntityClass = IpRangeEO.class, onDeleteAction = ReferenceOption.CASCADE)
@ForeignKey(parentEntityClass = IpRangeEO.class, onDeleteAction = ReferenceOption.SET_NULL)
private String ipRangeUuid;

@Column
Expand All @@ -48,6 +48,9 @@ public class UsedIpVO {
@Column
private String netmask;

@Column
private Integer prefixLen;

@Column
@Index
private long ipInLong;
Expand Down Expand Up @@ -147,6 +150,14 @@ public void setNetmask(String netmask) {
this.netmask = netmask;
}

public Integer getPrefixLen() {
return prefixLen;
}

public void setPrefixLen(Integer prefixLen) {
this.prefixLen = prefixLen;
}

public String getUsedFor() {
return usedFor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class UsedIpVO_ {
public static volatile SingularAttribute<UsedIpVO, Long> ipInLong;
public static volatile SingularAttribute<UsedIpVO, String> vmNicUuid;
public static volatile SingularAttribute<UsedIpVO, String> gateway;
public static volatile SingularAttribute<UsedIpVO, String> netmask;
public static volatile SingularAttribute<UsedIpVO, Integer> prefixLen;
public static volatile SingularAttribute<UsedIpVO, Timestamp> createDate;
public static volatile SingularAttribute<UsedIpVO, Timestamp> lastOpDate;
}
Loading