kaanalnet
Version:
Virtual Network Emulator Lab for SDN and traditional networks
296 lines (258 loc) • 13.1 kB
text/coffeescript
Vm = require('lxcdriver')
util = require('util')
netem = require('linuxtcdriver')
request = require('request-json')
#===============================================================================================#
keystore = require('mem-db')
Schema = require('./../schema').nodeschema
#===============================================================================================#
class VmBuilder
constructor: () ->
= new keystore "vmbuilder",Schema
# = new VmRegistry #"/tmp/vm.db"
= {}
list : (callback) ->
callback .list()
get: (id, callback) ->
callback .get id
create : (data, callback) ->
id = .add data
#util.log "new vmbuilder data created - id #{id}, data #{data.image} "
return callback new Error "invalid Schema" if id instanceof Error or id is false
vmobj = new Vm data.name
#util.log "vmobj state is #{vmobj.state} name is #{vmobj.name}"
data.status = "creation-in-progress"
.update id, data
callback({"id": id,"status": vmobj.state})
vmobj.clone data.image,(result)=>
util.log "clone vm " + result
if result instanceof Error
data.status = vmobj.state #"failed"
data.reason = "VM already exists"
.update id, data
return #callback({"id": id,"status": vmobj.state})
util.log "state is " + vmobj.state
#remove the interface file
vmobj.deleteFile "/etc/network/interfaces"
#processing the interfaces map
if data.ifmap?
for x in data.ifmap
if x.type is "mgmt"
#ubuntu interfaces file format
text = "\nauto #{x.ifname}\niface #{x.ifname} inet static \n\t address #{x.ipaddress} \n\t netmask #{x.netmask} \n"
vmobj.appendFile("/etc/network/interfaces",text)
else # for wan, lan interfaces
vmobj.addEthernetInterface(x.veth,x.hwAddress)
text = "\nauto #{x.ifname}\niface #{x.ifname} inet static \n\t address #{x.ipaddress} \n\t netmask #{x.netmask} \n\t gateway #{x.gateway}\n"
vmobj.appendFile("/etc/network/interfaces",text)
#write in to db
#processing the lag intefaces array
if data.lagmap?
for x in data.lagmap
vmobj.addEthernetInterface(x.veth1,x.hwAddress1)
vmobj.addEthernetInterface(x.veth2,x.hwAddress2)
text = "\nauto #{x.lagif1}\niface #{x.lagif1} inet static \n\t address 0.0.0.0 \n\t netmask 255.255.255.0 \n"
vmobj.appendFile("/etc/network/interfaces",text)
text = "\nauto #{x.lagif2}\niface #{x.lagif2} inet static \n\t address 0.0.0.0 \n\t netmask 255.255.255.0 \n"
vmobj.appendFile("/etc/network/interfaces",text)
#vmdata.data.id = vmdata.id
data.status = vmobj.state #"created"
#default router protocol ospf if not mentioned
data.protocol ?= "ospf" if data.type is "router"
.update id, data
[id] = vmobj
return #callback({"id": id,"status": vmobj.state})
start : (id,callback) ->
console.log "start called id is ", id
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
console.log "start ", vmdata
vmobj = [id]
return callback new Error "vm obj not found" unless vmobj?
vmobj.start (res) =>
util.log "startvm" + res
if res is true
vmdata.status = vmobj.state
.update id, vmdata
return callback
"id": id
"status":vmdata.status
else
vmdata.status = "failed"
vmddata.reason = "failed to start"
.update vmdata.id, vmdata
return callback
"id": vmdata.id
"status":vmdata.status
"reason": vmdata.reason
provision : (id, callback) ->
console.log "Dummy provisioning is called ", id
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
console.log "provision ", vmdata
vmobj = [id]
return callback new Error "vm obj not found" unless vmobj?
#Todo - provisioning routines to be placed here
# provision the LAG Bonding interfaces
return callback
"id" : vmdata.id
"status" : "provisioned"
provisionBonding : (vmdata)->
bondindex = 0
for lag in vmdata.lagmap
bonddata =
"bondname": lag.bondname
"ipaddress": lag.ipaddress
"interfaces":[lag.lagif1,lag.lagif2]
bondindex++
client = request.newClient("http://#{vmdata.mgmtip}:5051")
client.post "/bonding", bonddata , (err, res, body) =>
console.log "Post Bonding API Error %s ", err if err?
console.log "PosT Bonding API result body %s " , JSON.stringify body
stop:(id,callback) ->
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
vmobj = [id]
vmobj.stop (result) =>
util.log "stopvm" + result
if result is true
vmdata.status = vmobj.state #"stopped"
.update id, vmdata
return callback
"id":vmdata.id
"status":vmdata.status
else
vmdata.status = "failed"
vmdata.reason = "failed to stop"
.update id, vmdata
return callback
"id":vmdata.id
"status":vmdata.status
"reason" : vmdata.reason
del:(id,callback)->
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
vmobj = [id]
vmobj.stop (res) =>
vmobj.destroy (result) =>
util.log "deleteVM " + result
if result is true
vmdata.status = vmobj.state
.remove vmdata.id
#delete [id]
return callback
"id":vmdata.id
"status":vmdata.status
else
vmdata.status = "failed"
vmddata.reason = "failed to stop"
.update vmdata.id, vmdata
return callback
"id":vmdata.id
"status":vmdata.status
"reason":vmdata.reason
status:(id,callback) ->
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
vmobj = [id]
vmobj.runningstatus (res)=>
util.log "statusvm" + res
vmdata.status = res
.update vmdata.id, vmdata
return callback
"id": vmdata.id
"status":vmdata.status
setLinkChars : (id,callback)->
vmdata = .get id
return callback new Error "VM details not found in DB" if vmdata is false or vmdata instanceof Error
for i in vmdata.ifmap
util.log "Vmctrl - setLinkChars " + JSON.stringify i
if i.config?
Netem = new netem(i.veth,i.config)
Netem.create()
callback true
configStartup :(vmdata)->
util.log "in configStartup routine", JSON.stringify vmdata
vmobj = [vmdata.id]
#updating the link charactristics simulation
for i in vmdata.ifmap
util.log "Vmctrl - setLinkChars " + JSON.stringify i
if i.config?
#host side configuration
Netem = new netem(i.ifname,i.config)
#Netem.create()
console.log Netem.commands
text = " "
for command in Netem.commands
console.log "command ", command
text += "\n #{command}"
text += "\n"
console.log "string command ", text
#text = "\n/usr/lib/quagga/zebra -f /etc/zebra.conf -d & \n /usr/lib/quagga/ospfd -f /etc/ospf.conf -d & \n"
vmobj.appendFile("/etc/init.d/rc.local",text)
if vmdata.type is "router"
util.log 'its router'
#zebra config
zebraconf =
vmobj.appendFile("/etc/zebra.conf",zebraconf)
text = "\n/usr/lib/quagga/zebra -f /etc/zebra.conf -d & \n"
vmobj.appendFile("/etc/init.d/rc.local",text)
#protocol config
console.log "vmdata.protocol " ,vmdata.protocol
switch vmdata.protocol
when 'rip'
console.log "ripd case"
ripconf =
vmobj.appendFile("/etc/rip.conf",ripconf)
text = "/usr/lib/quagga/ripd -f /etc/rip.conf -d & \n"
vmobj.appendFile("/etc/init.d/rc.local",text)
when 'ospf'
console.log "ospf case"
ospfconf =
vmobj.appendFile("/etc/ospf.conf",ospfconf)
text = "/usr/lib/quagga/ospfd -f /etc/ospf.conf -d & \n"
vmobj.appendFile("/etc/init.d/rc.local",text)
else
console.log "default case"
#write the bgp conf for ODLBGP integreation
bgpconf =
vmobj.appendFile("/etc/bgp.conf",bgpconf)
util.log "its router- to be returned here"
return
else
util.log 'its host'
#updating the startup script
text = "\nnodejs /node_modules/testagent/lib/app.js > /var/log/testagent.log & \n iperf -s > /var/log/iperf_tcp_server.log & \n iperf -s -u > /var/log/iperf_udp_server.log & \n"
vmobj.appendFile("/etc/init.d/rc.local",text)
return
buildZebraConfig :(vmdata)->
#updating the zebra config file
zebraconf = "hostname zebra \npassword zebra \nenable password zebra \n log file /tmp/zebra.log debugging \n"
for i in vmdata.ifmap
zebraconf += "interface #{i.ifname} \n"
zebraconf += " ip address #{i.ipaddress}/29 \n" if i.type is "wan"
zebraconf += " ip address #{i.ipaddress}/24 \n" if i.type is "lan"
zebraconf += " ip address #{i.ipaddress}/24 \n" if i.type is "mgmt"
util.log "zebrafile " + zebraconf
return zebraconf
buildOspfConfig :(vmdata)->
ospfconf = "hostname zebra \npassword zebra \nenable password zebra \n log file /tmp/ospf.log debugging \n router ospf\n "
for i in vmdata.ifmap
ospfconf += " network #{i.ipaddress}/24 area 0 \n" unless i.type is "mgmt"
util.log "ospfconffile " + ospfconf
return ospfconf
buildBgpConfig :(vmdata)->
bgpconf = "hostname zebra \npassword zebra \nenable password zebra \nlog file /tmp/bgp.log debugging \nrouter bgp 1\n bgp router-id #{vmdata.mgmtip}\n neighbor 10.0.3.1 remote-as 1\n redistribute connected \n redistribute ospf\n redistribute rip\n"
#for i in vmdata.ifmap
# bgpconf += " network #{i.ipaddress}/24 \n" unless i.type is "mgmt"
#util.log "bgpconffile " + bgpconf
return bgpconf
buildRipConfig :(vmdata)->
ripconf = "hostname zebra \npassword zebra \nenable password zebra \n log file /tmp/rip.log debugging \n router rip\n "
for i in vmdata.ifmap
ripconf += " network #{i.ipaddress}/24 \n" unless i.type is "mgmt"
util.log "ripconffile " + ripconf
return ripconf
module.exports = new VmBuilder