~rackspace-ozone/openstack-guest-agents/trunk

« back to all changes in this revision

Viewing changes to unix/commands/freebsd/network.py

  • Committer: Johannes Erdfelt
  • Date: 2011-10-21 16:50:41 UTC
  • mfrom: (88.3.17 networking-refactor)
  • Revision ID: johannes.erdfelt@rackspace.com-20111021165041-smmnytu2xezh2751
MergeĀ lp:~johannes.erdfelt/openstack-guest-agents/networking-refactor

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
FreeBSD network helper module
21
21
"""
22
22
 
 
23
# FreeBSD network configuration uses:
 
24
# - 1 shell-script-style global configuration file (/etc/rc.conf)
 
25
# - 1 IP per interface
 
26
# - routes are global
 
27
# - gateways are global
 
28
# - DNS is configured via resolv.conf 
 
29
 
23
30
import os
24
31
import re
25
32
import time
29
36
 
30
37
import commands.network
31
38
 
32
 
RESOLV_FILE = "/etc/resolv.conf"
33
39
RCCONF_FILE = "/etc/rc.conf"
34
40
 
35
 
INTERFACE_LABELS = {"public": "xn0",
36
 
                    "private": "xn1"}
37
 
 
38
 
 
39
 
def configure_network(network_config, *args, **kwargs):
40
 
 
 
41
 
 
42
def configure_network(hostname, interfaces):
41
43
    update_files = {}
42
44
 
43
 
    # Generate new interface files
44
 
    interfaces = network_config.get('interfaces', [])
45
 
 
46
 
    # Generate new hostname file
47
 
    hostname = network_config.get('hostname')
48
 
 
49
45
    # Generate new /etc/rc.conf
50
46
    data = _get_file_data(interfaces, hostname)
51
47
    update_files[RCCONF_FILE] = data
52
48
 
53
49
    # Generate new /etc/resolv.conf file
54
 
    data = _get_resolv_conf(interfaces)
55
 
    update_files[RESOLV_FILE] = data
 
50
    filepath, data = commands.network.get_resolv_conf(interfaces)
 
51
    if data:
 
52
        update_files[filepath] = data
56
53
 
57
54
    # Generate new /etc/hosts file
58
55
    filepath, data = commands.network.get_etc_hosts(interfaces, hostname)
95
92
    return (0, "")
96
93
 
97
94
 
98
 
def _get_resolv_conf(interfaces):
99
 
    resolv_data = ''
100
 
    for interface in interfaces:
101
 
        if interface['label'] != 'public':
102
 
            continue
103
 
 
104
 
        for nameserver in interface.get('dns', []):
105
 
            resolv_data += 'nameserver %s\n' % nameserver
106
 
 
107
 
    if not resolv_data:
108
 
        return ''
109
 
 
110
 
    return '# Automatically generated, do not edit\n' + resolv_data
111
 
 
112
 
 
113
95
def _create_rcconf_file(infile, interfaces, hostname):
114
96
    """
115
97
    Return new rc.conf, merging in 'infile'
