4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
21 gi
.require_version('RwYang', '1.0')
22 from gi
.repository
import IetfL2TopologyYang
as l2Tl
23 from gi
.repository
import RwTopologyYang
as RwTl
24 from gi
.repository
import RwYang
25 from xml
.etree
import ElementTree
as etree
29 from create_stackedl2topology
import MyL2Network
30 from create_stackedl2topology
import MyL2Topology
31 from create_stackedProvNettopology
import MyProvNetwork
32 from create_stackedProvNettopology
import MyProvTopology
33 from create_stackedVMNettopology
import MyVMNetwork
34 from create_stackedVMNettopology
import MyVMTopology
37 class MyNwNotFound(Exception):
40 class MyNodeNotFound(Exception):
43 class MyTpNotFound(Exception):
46 class MySfcNetwork(object):
47 def __init__(self
, nwtop
, l2top
, provtop
, vmtop
, log
):
50 self
.sfcnet1
= nwtop
.network
.add()
51 self
.sfcnet1
.network_id
= "SfcNetwork-1"
54 self
.provtop
= provtop
57 # L2 Network type augmentation
58 self
.sfcnet1
.network_types
.l2_network
= self
.sfcnet1
.network_types
.l2_network
.new()
59 # L2 Network augmentation
60 self
.sfcnet1
.l2_network_attributes
.name
= "Rift LAB SFC-Demo SFC Network"
62 self
.l2netid
= l2top
.find_nw_id("L2HostNetwork-1")
65 ul_net
= self
.sfcnet1
.supporting_network
.add()
67 ul_net
.network_ref
= provtop
.find_nw_id("ProviderNetwork-1")
68 self
.provnetid
= ul_net
.network_ref
71 ul_net
= self
.sfcnet1
.supporting_network
.add()
73 ul_net
.network_ref
= vmtop
.find_nw_id("VmNetwork-1")
74 self
.vmnetid
= ul_net
.network_ref
78 def get_nw_id(self
, nw_name
):
79 for nw
in self
.nwtop
.network
:
80 if (nw
.network_id
== nw_name
):
83 def get_node(self
, node_name
):
84 _node_id
= "urn:Rift:Lab:" + node_name
85 for node
in self
.sfcnet1
.node
:
86 if (node
.node_id
== _node_id
):
89 def get_tp(self
, node
, tp_name
):
90 _tp_id
= "urn:Rift:Lab:" + node
.node_id
+ "_" + tp_name
91 for tp
in node
.termination_point
:
92 if (tp
.tp_id
== _tp_id
):
95 def get_link(self
, link_name
):
97 if (link
.l2_link_attributes
.name
== link_name
):
100 def create_node(self
, node_name
, description
, mgmt_ip_addr
= None, sup_node
= None, nw_ref
= None):
101 logging
.debug("Creating node %s", node_name
)
102 node
= self
.sfcnet1
.node
.add()
103 node
.node_id
= "urn:Rift:Lab:" + node_name
104 # L2 Node augmentation
105 node
.l2_node_attributes
.name
= node_name
106 node
.l2_node_attributes
.description
= description
107 if (mgmt_ip_addr
is not None):
108 node
.l2_node_attributes
.management_address
.append(mgmt_ip_addr
)
109 if (sup_node
is not None):
110 logging
.debug(" Adding support node %s", sup_node
.node_id
)
111 ul_node
= node
.supporting_node
.add()
112 if (nw_ref
is not None):
113 ul_node
.network_ref
= nw_ref
115 ul_node
.network_ref
= self
.l2netid
116 ul_node
.node_ref
= sup_node
.node_id
119 def create_tp(self
, node
, cfg_tp
, sup_node
= None, sup_tp
= None, nw_ref
= None):
120 logging
.debug(" Creating termination point %s %s", node
.l2_node_attributes
.name
, cfg_tp
)
121 tp
= node
.termination_point
.add()
122 tp
.tp_id
= ("{}:{}").format(node
.node_id
, cfg_tp
)
124 tp
.l2_termination_point_attributes
.description
= cfg_tp
125 tp
.l2_termination_point_attributes
.maximum_frame_size
= 1500
126 #tp.l2_termination_point_attributes.mac_address = "00:5e:8a:ab:dd:" + str(self.next_mac)
127 #self.next_mac = self.next_mac + 1
128 tp
.l2_termination_point_attributes
.eth_encapsulation
= "l2t:vxlan"
129 if ((sup_tp
is not None) and (sup_node
is not None)):
130 logging
.debug(" Adding support terminaton point %s", sup_tp
.tp_id
)
131 ul_tp
= tp
.supporting_termination_point
.add()
132 if (nw_ref
is not None):
133 ul_tp
.network_ref
= nw_ref
135 ul_tp
.network_ref
= self
.l2netid
136 ul_tp
.node_ref
= sup_node
.node_id
137 ul_tp
.tp_ref
= sup_tp
.tp_id
140 def create_link(self
, node1
, tp1
, node2
, tp2
, link_name1
, link_name2
= None):
141 logging
.debug("Creating links %s %s", link_name1
, link_name2
)
142 lnk1
= self
.sfcnet1
.link
.add()
143 lnk1
.link_id
= "urn:Rift:Lab:Ethernet:{}{}_{}{}".format(node1
.l2_node_attributes
.name
, tp1
.l2_termination_point_attributes
.description
, node2
.l2_node_attributes
.name
, tp2
.l2_termination_point_attributes
.description
)
144 lnk1
.source
.source_node
= node1
.node_id
145 lnk1
.source
.source_tp
= tp1
.tp_id
146 lnk1
.destination
.dest_node
= node2
.node_id
147 lnk1
.destination
.dest_tp
= tp2
.tp_id
148 # L2 link augmentation
149 lnk1
.l2_link_attributes
.name
= link_name1
150 lnk1
.l2_link_attributes
.rate
= 1000000000.00
152 # Create bidir link if second link is provided
153 if (link_name2
is not None):
154 lnk2
= self
.sfcnet1
.link
.add()
155 lnk2
.link_id
= "urn:Rift:Lab:Ethernet:{}{}_{}{}".format(node2
.l2_node_attributes
.name
, tp2
.l2_termination_point_attributes
.description
, node1
.l2_node_attributes
.name
, tp1
.l2_termination_point_attributes
.description
)
156 lnk2
.source
.source_node
= node2
.node_id
157 lnk2
.source
.source_tp
= tp2
.tp_id
158 lnk2
.destination
.dest_node
= node1
.node_id
159 lnk2
.destination
.dest_tp
= tp1
.tp_id
160 # L2 link augmentation
161 lnk2
.l2_link_attributes
.name
= link_name2
162 lnk2
.l2_link_attributes
.rate
= 1000000000.00
165 class MySfcTopology(MySfcNetwork
):
166 def __init__(self
, nwtop
, l2top
, provtop
, vmnet
, log
):
167 super(MySfcTopology
, self
).__init
__(nwtop
, l2top
, provtop
, vmnet
, log
)
169 def find_nw_id(self
, nw_name
):
170 return self
.get_nw_id(nw_name
)
172 def find_node(self
, node_name
):
173 return self
.get_node(node_name
)
175 def find_tp(self
, node
, tp_name
):
176 return self
.get_tp(node
, tp_name
)
178 def find_link(self
, link_name
):
179 return self
.get_link(link_name
)
181 def setup_nodes(self
):
182 logging
.debug("Setting up nodes")
184 self
.tg_node
= self
.vmtop
.find_node("Trafgen_VM")
185 if (self
.tg_node
is None):
186 raise MyNodeNotFound()
187 self
.lb_node
= self
.vmtop
.find_node("LB_VM")
188 if (self
.lb_node
is None):
189 raise MyNodeNotFound()
191 self
.g44_br_int_node
= self
.provtop
.find_node("G44_Br_Int")
192 if (self
.g44_br_int_node
is None):
193 raise MyNodeNotFound()
195 self
.sf1
= self
.create_node("SF1","SF on LB VM", sup_node
= self
.lb_node
, nw_ref
= self
.vmnetid
)
196 self
.sfc1
= self
.create_node("SFC1","SF classifier on Trafgen VM", sup_node
= self
.tg_node
, nw_ref
= self
.vmnetid
)
197 self
.sff1
= self
.create_node("SFF1","SF forwarder on Grunt44 OVS integration bridge", mgmt_ip_addr
="10.66.4.44", sup_node
= self
.g44_br_int_node
, nw_ref
= self
.provnetid
)
200 logging
.debug("Setting up termination points")
202 #self.g44_e2 = self.l2top.find_tp(self.g44_node, "eth2")
203 #if (self.g44_e2 is None):
204 # raise MyTpNotFound()
206 self
.sfc1_vxlannsh1
= self
.create_tp(self
.sfc1
, "vxlannsh1")
207 self
.sf1_vxlannsh1
= self
.create_tp(self
.sf1
, "vxlannsh1")
208 self
.sff1_vxlannsh1
= self
.create_tp(self
.sff1
, "vxlannsh1")
211 def setup_links(self
):
212 # Add links to sfcnet1 network
213 # These links are unidirectional and point-to-point
214 logging
.debug("Setting up links")
215 # Bidir Links for OVS bridges
216 self
.create_link(self
.sfc1
, self
.sfc1_vxlannsh1
, self
.sff1
, self
.sff1_vxlannsh1
, "Link_sfc1_sff1")
217 self
.create_link(self
.sfc1
, self
.sfc1_vxlannsh1
, self
.sf1
, self
.sf1_vxlannsh1
, "Link_sff1_sf1", "Link_sf1_sff1")
225 if __name__
== "__main__":
226 model
= RwYang
.Model
.create_libncx()
227 model
.load_schema_ypbc(RwTl
.get_schema())
229 logger
= logging
.getLogger('SFC Network Topology')
230 logger
.setLevel(logging
.DEBUG
)
231 logging
.basicConfig(level
=logging
.DEBUG
)
233 logger
.info('Creating an instance of SFC Network Topology')
235 nwtop
= RwTl
.YangData_IetfNetwork()
238 l2top
= MyL2Topology(nwtop
, logger
)
241 # Setup Provider network topology
242 provtop
= MyProvTopology(nwtop
, l2top
, logger
)
245 # Setup VM network topology
246 vmtop
= MyVMTopology(nwtop
, l2top
, provtop
, logger
)
249 # Setup SFC network topology
250 sfctop
= MySfcTopology(nwtop
, l2top
, provtop
, vmtop
, logger
)
253 print ("Converting to XML")
254 # Convert l2nw network to XML
255 xml_str
= nwtop
.to_xml_v2(model
)
256 tree
= etree
.XML(xml_str
)
257 xml_file
= "/tmp/stacked_sfctop.xml"
258 xml_formatted_file
= "/tmp/stacked_sfctop2.xml"
259 with
open(xml_file
, "w") as f
:
261 status
= subprocess
.call("xmllint --format " + xml_file
+ " > " + xml_formatted_file
, shell
=True)
263 status
= subprocess
.call("sed -i '/xml version/d' " + xml_formatted_file
, shell
=True)
264 status
= subprocess
.call("sed -i '/root xmlns/d' " + xml_formatted_file
, shell
=True)
265 status
= subprocess
.call("sed -i '/\/root/d' " + xml_formatted_file
, shell
=True)
267 print ("Converting to JSON ")
268 # Convert set of topologies to JSON
269 json_str
= nwtop
.to_json(model
)
270 with
open("/tmp/stacked_sfctop.json", "w") as f
:
272 status
= subprocess
.call("python -m json.tool /tmp/stacked_sfctop.json > /tmp/stacked_sfctop2.json", shell
=True)
273 json_formatted_file
= "/tmp/stacked_sfctop2.json"
274 status
= subprocess
.call("sed -i -e 's/\"l2t:ethernet\"/\"ethernet\"/g' " + json_formatted_file
, shell
=True)
275 status
= subprocess
.call("sed -i -e 's/\"l2t:vlan\"/\"vlan\"/g' " + json_formatted_file
, shell
=True)
276 status
= subprocess
.call("sed -i -e 's/\"l2t:vxlan\"/\"vxlan\"/g' " + json_formatted_file
, shell
=True)