3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
22 gi
.require_version('RwTypes', '1.0')
23 gi
.require_version('RwcalYang', '1.0')
24 gi
.require_version('RwSdn', '1.0')
25 from gi
.repository
import (
29 RwTopologyYang
as RwTl
,
36 logger
= logging
.getLogger('rwsdn.mock')
39 class UnknownAccountError(Exception):
43 class MissingFileError(Exception):
47 rwstatus
= rw_status
.rwstatus_from_exc_map({
48 IndexError: RwTypes
.RwStatus
.NOTFOUND
,
49 KeyError: RwTypes
.RwStatus
.NOTFOUND
,
50 UnknownAccountError
: RwTypes
.RwStatus
.NOTFOUND
,
51 MissingFileError
: RwTypes
.RwStatus
.NOTFOUND
,
54 GRUNT118
= {"name": "grunt118", "ip_addr": "10.66.4.118", "tps": ["eth0"]}
55 GRUNT44
= {"name": "grunt44", "ip_addr": "10.66.4.44", "tps": ["eth0"]}
56 AS1
= {"name":"AristaSw1", "ip_addr": "10.66.4.54", "tps": ["Ethernet8/7","Ethernet8/8"]}
57 NW_NODES
= [GRUNT118
, GRUNT44
, AS1
]
58 NW_BIDIR_LINKS
= [{"src" : ("grunt118","eth0"), "dest" : ("AristaSw1","Ethernet8/7")},
59 {"src" : ("grunt44","eth0"), "dest" : ("AristaSw1","Ethernet8/8")}]
62 class DataStore(object):
68 def create_link(self
, cfg_src_node
, cfg_src_tp
, cfg_dest_node
, cfg_dest_tp
):
69 lnk
= self
.nw
.link
.add()
70 lnk
.link_id
= "urn:Rift:Lab:Ethernet:{}{}_{}{}".format(cfg_src_node
, cfg_src_tp
, cfg_dest_node
, cfg_dest_tp
)
71 lnk
.source
.source_node
= cfg_src_node
72 lnk
.source
.source_tp
= cfg_src_tp
73 lnk
.destination
.dest_node
= cfg_dest_node
74 lnk
.destination
.dest_tp
= cfg_dest_tp
75 # L2 link augmentation
76 lnk
.l2_link_attributes
.name
= cfg_src_tp
+ cfg_dest_tp
77 lnk
.l2_link_attributes
.rate
= 1000000000.00
79 def create_tp(self
, node
, cfg_tp
):
80 tp
= node
.termination_point
.add()
81 tp
.tp_id
= ("urn:Rift:Lab:{}:{}").format(node
.node_id
, cfg_tp
)
83 tp
.l2_termination_point_attributes
.description
= cfg_tp
84 tp
.l2_termination_point_attributes
.maximum_frame_size
= 1500
85 tp
.l2_termination_point_attributes
.mac_address
= "00:1e:67:d8:48:" + str(self
.next_mac
)
86 self
.next_mac
= self
.next_mac
+ 1
87 tp
.l2_termination_point_attributes
.tp_state
= "in_use"
88 tp
.l2_termination_point_attributes
.eth_encapsulation
= "ethernet"
90 def create_node(self
, cfg_node
):
91 node
= self
.nw
.node
.add()
92 node
.node_id
= cfg_node
['name']
93 # L2 Node augmentation
94 node
.l2_node_attributes
.name
= cfg_node
['name']
95 node
.l2_node_attributes
.description
= "Host with OVS-DPDK"
96 node
.l2_node_attributes
.management_address
.append(cfg_node
['ip_addr'])
97 for cfg_tp
in cfg_node
['tps']:
98 self
.create_tp(node
, cfg_tp
)
100 def create_default_topology(self
):
101 logger
.debug('Creating default topology: ')
103 self
.topology
= RwTl
.YangData_IetfNetwork()
104 self
.nw
= self
.topology
.network
.add()
105 self
.nw
.network_id
= "L2HostTopology-Def1"
106 self
.nw
.server_provided
= 'true'
108 # L2 Network type augmentation
109 self
.nw
.network_types
.l2_network
= self
.nw
.network_types
.l2_network
.new()
110 # L2 Network augmentation
111 self
.nw
.l2_network_attributes
.name
= "Rift LAB SFC-Demo Host Network"
113 for cfg_node
in NW_NODES
:
114 self
.create_node(cfg_node
)
116 for cfg_link
in NW_BIDIR_LINKS
:
117 self
.create_link(cfg_link
['src'][0], cfg_link
['src'][1], cfg_link
['dest'][0], cfg_link
['dest'][1])
118 self
.create_link(cfg_link
['src'][1], cfg_link
['src'][0], cfg_link
['dest'][1], cfg_link
['dest'][0])
123 class Resources(object):
125 self
.networks
= dict()
128 class MockPlugin(GObject
.Object
, RwSdn
.Topology
):
129 """This class implements the abstract methods in the Topology class.
130 Mock is used for unit testing."""
133 GObject
.Object
.__init
__(self
)
134 self
.resources
= collections
.defaultdict(Resources
)
135 self
.datastore
= None
138 def do_init(self
, rwlog_ctx
):
139 if not any(isinstance(h
, rwlogger
.RwLogger
) for h
in logger
.handlers
):
142 subcategory
="rwsdn.mock",
147 account
= RwsdnalYang
.YangData_RwProject_Project_SdnAccounts_SdnAccountList()
148 account
.name
= 'mock'
149 account
.account_type
= 'mock'
150 account
.mock
.username
= 'rift'
152 self
.datastore
= DataStore()
153 self
.topology
= self
.datastore
.create_default_topology()
155 @rwstatus(ret_on_failure
=[None])
156 def do_get_network_list(self
, account
):
158 Returns the list of discovered network
160 @param account - a SDN account
163 logger
.debug('Get network list: ')
166 logger
.debug('Returning network list: ')
169 logger
.debug('Returning empty network list: ')