116
98
    """
117
99
 
118
 
    ipv6_interfaces = ''
 
100
    ipv6_interfaces = []
119
101
    static_route_entries = []
120
 
    defaultrouter = ''
121
 
    ipv6_defaultrouter = ''
122
102
 
123
103
    outfile = StringIO()
124
104
 
139
119
    print >> outfile, 'dhcpd_enable="NO"'
140
120
    print >> outfile, 'hostname=%s' % hostname
141
121
 
142
 
    for interface in interfaces:
143
 
        try:
144
 
            label = interface['label']
145
 
        except KeyError:
146
 
            raise SystemError("No interface label found")
147
 
 
148
 
        try:
149
 
            ifname_prefix = INTERFACE_LABELS[label]
150
 
        except KeyError:
151
 
            raise SystemError("Invalid label '%s'" % label)
152
 
 
153
 
        try:
154
 
            ips = interface['ips']
155
 
        except KeyError:
156
 
            raise SystemError("No IPs found for interface")
157
 
 
158
 
        ip6s = interface.get('ip6s', [])
159
 
 
160
 
        try:
161
 
            mac = interface['mac']
162
 
        except KeyError:
163
 
            raise SystemError("No mac address found for interface")
164
 
 
165
 
        try:
166
 
            routes = interface['routes']
167
 
        except KeyError:
168
 
            routes = []
169
 
 
170
 
        if label == "public":
171
 
            gateway4 = interface.get('gateway')
172
 
            gateway6 = interface.get('gateway6')
173
 
            if not gateway4 and not gateway6:
174
 
                raise SystemError("No gateway found for public interface")
175
 
            if gateway4 and not len(defaultrouter):
176
 
                defaultrouter = gateway4
177
 
            if gateway6 and not len(ipv6_defaultrouter):
178
 
                ipv6_defaultrouter = gateway6
179
 
            if len(ip6s):
180
 
                if len(ipv6_interfaces):
181
 
                    ipv6_interfaces += ','
182
 
                ipv6_interfaces += ifname_prefix
183
 
        else:
184
 
            gateway4 = gateway6 = None
 
122
    gateway4, gateway6 = commands.network.get_gateways(interfaces)
 
123
 
 
124
    ifnames = interfaces.keys()
 
125
    ifnames.sort()
 
126
    for ifname_prefix in ifnames:
 
127
        interface = interfaces[ifname_prefix]
 
128
 
 
129
        ip4s = interface['ip4s']
 
130
        ip6s = interface['ip6s']
 
131
 
 
132
        if ip6s:
 
133
            ipv6_interfaces.append(ifname_prefix)
185
134
 
186
135
        ifname_suffix_num = 0
187
136
 
188
 
        for i in xrange(max(len(ips), len(ip6s))):
 
137
        for ip4, ip6 in map(None, ip4s, ip6s):
189
138
            if ifname_suffix_num:
190
139
                ifname = "%s_alias%d" % (ifname_prefix, ifname_suffix_num - 1)
191
140
            else:
192
141
                ifname = ifname_prefix
193
142
 
194
 
            if i < len(ips):
195
 
                ip_info = ips[i]
196
 
            else:
197
 
                ip_info = None
198
 
 
199
 
            if i < len(ip6s):
200
 
                ip6_info = ip6s[i]
201
 
            else:
202
 
                ip6_info = None
203
 
 
204
 
            if not ip_info and not ip6_info:
205
 
                continue
206
 
 
207
 
            if ip_info and ip_info.get('enabled', '0') != '0':
208
 
                try:
209
 
                    ip = ip_info['ip']
210
 
                    netmask = ip_info['netmask']
211
 
                except KeyError:
212
 
                    raise SystemError(
213
 
                            "Missing IP or netmask in interface's IP list")
214
 
 
 
143
            if ip4:
215
144
                if ifname_suffix_num:
216
145
                    # XXX -- Known bug here.  If we're adding an alias
217
146
                    # that is on the same network as another address already
218
147
                    # configured, the netmask here should be 255.255.255.255
219
148
                    print >> outfile, 'ifconfig_%s="%s netmask %s"' % \
220
 
                            (ifname, ip, netmask)
 
149
                            (ifname, ip4['address'], ip4['netmask'])
221
150
                else:
222
151
                    print >> outfile, 'ifconfig_%s="%s netmask %s up"' % \
223
 
                            (ifname, ip, netmask)
224
 
 
225
 
            if ip6_info and ip6_info.get('enabled', '0') != '0':
226
 
                ip = ip6_info.get('address', ip6_info.get('ip'))
227
 
                if not ip:
228
 
                    raise SystemError(
229
 
                            "Missing IP in interface's IPv6 list")
230
 
                netmask = ip6_info.get('netmask')
231
 
                if not netmask:
232
 
                    raise SystemError(
233
 
                            "Missing netmask in interface's IPv6 list")
234
 
 
 
152
                            (ifname, ip4['address'], ip4['netmask'])
 
153
 
 
154
            if ip6:
235
155
                print >> outfile, 'ipv6_ifconfig_%s="%s/%s"' % \
236
 
                        (ifname, ip, netmask)
237
 
 
238
 
                gateway = ip6_info.get('gateway', gateway6)
 
156
                        (ifname, ip6['address'], ip6['prefixlen'])
239
157
 
240
158
            ifname_suffix_num += 1
241
159
 
242
 
        for x in xrange(len(routes)):
243
 
            route = routes[x]
244
 
            network = route['route']
245
 
            netmask = route['netmask']
246
 
            gateway = route['gateway']
247
 
 
248
 
            if ':' in network:
 
160
        for route in interface['routes']:
 
161
            if ':' in route['network']:
249
162
                # ipv6
250
 
                fmt = '-net %s/%s %s'
 
163
                fmt = '-net %(network)s/%(netmask)s %(gateway)s'
251
164
            else:
252
 
                fmt = '-net %s -netmask %s %s'
253
 
 
254
 
            static_route_entries.append(fmt % (network, netmask, gateway))
255
 
 
256
 
    if len(static_route_entries):
 
165
                fmt = '-net %(network)s -netmask %(netmask)s %(gateway)s'
 
166
 
 
167
            static_route_entries.append(fmt % route)
 
168
 
 
169
    if static_route_entries:
257
170
        names = []
258
 
        for x in xrange(len(static_route_entries)):
259
 
            name = 'lan%d' % x
 
171
        for i, line in enumerate(static_route_entries):
 
172
            name = 'lan%d' % i
260
173
            names.append(name)
261
 
            print >> outfile, 'route_lan%d="%s"' % \
262
 
                    (x, static_route_entries[x])
 
174
            print >> outfile, 'route_%s="%s"' % (name, line)
 
175
 
263
176
        print >> outfile, 'static_routes="%s"' % ','.join(names)
264
 
    if len(ipv6_interfaces):
 
177
 
 
178
    if ipv6_interfaces:
265
179
        print >> outfile, 'ipv6_enable="YES"'
266
 
        print >> outfile, 'ipv6_network_interfaces="%s"' % ipv6_interfaces
267
 
    if len(defaultrouter):
268
 
        print >> outfile, 'defaultrouter="%s"' % defaultrouter
269
 
    if len(ipv6_defaultrouter):
270
 
        print >> outfile, 'ipv6_defaultrouter="%s"' % ipv6_defaultrouter
 
180
        print >> outfile, 'ipv6_network_interfaces="%s"' % \
 
181
            ','.join(ipv6_interfaces)
 
182
 
 
183
    if gateway4:
 
184
        print >> outfile, 'defaultrouter="%s"' % gateway4
 
185
 
 
186
    if gateway6:
 
187
        print >> outfile, 'ipv6_defaultrouter="%s"' % gateway6
271
188
 
272
189
    outfile.seek(0)
273
190
    return outfile.read()