Skip to content

Commit 3fab757

Browse files
committed
Merge pull request #1474 from remibergsma/47_private_gw_initial_config
Handle private gateways more reliablyWhen initialising a VPC router we need to know which IP/device corresponds to a private gateway. This is to solve a problem when stop/starting a VPC router (which gets the private gateway config as a guest network and as a result breaks the functionality). You read it right, the private gateway is sent as type=guest after reboot and type=public initially. Before this change, you could add a private gw to a running router but you couldn't restart it (it would mix up the tiers). Now the private gateway is detected properly and it works just fine. Booting without private gateway: ``` root@r-167-VM:~# cat /etc/cloudstack/cmdline.json { "config": { "baremetalnotificationapikey": "V2l1u3wKJVan01h8kq63-5Y5Ia3VLEW1v_Z6i-31QIRJXlt5vkqaqf6DVcdK0jP3u79SW6X9pqJSLSwQP2c2Rw", "baremetalnotificationsecuritykey": "OXI16srCrxFBi-xOtEwcYqwLlMfSFTlTg66YHtXBBqR7HNN1us3HP5zWOKxfVmz4a3C1kUNLPrUH13gNmZlu4w", "disable_rp_filter": "true", "dns1": "8.8.8.8", "domain": "cs2cloud", "eth0ip": "169.254.0.42", "eth0mask": "255.255.0.0", "host": "192.168.22.61", "name": "r-167-VM", "port": "8080", "privategateway": "None", "redundant_router": "false", "template": "domP", "type": "vpcrouter", "vpccidr": "10.0.0.0/24" }, "id": "cmdline" ``` Booting with private gateway: ``` root@r-167-VM:~# cat /etc/cloudstack/cmdline.json { "config": { "baremetalnotificationapikey": "V2l1u3wKJVan01h8kq63-5Y5Ia3VLEW1v_Z6i-31QIRJXlt5vkqaqf6DVcdK0jP3u79SW6X9pqJSLSwQP2c2Rw", "baremetalnotificationsecuritykey": "OXI16srCrxFBi-xOtEwcYqwLlMfSFTlTg66YHtXBBqR7HNN1us3HP5zWOKxfVmz4a3C1kUNLPrUH13gNmZlu4w", "disable_rp_filter": "true", "dns1": "8.8.8.8", "domain": "cs2cloud", "eth0ip": "169.254.2.227", "eth0mask": "255.255.0.0", "host": "192.168.22.61", "name": "r-167-VM", "port": "8080", "privategateway": "10.201.10.1", "redundant_router": "false", "template": "domP", "type": "vpcrouter", "vpccidr": "10.0.0.0/24" }, "id": "cmdline" ``` And: ``` cat cmdline vpccidr=10.0.0.0/24 domain=cs2cloud dns1=8.8.8.8 privategateway=10.201.10.1 template=domP name=r-167-VM eth0ip=169.254.2.227 eth0mask=255.255.0.0 type=vpcrouter disable_rp_filter=true baremetalnotificationsecuritykey=OXI16srCrxFBi-xOtEwcYqwLlMfSFTlTg66YHtXBBqR7HNN1us3HP5zWOKxfVmz4a3C1kUNLPrUH13gNmZlu4w baremetalnotificationapikey=V2l1u3wKJVan01h8kq63-5Y5Ia3VLEW1v_Z6i-31QIRJXlt5vkqaqf6DVcdK0jP3u79SW6X9pqJSLSwQP2c2Rw host=192.168.22.61 port=8080 ``` Logs: ``` 2016-02-24 20:08:45,723 DEBUG [c.c.n.r.VpcVirtualNetworkApplianceManagerImpl] (Work-Job-Executor-4:ctx-458d4c52 job-1402/job-1403 ctx-d5355fca) (logid:5772906c) Set privategateway field in cmd_line.json to 10.201.10.1 ``` * pr/1474: Handle private gateways more reliably Add private gateway IP to router initialization config Signed-off-by: Will Stevens <[email protected]>
2 parents 919660d + f4f9b3a commit 3fab757

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import com.cloud.network.vpc.StaticRouteProfile;
6666
import com.cloud.network.vpc.Vpc;
6767
import com.cloud.network.vpc.VpcGateway;
68+
import com.cloud.network.vpc.VpcGatewayVO;
6869
import com.cloud.network.vpc.VpcManager;
6970
import com.cloud.network.vpc.VpcVO;
7071
import com.cloud.network.vpc.dao.PrivateIpDao;
@@ -260,6 +261,15 @@ public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile
260261
if (defaultDns2 != null) {
261262
buf.append(" dns2=").append(defaultDns2);
262263
}
264+
265+
VpcGatewayVO privateGatewayForVpc = _vpcGatewayDao.getPrivateGatewayForVpc(domainRouterVO.getVpcId());
266+
if (privateGatewayForVpc != null) {
267+
String ip4Address = privateGatewayForVpc.getIp4Address();
268+
buf.append(" privategateway=").append(ip4Address);
269+
s_logger.debug("Set privategateway field in cmd_line.json to " + ip4Address);
270+
} else {
271+
buf.append(" privategateway=None");
272+
}
263273
}
264274
}
265275

