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
30 class MyL2Network(object):
31 def __init__(self
, nwtop
, log
):
35 self
.l2net1
= nwtop
.network
.add()
36 self
.l2net1
.network_id
= "L2HostNetwork-1"
38 # L2 Network type augmentation
39 self
.l2net1
.network_types
.l2_network
= self
.l2net1
.network_types
.l2_network
.new()
40 # L2 Network augmentation
41 self
.l2net1
.l2_network_attributes
.name
= "Rift LAB SFC-Demo Host Network"
43 def get_nw_id(self
, nw_name
):
44 for nw
in self
.nwtop
.network
:
45 if (nw
.network_id
== nw_name
):
48 def get_nw(self
, nw_name
):
49 for nw
in self
.nwtop
.network
:
50 if (nw
.network_id
== nw_name
):
53 def get_node(self
, node_name
):
54 _node_id
= "urn:Rift:Lab:" + node_name
55 for node
in self
.l2net1
.node
:
56 if (node
.node_id
== _node_id
):
59 def get_tp(self
, node
, tp_name
):
60 _tp_id
= node
.node_id
+ "_" + tp_name
61 for tp
in node
.termination_point
:
62 if (tp
.tp_id
== _tp_id
):
65 def get_link(self
, link_name
):
67 if (link
.l2_link_attributes
.name
== link_name
):
70 def create_node(self
, node_name
, mgmt_ip_addr
, description
):
71 logging
.debug("Creating node %s", node_name
)
72 node
= self
.l2net1
.node
.add()
73 node
.node_id
= "urn:Rift:Lab:" + node_name
74 # L2 Node augmentation
75 node
.l2_node_attributes
.name
= node_name
76 node
.l2_node_attributes
.description
= description
77 node
.l2_node_attributes
.management_address
.append(mgmt_ip_addr
)
80 def create_tp(self
, node
, cfg_tp
):
81 logging
.debug(" Creating termination point %s %s", node
.l2_node_attributes
.name
, cfg_tp
)
82 tp
= node
.termination_point
.add()
83 tp
.tp_id
= ("{}_{}").format(node
.node_id
, cfg_tp
)
85 tp
.l2_termination_point_attributes
.description
= cfg_tp
86 tp
.l2_termination_point_attributes
.maximum_frame_size
= 1500
87 tp
.l2_termination_point_attributes
.mac_address
= "00:1e:67:d8:48:" + str(self
.next_mac
)
88 self
.next_mac
= self
.next_mac
+ 1
89 tp
.l2_termination_point_attributes
.eth_encapsulation
= "l2t:ethernet"
92 def create_bidir_link(self
, node1
, tp1
, node2
, tp2
, link_name1
, link_name2
):
93 logging
.debug("Creating links %s %s", link_name1
, link_name2
)
94 lnk1
= self
.l2net1
.link
.add()
95 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
)
96 lnk1
.source
.source_node
= node1
.node_id
97 lnk1
.source
.source_tp
= tp1
.tp_id
98 lnk1
.destination
.dest_node
= node2
.node_id
99 lnk1
.destination
.dest_tp
= tp2
.tp_id
100 # L2 link augmentation
101 lnk1
.l2_link_attributes
.name
= link_name1
102 #lnk1.l2_link_attributes.rate = 1000000000.00
104 lnk2
= self
.l2net1
.link
.add()
105 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
)
106 lnk2
.source
.source_node
= node2
.node_id
107 lnk2
.source
.source_tp
= tp2
.tp_id
108 lnk2
.destination
.dest_node
= node1
.node_id
109 lnk2
.destination
.dest_tp
= tp1
.tp_id
110 # L2 link augmentation
111 lnk2
.l2_link_attributes
.name
= link_name2
112 #lnk2.l2_link_attributes.rate = 1000000000.00
115 class MyL2Topology(MyL2Network
):
116 def __init__(self
, nwtop
, log
):
117 super(MyL2Topology
, self
).__init
__(nwtop
, log
)
119 def find_nw_id(self
, nw_name
):
120 return self
.get_nw_id(nw_name
)
122 def find_nw(self
, nw_name
):
123 return self
.get_nw(nw_name
)
125 def find_node(self
, node_name
):
126 return self
.get_node(node_name
)
128 def find_tp(self
, node
, tp_name
):
129 return self
.get_tp(node
, tp_name
)
131 def find_link(self
, link_name
):
132 return self
.get_link(link_name
)
134 def setup_nodes(self
):
135 self
.g118
= self
.create_node("Grunt118","10.66.4.118", "Host with OVS and PCI")
136 self
.g44
= self
.create_node("Grunt44","10.66.4.44", "Host with OVS-DPDK")
137 self
.g120
= self
.create_node("Grunt120","10.66.4.120", "Host with OVS and PCI")
138 self
.hms
= self
.create_node("HostMgmtSwitch","10.66.4.98", "Switch for host eth0")
139 self
.vms
= self
.create_node("VMMgmtSwitch","10.66.4.55", "Switch for VMs eth0")
140 self
.ads
= self
.create_node("AristaDPSwitch","10.66.4.90", "10 Gbps Switch")
143 self
.g118_e0
= self
.create_tp(self
.g118
, "eth0")
144 self
.g118_e1
= self
.create_tp(self
.g118
, "eth1")
145 self
.g118_e2
= self
.create_tp(self
.g118
, "eth2")
147 self
.g44_e0
= self
.create_tp(self
.g44
, "eth0")
148 self
.g44_e1
= self
.create_tp(self
.g44
, "eth1")
149 self
.g44_e2
= self
.create_tp(self
.g44
, "eth2")
150 self
.g44_e3
= self
.create_tp(self
.g44
, "eth3")
152 self
.g120_e0
= self
.create_tp(self
.g120
, "eth0")
153 self
.g120_e1
= self
.create_tp(self
.g120
, "eth1")
154 self
.g120_e2
= self
.create_tp(self
.g120
, "eth2")
156 self
.hms_e1
= self
.create_tp(self
.hms
, "eth1")
157 self
.hms_e2
= self
.create_tp(self
.hms
, "eth2")
158 self
.hms_e3
= self
.create_tp(self
.hms
, "eth3")
160 self
.vms_e1
= self
.create_tp(self
.vms
, "eth1")
161 self
.vms_e2
= self
.create_tp(self
.vms
, "eth2")
162 self
.vms_e3
= self
.create_tp(self
.vms
, "eth3")
164 self
.ads_57
= self
.create_tp(self
.ads
, "Card_5:Port_7")
165 self
.ads_58
= self
.create_tp(self
.ads
, "Card_8:Port_8")
166 self
.ads_47
= self
.create_tp(self
.ads
, "Card_4:Port_7")
167 self
.ads_48
= self
.create_tp(self
.ads
, "Card_4:Port_8")
169 def setup_links(self
):
170 # Add links to l2net1 network
171 # These links are unidirectional and point-to-point
172 # Bidir Links for Grunt118
173 self
.create_bidir_link(self
.g118
, self
.g118_e0
, self
.hms
, self
.hms_e1
, "Link_g118_e0_hms_e1", "Link_hms_e1_g118_e0")
174 self
.create_bidir_link(self
.g118
, self
.g118_e1
, self
.vms
, self
.vms_e1
, "Link_g118_e1_vms_e1", "Link_vms_e1_g118_e1")
175 self
.create_bidir_link(self
.g118
, self
.g118_e2
, self
.ads
, self
.ads_57
, "Link_g118_e2_ads_47", "Link_ads_47_g118_e2")
176 # Bidir Links for Grunt44
177 self
.create_bidir_link(self
.g44
, self
.g44_e0
, self
.hms
, self
.hms_e2
, "Link_g44_e0_hms_e1", "Link_hms_e1_g44_e0")
178 self
.create_bidir_link(self
.g44
, self
.g44_e1
, self
.vms
, self
.vms_e2
, "Link_g44_e1_vms_e1", "Link_vms_e1_g44_e1")
179 self
.create_bidir_link(self
.g44
, self
.g44_e2
, self
.ads
, self
.ads_47
, "Link_g44_e2_ads_47", "Link_ads_47_g44_e2")
180 self
.create_bidir_link(self
.g44
, self
.g44_e3
, self
.ads
, self
.ads_48
, "Link_g44_e3_ads_48", "Link_ads_48_g44_e3")
181 # Bidir Links for Grunt120
182 self
.create_bidir_link(self
.g120
, self
.g120_e0
, self
.hms
, self
.hms_e3
, "Link_g120_e0_hms_e1", "Link_hms_e1_g120_e0")
183 self
.create_bidir_link(self
.g120
, self
.g120_e1
, self
.vms
, self
.vms_e3
, "Link_g120_e1_vms_e1", "Link_vms_e1_g120_e1")
184 self
.create_bidir_link(self
.g120
, self
.g120_e2
, self
.ads
, self
.ads_58
, "Link_g120_e2_ads_58", "Link_ads_58_g120_e2")
191 def adjust_xml_file(infile
, outfile
, begin_marker
, end_marker
):
194 max_interesting_line_toread
= 1
196 with
open(infile
) as inf
:
197 with
open(outfile
, 'w') as outf
:
199 if begin_marker
in line
:
202 if end_marker
in line
:
203 assert in_block
is True
204 print("End of gathering line...", line
)
205 buffer.append(line
) # gather lines
206 interesting_line
= max_interesting_line_toread
210 print("Interesting line printing ...", line
)
212 interesting_line
-= 1
213 if interesting_line
== 0: # output gathered lines
216 buffer = [] # empty buffer
221 print("Gathering line...", line
)
222 buffer.append(line
) # gather lines
226 if __name__
== "__main__":
227 model
= RwYang
.Model
.create_libncx()
228 model
.load_schema_ypbc(RwTl
.get_schema())
230 logger
= logging
.getLogger(__file__
)
231 logger
.setLevel(logging
.DEBUG
)
232 logging
.basicConfig(level
=logging
.DEBUG
)
234 logging
.info('Creating an instance of L2 Host Topology')
235 nwtop
= RwTl
.YangData_IetfNetwork()
237 l2top
= MyL2Topology(nwtop
, logger
)
240 logging
.info ("Converting to XML")
241 # Convert l2nw network to XML
242 xml_str
= nwtop
.to_xml_v2(model
)
243 tree
= etree
.XML(xml_str
)
244 xml_file
= "/tmp/stacked_top.xml"
245 xml_formatted_file
= "/tmp/stacked_top2.xml"
246 with
open(xml_file
, "w") as f
:
248 status
= subprocess
.call("xmllint --format " + xml_file
+ " > " + xml_formatted_file
, shell
=True)
249 status
= subprocess
.call("sed -i '/xml version/d' " + xml_formatted_file
, shell
=True)
250 status
= subprocess
.call("sed -i '/root xmlns/d' " + xml_formatted_file
, shell
=True)
251 status
= subprocess
.call("sed -i '/\/root/d' " + xml_formatted_file
, shell
=True)
253 logging
.info ("Converting to JSON")
254 # Convert set of topologies to JSON
255 json_str
= nwtop
.to_json(model
)
256 with
open("/tmp/stacked_top.json", "w") as f
:
258 status
= subprocess
.call("python -m json.tool /tmp/stacked_top.json > /tmp/stacked_top2.json", shell
=True)
259 json_formatted_file
= "/tmp/stacked_top2.json"
260 status
= subprocess
.call("sed -i -e 's/\"l2t:ethernet\"/\"ethernet\"/g' " + json_formatted_file
, shell
=True)