1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2012 Nicira Networks
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
# not use this file except in compliance with the License. You may obtain
8
# 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, WITHOUT
14
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
# License for the specific language governing permissions and limitations
17
# @author: Dan Wendlandt Nicira Networks
19
from nova.network.quantum import client
20
from nova import utils
22
#TODO(danwent): would be nice to have these functions raise QuantumIOErrors
23
# to make sure such errors are caught and reported properly
26
# this is a fake quantum client that just stores all data in a nested dict
31
# { '<net-uuid>' : { 'name' : "t1-net1",
32
# 'ports' : [ { '<port-uuid'> :
34
# 'attachment': 'iface-id'},
36
# 'attachment' : None}}]
42
class FakeClient(object):
43
"""A fake Quantum Client for testing"""
45
def __init__(self, logger=None, **kwargs):
46
"""Creates a new client to some service.
47
:param logger: logging object to be used by client library
52
def _get_tenant_nets(self, tenant):
54
raise Exception("'tenant' cannot be None")
55
return self.tenant_map.setdefault(tenant, {})
57
def _verify_net(self, network, nets):
58
if network not in nets:
59
raise client.QuantumNotFoundException("no network with uuid %s"
62
def _verify_net_and_port(self, network, port, nets):
63
if network not in nets:
64
raise client.QuantumNotFoundException("no network with uuid %s"
66
if port not in nets[network]['ports']:
67
raise client.QuantumNotFoundException("no port with uuid %s"
70
def list_networks(self, tenant=None, filter_ops=None):
71
"""Fetches a list of all networks for a tenant"""
72
nets = self._get_tenant_nets(tenant)
74
raise Exception("Need to implement filters %s in "
75
"quantum fake client" % filter_ops)
76
return {"networks": [{"id": uuid} for uuid in nets.keys()]}
78
def show_network_details(self, network, tenant=None):
79
"""Fetches the details of a certain network"""
80
nets = self._get_tenant_nets(tenant)
81
self._verify_net(network, nets)
82
return {"network": {"id": network, "name": nets[network]["name"]}}
84
def create_network(self, body=None, tenant=None):
85
"""Creates a new network"""
86
nets = self._get_tenant_nets(tenant)
87
uuid = str(utils.gen_uuid())
88
name = body["network"]["name"]
89
nets[uuid] = {"ports": {}, "name": name}
90
return {"network": {"id": uuid}}
92
def update_network(self, network, body=None, tenant=None):
93
"""Updates a network"""
94
nets = self._get_tenant_nets(tenant)
95
self._verify_net(network, nets)
96
nets[network]['name'] = body["network"]["name"]
97
return {"network": {"id": network, "name": nets[networks]["name"]}}
99
def delete_network(self, network, tenant=None):
100
"""Deletes the specified network"""
101
nets = self._get_tenant_nets(tenant)
102
self._verify_net(network, nets)
105
def list_ports(self, network, filter_ops=None, tenant=None):
106
"""Fetches a list of ports on a given network"""
107
nets = self._get_tenant_nets(tenant)
108
self._verify_net(network, nets)
110
ports = nets[network]['ports'].items()
111
if filter_ops and 'attachment' in filter_ops:
112
a = filter_ops.pop('attachment')
113
ports = [p for p in ports if p[1]['attachment'] == a]
116
raise Exception("Need to implement files %s in "
117
"quantum fake client" % filter_ops)
119
return {"ports": [{'id': p[0]} for p in ports]}
121
def show_port_details(self, network, port, tenant=None):
122
"""Fetches the details of a certain port"""
123
nets = self._get_tenant_nets(tenant)
124
self._verify_net_and_port(network, port, nets)
125
p = nets[network]['ports'][port]
126
return {"port": {"state": p["state"], "id": port}}
128
def create_port(self, network, body=None, tenant=None):
129
"""Creates a new port on a given network"""
130
nets = self._get_tenant_nets(tenant)
131
self._verify_net(network, nets)
132
uuid = str(utils.gen_uuid())
133
nets[network]['ports'][uuid] = {'attachment': None,
134
'state': body['port']['state']}
135
return {"port": {"id": uuid}}
137
def delete_port(self, network, port, tenant=None):
138
"""Deletes the specified port from a network"""
139
nets = self._get_tenant_nets(tenant)
140
self._verify_net_and_port(network, port, nets)
141
del nets[network]['ports'][port]
143
def set_port_state(self, network, port, body=None, tenant=None):
144
"""Sets the state of the specified port"""
145
nets = self._get_tenant_nets(tenant)
146
self._verify_net_and_port(network, port, nets)
148
new_state = body['port']['state']
149
nets[network]['ports'][port]['state'] = new_state
150
return {"port": {"state": new_state}}
152
def show_port_attachment(self, network, port, tenant=None):
153
"""Fetches the attachment-id associated with the specified port"""
154
nets = self._get_tenant_nets(tenant)
155
self._verify_net_and_port(network, port, nets)
156
p = nets[network]['ports'][port]
157
if p['attachment'] is not None:
158
return {"attachment": {"id": p['attachment']}}
160
return {"attachment": {}}
162
def attach_resource(self, network, port, body=None, tenant=None):
163
nets = self._get_tenant_nets(tenant)
164
self._verify_net_and_port(network, port, nets)
165
nets[network]['ports'][port]['attachment'] = body['attachment']['id']
167
def detach_resource(self, network, port, tenant=None):
168
"""Removes the attachment-id of the specified port"""
169
nets = self._get_tenant_nets(tenant)
170
self._verify_net_and_port(network, port, nets)
171
nets[network]['ports'][port]['attachment'] = None