systemvm/patches/debian/config/opt/cloud/bin/cs/CsHelper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,4 @@ def copy(src, dest):
248248
except IOError:
249249
logging.Error("Could not copy %s to %s" % (src, dest))
250250
else:
251-
logging.info("Copied %s to %s" % (src, dest))
251+
logging.info("Copied %s to %s" % (src, dest))

systemvm/patches/debian/config/opt/cloud/bin/merge.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,13 @@ def processGuestNetwork(self, dbag):
145145
dp['gateway'] = d['router_guest_gateway']
146146
dp['nic_dev_id'] = d['device'][3]
147147
dp['nw_type'] = 'guest'
148+
dp = PrivateGatewayHack.update_network_type_for_privategateway(dbag, dp)
148149
qf = QueueFile()
149150
qf.load({'ip_address': [dp], 'type': 'ips'})
150151
if 'domain_name' not in d.keys() or d['domain_name'] == '':
151152
d['domain_name'] = "cloudnine.internal"
153+
154+
d = PrivateGatewayHack.update_network_type_for_privategateway(dbag, d)
152155
return cs_guestnetwork.merge(dbag, d)
153156

154157
def process_dhcp_entry(self, dbag):
@@ -274,3 +277,46 @@ def __moveFile(self, origPath, path):
274277
os.makedirs(path)
275278
timestamp = str(int(round(time.time())))
276279
os.rename(origPath, path + "/" + self.fileName + "." + timestamp)
280+
281+
282+
class PrivateGatewayHack:
283+
284+
285+
@classmethod
286+
def update_network_type_for_privategateway(cls, dbag, data):
287+
ip = data['router_guest_ip'] if 'router_guest_ip' in data.keys() else data['public_ip']
288+
289+
initial_data = cls.load_inital_data()
290+
has_private_gw_ip = cls.if_config_has_privategateway(initial_data)
291+
private_gw_matches = 'privategateway' in initial_data['config'] and cls.ip_matches_private_gateway_ip(ip, initial_data['config']['privategateway'])
292+
293+
if has_private_gw_ip and private_gw_matches:
294+
data['nw_type'] = "public"
295+
logging.debug("Updating nw_type for ip %s" % ip)
296+
else:
297+
logging.debug("Not updating nw_type for ip %s because has_private_gw_ip = %s and private_gw_matches = %s " % (ip, has_private_gw_ip, private_gw_matches))
298+
return data
299+
300+
301+
@classmethod
302+
def if_config_has_privategateway(cls, dbag):
303+
return 'privategateway' in dbag['config'].keys() and dbag['config']['privategateway'] != "None"
304+
305+
306+
@classmethod
307+
def ip_matches_private_gateway_ip(cls, ip, private_gateway_ip):
308+
new_ip_matches_private_gateway_ip = False
309+
if ip == private_gateway_ip:
310+
new_ip_matches_private_gateway_ip = True
311+
return new_ip_matches_private_gateway_ip
312+
313+
314+
@classmethod
315+
def load_inital_data(cls):
316+
initial_data_bag = DataBag()
317+
initial_data_bag.setKey('cmdline')
318+
initial_data_bag.load()
319+
initial_data = initial_data_bag.getDataBag()
320+
logging.debug("Initial data = %s" % initial_data)
321+
322+
return initial_data

0 commit comments

Comments
 (0)