Merge branch 'newinterface' of ssh://bakers@git.planet-lab.org/git/plcapi into newint...
[plcapi.git] / PLC / Methods / Legacy / GetInterfaces.py
1 from PLC.Faults import *
2 from PLC.Method import Method
3 from PLC.Parameter import Parameter, Mixed
4 from PLC.Filter import Filter
5 from PLC.Interfaces import Interface, Interfaces
6 from PLC.IpAddresses import IpAddress, IpAddresses
7 from PLC.Routes import Route, Routes
8 from PLC.Nodes import Node, Nodes
9 from PLC.Auth import Auth
10
11
12 legacy_interface_fields = {
13         'interface_id': Parameter(int, "Node interface identifier"),
14         'method': Parameter(str, "Addressing method (e.g., 'static' or 'dhcp')"),
15         'type': Parameter(str, "Address type (e.g., 'ipv4')"),
16         'ip': Parameter(str, "IP address", nullok = True),
17         'mac': Parameter(str, "MAC address", nullok = True),
18         'gateway': Parameter(str, "IP address of primary gateway", nullok = True),
19         'network': Parameter(str, "Subnet address", nullok = True),
20         'broadcast': Parameter(str, "Network broadcast address", nullok = True),
21         'netmask': Parameter(str, "Subnet mask", nullok = True),
22         'dns1': Parameter(str, "IP address of primary DNS server", nullok = True),
23         'dns2': Parameter(str, "IP address of secondary DNS server", nullok = True),
24         'bwlimit': Parameter(int, "Bandwidth limit", min = 0, nullok = True),
25         'hostname': Parameter(str, "(Optional) Hostname", nullok = True),
26         'node_id': Parameter(int, "Node associated with this interface"),
27         'is_primary': Parameter(bool, "Is the primary interface for this node"),
28         'interface_tag_ids' : Parameter([int], "List of interface settings"),
29         'last_updated': Parameter(int, "Date and time when the interface entry was last updated"),
30         }
31
32 def clean_interface_fields(interface):
33     remove_keys = [key for key in interface.keys() if key not in legacy_interface_fields.keys()]
34     for key in remove_keys:
35         del interface[key]
36     return interface
37
38
39 class GetInterfaces(Method):
40     """
41     Returns an array of structs containing details about network
42     interfaces. If interfaces_filter is specified and is an array of
43     interface identifiers, or a struct of interface fields and
44     values, only interfaces matching the filter will be
45     returned.
46
47     If return_fields is given, only the specified details will be returned.
48     """
49
50     roles = ['admin', 'pi', 'user', 'tech', 'node', 'anonymous']
51
52     accepts = [
53         Auth(),
54         Mixed([Mixed(Interface.fields['interface_id'])],
55               Parameter (int, "interface id"),
56               Filter(legacy_interface_fields)),
57         Parameter([str], "List of fields to return", nullok = True)
58         ]
59
60     returns = [Interface.fields] + ["type", "ip", "netmask", "network", "broadcast"]
61
62     # needed for generating the doc and prevent conflicts in the xml ids
63     status = 'legacy'
64
65     def call(self, auth, interface_filter = None, return_fields = None):
66          if (return_fields is not None):
67              interface_return_fields = return_fields[:]
68              if not ("ip_address_ids" in interface_return_fields):
69                  interface_return_fields += ["ip_address_ids"]
70              interface_return_fields = [f for f in interface_return_fields if (f in Interface.fields)]
71          else:
72              interface_return_fields = return_fields
73
74          interfaces = Interfaces(self.api, interface_filter, interface_return_fields)
75          
76
77          for interface in interfaces:
78              ip_address_ids = interface["ip_address_ids"]
79              if ip_address_ids:
80                  # we'll use the first IpAddress only
81                  addresses = IpAddresses(self.api, ip_address_ids[0])
82                  if (not return_fields) or ("type" in return_fields):
83                      interface["type"] = addresses[0]["type"]
84                  if (not return_fields) or ("ip" in return_fields):
85                      interface["ip"] = addresses[0]["ip_addr"]
86                  if (not return_fields) or ("netmask" in return_fields):
87                      interface["netmask"] = addresses[0]["netmask"]
88                  if (not return_fields) or ("network" in return_fields):
89                      interface["network"] = addresses[0].get_network()
90                  if (not return_fields) or ("broadcast" in return_fields):
91                      interface["broadcast"] = addresses[0].get_broadcast()
92
93              # add default gw
94              routes = Routes(self.api, {'node_id' : interface['node_id'], 'subnet' : '0.0.0.0/0'})
95              if routes:
96                  interface['gateway'] = routes[0]['next_hop']
97              
98              dns1 = None
99              dns2 = None
100              nodes = Node(self.api, {'node_id' : interface['node_id']})
101              if nodes and nodes.has_key('dns'):
102                  # we'll only get the first two dns records
103                  dns_records = nodes[0]['dns'].split(',')
104                  if dns_records:
105                      dns1 = dns_records[0]
106                  if len(dns_records) > 1:
107                      dns2 = dns_records[1]
108
109              interface['dns1'] = dns1
110              interface['dns2'] = dns2
111
112              interface = clean_interface_fields(interface)
113
114          return interfaces
115