You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by gi...@git.apache.org on 2017/04/27 05:35:32 UTC

[GitHub] sudhansu7 opened a new pull request #1850: CLOUDSTACK-9694: Unable to limit the Public IPs in VPC

sudhansu7 opened a new pull request #1850: CLOUDSTACK-9694: Unable to limit the Public IPs in VPC
URL: https://github.com/apache/cloudstack/pull/1850
 
 
   Unable to limit the Public IPs in VPC.
   In VPC network, while acquiring the IP addresses, in the resource_count table, count for the domain is getting increased. However, when the resource count is updated at Domain level, resource count is getting reverted to only non-vpc ip count.
   
   Steps to Reproduce:
   
   1. Create a VPC
   2. Create a VPC tier.
   3. Check resource_count table and note the ip address count. (say 1)
   4. Keep acquiring the IP addresses, (say 4 IP addresses). Now new ip address count resource_count table is 5.
   5. update the resource count at domain level.
   6. the resource_count is updated back 1
   
   Root Cause: Update resource count command recalculates the resource count. While computing public IP we are not considering the ips allocated to VPC.
   
   ResourceLimitManagerImpl.java -> calculatePublicIpForAccount() -> IPAddressDaoImpl.countAllocatedIPsForAccount()
   
   Currently we have below query builder. Which does not consider vpc_id column.
   ```
           AllocatedIpCountForAccount = createSearchBuilder(Long.class);
           AllocatedIpCountForAccount.select(null, Func.COUNT, AllocatedIpCountForAccount.entity().getAddress());
           AllocatedIpCountForAccount.and("account", AllocatedIpCountForAccount.entity().getAllocatedToAccountId(), Op.EQ);
           AllocatedIpCountForAccount.and("allocated", AllocatedIpCountForAccount.entity().getAllocatedTime(), Op.NNULL);
           AllocatedIpCountForAccount.and("network", AllocatedIpCountForAccount.entity().getAssociatedWithNetworkId(), Op.NNULL);
           AllocatedIpCountForAccount.done();
   ```
   it generates below sql query
   ```
   SELECT COUNT(user_ip_address.public_ip_address) FROM user_ip_address WHERE user_ip_address.account_id = 6  AND user_ip_address.allocated IS NOT NULL  AND user_ip_address.network_id IS NOT NULL  AND user_ip_address.removed IS NULL
   ```
   Fix:
   Add vpc_id check in query.
   ```
           AllocatedIpCountForAccount = createSearchBuilder(Long.class);
           AllocatedIpCountForAccount.select(null, Func.COUNT, AllocatedIpCountForAccount.entity().getAddress());
           AllocatedIpCountForAccount.and("account", AllocatedIpCountForAccount.entity().getAllocatedToAccountId(), Op.EQ);
           AllocatedIpCountForAccount.and("allocated", AllocatedIpCountForAccount.entity().getAllocatedTime(), Op.NNULL);
           AllocatedIpCountForAccount.and().op("network", AllocatedIpCountForAccount.entity().getAssociatedWithNetworkId(), Op.NNULL);
           AllocatedIpCountForAccount.or("vpc", AllocatedIpCountForAccount.entity().getVpcId(), Op.NNULL);
           AllocatedIpCountForAccount.cp();
           AllocatedIpCountForAccount.done();
   ```
   SQL:
   ```
   SELECT COUNT(user_ip_address.public_ip_address) FROM user_ip_address WHERE user_ip_address.account_id = 6  AND user_ip_address.allocated IS NOT NULL  AND ( user_ip_address.network_id IS NOT NULL or user_ip_address.vpc_id IS NOT NULL) AND user_ip_address.removed IS NULL
   ```
   Test Result:
   Initial resource count
   ```
   mysql> select * from resource_count where type in ('vpc','public_ip') and domain_id = 3;
   +----+------------+-----------+-----------+-------+
   | id | account_id | domain_id | type      | count |
   +----+------------+-----------+-----------+-------+
   | 66 |       NULL |         3 | public_ip |     2 |
   | 72 |       NULL |         3 | vpc       |     1 |
   +----+------------+-----------+-----------+-------+
   2 rows in set (0.00 sec)
   ```
   Aquire 2 more public ip in VPC network.
   ```
   mysql> select * from resource_count where type in ('vpc','public_ip') and domain_id = 3;
   +----+------------+-----------+-----------+-------+
   | id | account_id | domain_id | type      | count |
   +----+------------+-----------+-----------+-------+
   | 66 |       NULL |         3 | public_ip |     4 |
   | 72 |       NULL |         3 | vpc       |     1 |
   +----+------------+-----------+-----------+-------+
   2 rows in set (0.00 sec)
   ```
   After updating resource count at for doamin 3.
   ```
   mysql> select * from resource_count where type in ('vpc','public_ip') and domain_id = 3;
   +----+------------+-----------+-----------+-------+
   | id | account_id | domain_id | type      | count |
   +----+------------+-----------+-----------+-------+
   | 66 |       NULL |         3 | public_ip |     1 |
   | 72 |       NULL |         3 | vpc       |     1 |
   +----+------------+-----------+-----------+-------+
   2 rows in set (0.00 sec)
   ```
   
   Output of INCORRECT query used for calculating public ip addresses.
   ```
   mysql> SELECT COUNT(user_ip_address.public_ip_address) FROM user_ip_address WHERE user_ip_address.account_id = 4  AND user_ip_address.allocated IS NOT NULL  AND user_ip_address.network_id IS NOT NULL  AND user_ip_address.removed IS NULL;
   +------------------------------------------+
   | COUNT(user_ip_address.public_ip_address) |
   +------------------------------------------+
   |                                        1 |
   +------------------------------------------+
   1 row in set (0.00 sec)
   ```
   
   
   Output of CORRECT query used for calculating public ip addresses.
   ```
   mysql> SELECT COUNT(user_ip_address.public_ip_address) FROM user_ip_address WHERE user_ip_address.account_id = 4  AND user_ip_address.allocated IS NOT NULL  AND ( user_ip_address.network_id IS NOT NULL or user_ip_address.vpc_id IS NOT NULL) AND user_ip_address.removed IS NULL;
   +------------------------------------------+
   | COUNT(user_ip_address.public_ip_address) |
   +------------------------------------------+
   |                                        4 |
   +------------------------------------------+
   1 row in set (0.00 sec)
   ```
   
   
   After FIX:
   ```
   mysql> select * from resource_count where type in ('vpc','public_ip') and domain_id = 3;
   +----+------------+-----------+-----------+-------+
   | id | account_id | domain_id | type      | count |
   +----+------------+-----------+-----------+-------+
   | 66 |       NULL |         3 | public_ip |     4 |
   | 72 |       NULL |         3 | vpc       |     1 |
   +----+------------+-----------+-----------+-------+
   2 rows in set (0.00 sec)
   ```
   
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services