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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ enum State {

Long getParentId();

Long getDataCenterId();

String getSubnet();

Long getVpcId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class Ipv4GuestSubnetNetworkMapVO implements Ipv4GuestSubnetNetworkMap {
@Column(name = "parent_id")
private Long parentId;

@Column(name = "data_center_id")
private Long dataCenterId;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

should listing subnets by zone use this column too? right now it only matches through the zone subnet, so ones made without a zone subnet dont show up when you filter by zone

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks @Damans227 and it’s a bit worse than parentless rows. The zoneid filter resolves the zone through dc_ip4_guest_subnets:

List<DataCenterIpv4GuestSubnetVO> subnets = dataCenterIpv4GuestSubnetDao.listByDataCenterId(zoneId);
if (CollectionUtils.isEmpty(subnets)) {
    return new ArrayList<>();
}
sc.addAnd("parentId", SearchCriteria.Op.IN, parentIds.toArray());

So if the zone has no zone-level subnet configured at all, the list returns empty even when routed VPCs exist there , which is exactly the setup in #14419. createIpv4SubnetForGuestNetworkResponse has the same gap: zoneId is only derived from the network, VPC or parent, so a parentless unassigned row reports no zone.

Now that the row carries the zone, I’ll replace the parent-id lookup with a direct data_center_id filter and add it as a fallback in the response (that needs getDataCenterId() on the Ipv4GuestSubnetNetworkMap interface). Rows that predate the upgrade and can’t be attributed to a zone keep data_center_id = NULL and still won’t show under a zone filter same as today, so no regression. Pushing shortly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pushed in d98069c , filter now uses data_center_id, and the response falls back to it for parentless subnets.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that covers it, thanks


@Column(name = "subnet")
private String subnet;

Expand All @@ -72,8 +75,9 @@ protected Ipv4GuestSubnetNetworkMapVO() {
uuid = UUID.randomUUID().toString();
}

protected Ipv4GuestSubnetNetworkMapVO(Long parentId, String subnet, Long networkId, Ipv4GuestSubnetNetworkMap.State state) {
protected Ipv4GuestSubnetNetworkMapVO(Long parentId, Long dataCenterId, String subnet, Long networkId, Ipv4GuestSubnetNetworkMap.State state) {
this.parentId = parentId;
this.dataCenterId = dataCenterId;
this.subnet = subnet;
this.networkId = networkId;
this.state = state;
Expand All @@ -95,6 +99,15 @@ public Long getParentId() {
return parentId;
}

@Override
public Long getDataCenterId() {
return dataCenterId;
}

public void setDataCenterId(Long dataCenterId) {
this.dataCenterId = dataCenterId;
}

@Override
public String getSubnet() {
return subnet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public interface Ipv4GuestSubnetNetworkMapDao extends GenericDao<Ipv4GuestSubnet
Ipv4GuestSubnetNetworkMapVO findFirstAvailable(long parentId, long cidrSize);
Ipv4GuestSubnetNetworkMapVO findByNetworkId(long networkId);
Ipv4GuestSubnetNetworkMapVO findByVpcId(long vpcId);
Ipv4GuestSubnetNetworkMapVO findBySubnet(String subnet);
Ipv4GuestSubnetNetworkMapVO findBySubnetAndDataCenterId(String subnet, Long dataCenterId);
List<Ipv4GuestSubnetNetworkMapVO> findSubnetsInStates(Ipv4GuestSubnetNetworkMap.State... states);
void deleteByParentId(long parentId);
List<Ipv4GuestSubnetNetworkMapVO> listAllNoParent();
List<Ipv4GuestSubnetNetworkMapVO> listAllNoParentByDataCenterId(Long dataCenterId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ public void init() {
ParentIdSearch.done();
NoParentSearch = createSearchBuilder();
NoParentSearch.and("parentId", NoParentSearch.entity().getParentId(), SearchCriteria.Op.NULL);
NoParentSearch.and("dataCenterId", NoParentSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
NoParentSearch.done();
NetworkIdSearch = createSearchBuilder();
NetworkIdSearch.and("networkId", NetworkIdSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
NetworkIdSearch.and("vpcId", NetworkIdSearch.entity().getVpcId(), SearchCriteria.Op.EQ);
NetworkIdSearch.done();
SubnetSearch = createSearchBuilder();
SubnetSearch.and("subnet", SubnetSearch.entity().getSubnet(), SearchCriteria.Op.EQ);
SubnetSearch.and("dataCenterId", SubnetSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
SubnetSearch.done();
StatesSearch = createSearchBuilder();
StatesSearch.and("state", StatesSearch.entity().getState(), SearchCriteria.Op.IN);
Expand Down Expand Up @@ -142,9 +144,10 @@ public Ipv4GuestSubnetNetworkMapVO findByVpcId(long vpcId) {
}

@Override
public Ipv4GuestSubnetNetworkMapVO findBySubnet(String subnet) {
public Ipv4GuestSubnetNetworkMapVO findBySubnetAndDataCenterId(String subnet, Long dataCenterId) {
SearchCriteria<Ipv4GuestSubnetNetworkMapVO> sc = SubnetSearch.create();
sc.setParameters("subnet", subnet);
sc.setParameters("dataCenterId", dataCenterId);
return findOneBy(sc);
}

Expand All @@ -163,8 +166,9 @@ public void deleteByParentId(long parentId) {
}

@Override
public List<Ipv4GuestSubnetNetworkMapVO> listAllNoParent() {
public List<Ipv4GuestSubnetNetworkMapVO> listAllNoParentByDataCenterId(Long dataCenterId) {
SearchCriteria<Ipv4GuestSubnetNetworkMapVO> sc = NoParentSearch.create();
sc.setParameters("dataCenterId", dataCenterId);
return listBy(sc, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,23 @@ UPDATE op_dc_vnet_alloc a
a.reservation_id = NULL,
a.taken = NULL
WHERE n.removed IS NOT NULL;

-- Scope routed network/VPC subnets to a zone, so that the same CIDR can be used in more than one zone. See #14419.
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.ip4_guest_subnet_network_map', 'data_center_id', 'bigint unsigned DEFAULT NULL COMMENT "zone it belongs to"');

UPDATE `cloud`.`ip4_guest_subnet_network_map` m
JOIN `cloud`.`dc_ip4_guest_subnets` p ON p.id = m.parent_id
SET m.data_center_id = p.data_center_id
WHERE m.data_center_id IS NULL;

UPDATE `cloud`.`ip4_guest_subnet_network_map` m
JOIN `cloud`.`vpc` v ON v.id = m.vpc_id
SET m.data_center_id = v.zone_id
WHERE m.data_center_id IS NULL;

UPDATE `cloud`.`ip4_guest_subnet_network_map` m
JOIN `cloud`.`networks` n ON n.id = m.network_id
SET m.data_center_id = n.data_center_id
WHERE m.data_center_id IS NULL;

CALL `cloud`.`IDEMPOTENT_ADD_FOREIGN_KEY`('cloud.ip4_guest_subnet_network_map', 'fk_ip4_guest_subnet_network_map__data_center_id', '(`data_center_id`)', '`data_center`(`id`)');
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public class RoutedIpv4ManagerImpl extends ComponentLifecycleBase implements RoutedIpv4Manager {
Expand Down Expand Up @@ -519,12 +518,7 @@ public List<Ipv4GuestSubnetNetworkMap> listIpv4GuestSubnetsForGuestNetwork(ListI
sc.addAnd("id", SearchCriteria.Op.EQ, id);
}
if (zoneId != null) {
List<DataCenterIpv4GuestSubnetVO> subnets = dataCenterIpv4GuestSubnetDao.listByDataCenterId(zoneId);
if (CollectionUtils.isEmpty(subnets)) {
return new ArrayList<>();
}
List<Long> parentIds = subnets.stream().map(DataCenterIpv4GuestSubnetVO::getId).collect(Collectors.toList());
sc.addAnd("parentId", SearchCriteria.Op.IN, parentIds.toArray());
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
}
if (parentId != null) {
sc.addAnd("parentId", SearchCriteria.Op.EQ, parentId);
Expand Down Expand Up @@ -554,7 +548,7 @@ public Ipv4SubnetForGuestNetworkResponse createIpv4SubnetForGuestNetworkResponse
response.setState(subnet.getState().name());
response.setId(subnet.getUuid());
response.setAllocatedTime(subnet.getAllocated());
Long zoneId = null;
Long zoneId = subnet.getDataCenterId();
if (subnet.getNetworkId() != null) {
Network network = ApiDBUtils.findNetworkById(subnet.getNetworkId());
response.setNetworkId(network.getUuid());
Expand Down Expand Up @@ -650,7 +644,7 @@ protected Ipv4GuestSubnetNetworkMap getOrCreateIpv4SubnetForGuestNetworkOrVpcInt
}

protected void getOrCreateIpv4SubnetForGuestNetworkOrVpcInternal(String networkCidr, Long ownerDomainId, Long ownerAccountId, Long zoneId) {
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnet(networkCidr);
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnetAndDataCenterId(networkCidr, zoneId);
if (subnetMap != null) {
// check if the subnet is in use
if (subnetMap.getNetworkId() != null || subnetMap.getVpcId() != null) {
Expand All @@ -672,7 +666,7 @@ protected void getOrCreateIpv4SubnetForGuestNetworkOrVpcInternal(String networkC

// Create new record without networkId
final Long parentId = parent != null ? parent.getId() : null;
subnetMap = new Ipv4GuestSubnetNetworkMapVO(parentId, NetUtils.transformCidr(networkCidr), null, State.Free);
subnetMap = new Ipv4GuestSubnetNetworkMapVO(parentId, zoneId, NetUtils.transformCidr(networkCidr), null, State.Free);
ipv4GuestSubnetNetworkMapDao.persist(subnetMap);
}

Expand All @@ -698,7 +692,7 @@ protected DataCenterIpv4GuestSubnet getParentOfNetworkCidr(Long zoneId, String n
}
}
// check conflicts
List<Ipv4GuestSubnetNetworkMapVO> subnetsForNetworkNoParents = ipv4GuestSubnetNetworkMapDao.listAllNoParent();
List<Ipv4GuestSubnetNetworkMapVO> subnetsForNetworkNoParents = ipv4GuestSubnetNetworkMapDao.listAllNoParentByDataCenterId(zoneId);
checkConflicts(subnetsForNetworkNoParents, networkCidr);
return null;
}
Expand Down Expand Up @@ -730,7 +724,7 @@ private List<DataCenterIpv4GuestSubnetVO> getZoneSubnetsForAccount(long domainId
protected Ipv4GuestSubnetNetworkMap createIpv4SubnetFromParentSubnet(DataCenterIpv4GuestSubnet parent, Integer networkCidrSize) {
String networkCidr = createIpv4SubnetStringFromParentSubnet(parent, networkCidrSize);
// create DB record
Ipv4GuestSubnetNetworkMapVO subnetMap = new Ipv4GuestSubnetNetworkMapVO(parent.getId(), NetUtils.transformCidr(networkCidr), null, State.Free);
Ipv4GuestSubnetNetworkMapVO subnetMap = new Ipv4GuestSubnetNetworkMapVO(parent.getId(), parent.getDataCenterId(), NetUtils.transformCidr(networkCidr), null, State.Free);
return ipv4GuestSubnetNetworkMapDao.persist(subnetMap);
}

Expand Down Expand Up @@ -767,19 +761,19 @@ protected String createIpv4SubnetStringFromParentSubnet(DataCenterIpv4GuestSubne
}

// Allocate a subnet automatically
String networkCidr = getFreeNetworkCidr(subnetsInFreeIpRanges, networkCidrSize);
String networkCidr = getFreeNetworkCidr(subnetsInFreeIpRanges, networkCidrSize, parent.getDataCenterId());
if (networkCidr == null) {
throw new InvalidParameterValueException("Failed to automatically allocate a subnet with specified cidrsize");
}
return networkCidr;
}

private String getFreeNetworkCidr(List<Pair<Long, Integer>> subnetsInFreeIpRanges, int networkCidrSize) {
private String getFreeNetworkCidr(List<Pair<Long, Integer>> subnetsInFreeIpRanges, int networkCidrSize, Long dataCenterId) {
for (int cidrSize = networkCidrSize; cidrSize >= 1; cidrSize--) {
for (Pair<Long, Integer> freeSubnet : subnetsInFreeIpRanges) {
if (freeSubnet.second().equals(cidrSize)) {
String networkCidr = String.format("%s/%s", NetUtils.long2Ip(freeSubnet.first()), networkCidrSize);
if (ipv4GuestSubnetNetworkMapDao.findBySubnet(networkCidr) == null) {
if (ipv4GuestSubnetNetworkMapDao.findBySubnetAndDataCenterId(networkCidr, dataCenterId) == null) {
return networkCidr;
}
}
Expand All @@ -798,7 +792,7 @@ protected Ipv4GuestSubnetNetworkMap createIpv4SubnetFromParentSubnet(DataCenterI
checkConflicts(existingSubnets, networkCidr);

// create DB record
Ipv4GuestSubnetNetworkMapVO subnetMap = new Ipv4GuestSubnetNetworkMapVO(parent.getId(), NetUtils.transformCidr(networkCidr), null, State.Free);
Ipv4GuestSubnetNetworkMapVO subnetMap = new Ipv4GuestSubnetNetworkMapVO(parent.getId(), parent.getDataCenterId(), NetUtils.transformCidr(networkCidr), null, State.Free);
return ipv4GuestSubnetNetworkMapDao.persist(subnetMap);
}

Expand All @@ -807,7 +801,7 @@ public void assignIpv4SubnetToNetwork(Network network) {
if (network == null || network.getCidr() == null) {
return;
}
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnet(network.getCidr());
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnetAndDataCenterId(network.getCidr(), network.getDataCenterId());
if (subnetMap != null) {
if (network.getId() > 0L) {
subnetMap.setNetworkId(network.getId());
Expand All @@ -823,7 +817,7 @@ public void assignIpv4SubnetToVpc(Vpc vpc) {
if (vpc == null || vpc.getCidr() == null) {
return;
}
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnet(vpc.getCidr());
Ipv4GuestSubnetNetworkMapVO subnetMap = ipv4GuestSubnetNetworkMapDao.findBySubnetAndDataCenterId(vpc.getCidr(), vpc.getZoneId());
if (subnetMap != null) {
if (vpc != null && vpc.getId() > 0L) {
subnetMap.setVpcId(vpc.getId());
Expand Down
Loading