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
32 class MyNwNotFound(Exception):
35 class MyNodeNotFound(Exception):
38 class MyTpNotFound(Exception):
41 class MyProvNetwork(object):
42 def __init__(self
, nwtop
, l2top
, log
):
45 self
.provnet1
= nwtop
.network
.add()
46 self
.provnet1
.network_id
= "ProviderNetwork-1"
51 # L2 Network type augmentation
52 self
.provnet1
.network_types
.l2_network
= self
.provnet1
.network_types
.l2_network
.new()
53 # L2 Network augmentation
54 self
.provnet1
.l2_network_attributes
.name
= "Rift LAB SFC-Demo Provider Network"
55 ul_net
= self
.provnet1
.supporting_network
.add()
57 ul_net
.network_ref
= l2top
.find_nw_id("L2HostNetwork-1")
58 self
.l2netid
= ul_net
.network_ref
62 def get_nw_id(self
, nw_name
):
63 for nw
in self
.nwtop
.network
:
64 if (nw
.network_id
== nw_name
):
67 def get_node(self
, node_name
):
68 _node_id
= "urn:Rift:Lab:" + node_name
69 for node
in self
.provnet1
.node
:
70 if (node
.node_id
== _node_id
):
73 def get_tp(self
, node
, tp_name
):
74 _tp_id
= node
.node_id
+ ":" + tp_name
75 for tp
in node
.termination_point
:
76 if (tp
.tp_id
== _tp_id
):
79 def get_link(self
, link_name
):
81 if (link
.l2_link_attributes
.name
== link_name
):
84 def create_node(self
, node_name
, description
, mgmt_ip_addr
= None, sup_node
= None):
85 logging
.debug("Creating node %s", node_name
)
86 node
= self
.provnet1
.node
.add()
87 node
.node_id
= "urn:Rift:Lab:" + node_name
88 # L2 Node augmentation
89 node
.l2_node_attributes
.name
= node_name
90 node
.l2_node_attributes
.description
= description
91 if (mgmt_ip_addr
is not None):
92 node
.l2_node_attributes
.management_address
.append(mgmt_ip_addr
)
93 if (sup_node
is not None):
94 logging
.debug(" Adding support node %s", sup_node
.node_id
)
95 ul_node
= node
.supporting_node
.add()
96 ul_node
.network_ref
= self
.l2netid
97 ul_node
.node_ref
= sup_node
.node_id
100 def create_tp(self
, node
, cfg_tp
, sup_node
= None, sup_tp
= None, vlan
= False):
101 logging
.debug(" Creating termination point %s %s", node
.l2_node_attributes
.name
, cfg_tp
)
102 tp
= node
.termination_point
.add()
103 tp
.tp_id
= ("{}:{}").format(node
.node_id
, cfg_tp
)
105 tp
.l2_termination_point_attributes
.description
= cfg_tp
106 tp
.l2_termination_point_attributes
.maximum_frame_size
= 1500
107 tp
.l2_termination_point_attributes
.mac_address
= "00:4f:9c:ab:dd:" + str(self
.next_mac
)
108 self
.next_mac
= self
.next_mac
+ 1
110 tp
.l2_termination_point_attributes
.eth_encapsulation
= "l2t:vlan"
112 tp
.l2_termination_point_attributes
.eth_encapsulation
= "l2t:ethernet"
113 if ((sup_tp
is not None) and (sup_node
is not None)):
114 logging
.debug(" Adding support terminaton point %s", sup_tp
.tp_id
)
115 ul_tp
= tp
.supporting_termination_point
.add()
116 ul_tp
.network_ref
= self
.l2netid
117 ul_tp
.node_ref
= sup_node
.node_id
118 ul_tp
.tp_ref
= sup_tp
.tp_id
121 def create_bidir_link(self
, node1
, tp1
, node2
, tp2
, link_name1
, link_name2
):
122 logging
.debug("Creating links %s %s", link_name1
, link_name2
)
123 lnk1
= self
.provnet1
.link
.add()
124 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
)
125 lnk1
.source
.source_node
= node1
.node_id
126 lnk1
.source
.source_tp
= tp1
.tp_id
127 lnk1
.destination
.dest_node
= node2
.node_id
128 lnk1
.destination
.dest_tp
= tp2
.tp_id
129 # L2 link augmentation
130 lnk1
.l2_link_attributes
.name
= link_name1
131 #lnk1.l2_link_attributes.rate = 1000000000.00
133 lnk2
= self
.provnet1
.link
.add()
134 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
)
135 lnk2
.source
.source_node
= node2
.node_id
136 lnk2
.source
.source_tp
= tp2
.tp_id
137 lnk2
.destination
.dest_node
= node1
.node_id
138 lnk2
.destination
.dest_tp
= tp1
.tp_id
139 # L2 link augmentation
140 lnk2
.l2_link_attributes
.name
= link_name2
141 #lnk2.l2_link_attributes.rate = 1000000000.00
144 class MyProvTopology(MyProvNetwork
):
145 def __init__(self
, nwtop
, l2top
, log
):
146 super(MyProvTopology
, self
).__init
__(nwtop
, l2top
, log
)
148 def find_nw_id(self
, nw_name
):
149 return self
.get_nw_id(nw_name
)
151 def find_node(self
, node_name
):
152 return self
.get_node(node_name
)
154 def find_tp(self
, node
, tp_name
):
155 return self
.get_tp(node
, tp_name
)
157 def find_link(self
, link_name
):
158 return self
.get_link(link_name
)
160 def setup_nodes(self
):
161 logging
.debug("Setting up nodes")
162 self
.pseudo_mgmt_node
= self
.create_node("Pseudo_mgmt_node", "Pseudo node for VM mgmt network LAN")
163 self
.pseudo_dp_node
= self
.create_node("Pseudo_DP_node", "Pseudo node for DP network LAN")
165 self
.g118_node
= self
.l2top
.find_node("Grunt118")
166 if (self
.g118_node
is None):
167 raise MyNodeNotFound()
168 self
.g44_node
= self
.l2top
.find_node("Grunt44")
169 if (self
.g44_node
is None):
170 raise MyNodeNotFound()
171 self
.g120_node
= self
.l2top
.find_node("Grunt120")
172 if (self
.g120_node
is None):
173 raise MyNodeNotFound()
175 self
.g118_br_int
= self
.create_node("G118_Br_Int","OVS Integration bridge on Grunt118", mgmt_ip_addr
="10.66.4.118", sup_node
= self
.g118_node
)
176 self
.g118_br_eth1
= self
.create_node("G118_Br_Eth1","OVS Integration bridge on Grunt118", mgmt_ip_addr
="10.66.4.118", sup_node
= self
.g118_node
)
177 # eth2 on g118 is being used in PCI passthrough mode
179 self
.g44_br_int
= self
.create_node("G44_Br_Int","OVS Integration bridge on Grunt44", mgmt_ip_addr
="10.66.4.44", sup_node
= self
.g44_node
)
180 self
.g44_br_eth1
= self
.create_node("G44_Br_Eth1","OVS Interface bridge on Grunt44", mgmt_ip_addr
="10.66.4.44", sup_node
= self
.g44_node
)
181 self
.g44_br_eth2
= self
.create_node("G44_Br_Eth2","OVS Interface bridge on Grunt44", mgmt_ip_addr
="10.66.4.44", sup_node
= self
.g44_node
)
182 self
.g44_br_eth3
= self
.create_node("G44_Br_Eth3","OVS Interface bridge on Grunt44", mgmt_ip_addr
="10.66.4.44", sup_node
= self
.g44_node
)
184 self
.g120_br_int
= self
.create_node("G120_Br_Int","OVS Integration bridge on Grunt120", mgmt_ip_addr
= "10.66.4.120", sup_node
= self
.g120_node
)
185 self
.g120_br_eth1
= self
.create_node("G120_Br_Eth1","OVS Integration bridge on Grunt120", mgmt_ip_addr
= "10.66.4.120", sup_node
= self
.g120_node
)
186 # eth2 on g120 is being used in PCI passthrough mode
189 logging
.debug("Setting up termination points")
190 self
.g118_e1
= self
.l2top
.find_tp(self
.g118_node
, "eth1")
191 if (self
.g118_e1
is None):
193 self
.g44_e1
= self
.l2top
.find_tp(self
.g44_node
, "eth1")
194 if (self
.g44_e1
is None):
196 self
.g44_e2
= self
.l2top
.find_tp(self
.g44_node
, "eth2")
197 if (self
.g44_e2
is None):
199 self
.g44_e3
= self
.l2top
.find_tp(self
.g44_node
, "eth3")
200 if (self
.g44_e3
is None):
202 self
.g120_e1
= self
.l2top
.find_tp(self
.g120_node
, "eth1")
203 if (self
.g44_e3
is None):
206 self
.g118_br_int_eth1
= self
.create_tp(self
.g118_br_int
, "int-br-eth1")
207 self
.g118_br_int_tap1
= self
.create_tp(self
.g118_br_int
, "tap1")
209 self
.g118_br_eth1_phyeth1
= self
.create_tp(self
.g118_br_eth1
, "phyeth1")
210 self
.g118_br_eth1_eth1
= self
.create_tp(self
.g118_br_eth1
, "eth1", sup_node
=self
.g118_node
, sup_tp
=self
.g118_e1
, vlan
=True)
212 self
.g44_br_int_eth1
= self
.create_tp(self
.g44_br_int
, "int-br-eth1")
213 self
.g44_br_int_vhu1
= self
.create_tp(self
.g44_br_int
, "vhu1")
214 self
.g44_br_int_eth2
= self
.create_tp(self
.g44_br_int
, "int-br-eth2")
215 self
.g44_br_int_vhu2
= self
.create_tp(self
.g44_br_int
, "vhu2")
216 self
.g44_br_int_eth1
= self
.create_tp(self
.g44_br_int
, "int-br-eth3")
217 self
.g44_br_int_vhu1
= self
.create_tp(self
.g44_br_int
, "vhu3")
219 self
.g44_br_eth1_phyeth1
= self
.create_tp(self
.g44_br_eth1
, "phyeth1")
220 self
.g44_br_eth1_dpdk0
= self
.create_tp(self
.g44_br_eth1
, "dpdk0", sup_node
=self
.g44_node
, sup_tp
=self
.g44_e1
, vlan
=True)
222 self
.g44_br_eth2_phyeth1
= self
.create_tp(self
.g44_br_eth2
, "phyeth2")
223 self
.g44_br_eth2_dpdk1
= self
.create_tp(self
.g44_br_eth2
, "dpdk1", sup_node
=self
.g44_node
, sup_tp
=self
.g44_e2
)
225 self
.g44_br_eth3_phyeth1
= self
.create_tp(self
.g44_br_eth3
, "phyeth3")
226 self
.g44_br_eth3_dpdk2
= self
.create_tp(self
.g44_br_eth3
, "dpdk2", sup_node
=self
.g44_node
, sup_tp
=self
.g44_e3
)
228 self
.g120_br_int_eth1
= self
.create_tp(self
.g120_br_int
, "int-br-eth1")
229 self
.g120_br_int_tap1
= self
.create_tp(self
.g120_br_int
, "tap1")
231 self
.g120_br_eth1_phyeth1
= self
.create_tp(self
.g120_br_eth1
, "phyeth1")
232 self
.g120_br_eth1_eth1
= self
.create_tp(self
.g120_br_eth1
, "eth1", sup_node
=self
.g120_node
, sup_tp
=self
.g120_e1
, vlan
=True)
234 self
.pmn_eth1
= self
.create_tp(self
.pseudo_mgmt_node
, "eth1")
235 self
.pmn_eth2
= self
.create_tp(self
.pseudo_mgmt_node
, "eth2")
236 self
.pmn_eth3
= self
.create_tp(self
.pseudo_mgmt_node
, "eth3")
238 def setup_links(self
):
239 # Add links to provnet1 network
240 # These links are unidirectional and point-to-point
241 logging
.debug("Setting up links")
242 # Bidir Links for OVS bridges
243 self
.create_bidir_link(self
.g118_br_eth1
, self
.g118_br_eth1_eth1
, self
.pseudo_mgmt_node
, self
.pmn_eth1
, "Link_g118_be1_pmn_e1", "Link_pmn_e1_g118_be1")
244 self
.create_bidir_link(self
.g44_br_eth1
, self
.g44_br_eth1_dpdk0
, self
.pseudo_mgmt_node
, self
.pmn_eth2
, "Link_g44_be1_pmn_d0", "Link_pmn_e2_g44_d0")
245 self
.create_bidir_link(self
.g120_br_eth1
, self
.g120_br_eth1_eth1
, self
.pseudo_mgmt_node
, self
.pmn_eth3
, "Link_g120_be1_pmn_e3", "Link_pmn_e3_g120_be1")
246 # Data path links cannot be represented here since PCI pass through is beingused on G118 and G44
253 def adjust_xml_file(infile
, outfile
, begin_marker
, end_marker
):
256 max_interesting_line_toread
= 1
258 with
open(infile
) as inf
:
259 with
open(outfile
, 'w') as outf
:
261 if begin_marker
in line
:
264 if end_marker
in line
:
265 assert in_block
is True
266 print("End of gathering line...", line
)
267 buffer.append(line
) # gather lines
268 interesting_line
= max_interesting_line_toread
272 print("Interesting line printing ...", line
)
274 interesting_line
-= 1
275 if interesting_line
== 0: # output gathered lines
278 buffer = [] # empty buffer
283 print("Gathering line...", line
)
284 buffer.append(line
) # gather lines
289 if __name__
== "__main__":
290 model
= RwYang
.Model
.create_libncx()
291 model
.load_schema_ypbc(RwTl
.get_schema())
293 logger
= logging
.getLogger('Provider Network Topology')
294 logger
.setLevel(logging
.DEBUG
)
295 logging
.basicConfig(level
=logging
.DEBUG
)
297 logger
.info('Creating an instance of Provider Network Topology')
299 nwtop
= RwTl
.YangData_IetfNetwork()
302 l2top
= MyL2Topology(nwtop
, logger
)
305 # Setup Provider network topology
306 provtop
= MyProvTopology(nwtop
, l2top
, logger
)
309 print ("Converting to XML")
310 # Convert l2nw network to XML
311 xml_str
= nwtop
.to_xml_v2(model
)
312 tree
= etree
.XML(xml_str
)
313 xml_file
= "/tmp/stacked_provtop.xml"
314 xml_formatted_file
= "/tmp/stacked_provtop2.xml"
315 with
open(xml_file
, "w") as f
:
317 status
= subprocess
.call("xmllint --format " + xml_file
+ " > " + xml_formatted_file
, shell
=True)
319 status
= subprocess
.call("sed -i '/xml version/d' " + xml_formatted_file
, shell
=True)
320 status
= subprocess
.call("sed -i '/root xmlns/d' " + xml_formatted_file
, shell
=True)
321 status
= subprocess
.call("sed -i '/\/root/d' " + xml_formatted_file
, shell
=True)
323 print ("Converting to JSON ")
324 # Convert set of topologies to JSON
325 json_str
= nwtop
.to_json(model
)
326 with
open("/tmp/stacked_provtop.json", "w") as f
:
328 status
= subprocess
.call("python -m json.tool /tmp/stacked_provtop.json > /tmp/stacked_provtop2.json", shell
=True)
329 json_formatted_file
= "/tmp/stacked_provtop2.json"
330 status
= subprocess
.call("sed -i -e 's/\"l2t:ethernet\"/\"ethernet\"/g' " + json_formatted_file
, shell
=True)
331 status
= subprocess
.call("sed -i -e 's/\"l2t:vlan\"/\"vlan\"/g' " + json_formatted_file
, shell
=True)