~hglkrijger/cloud-init/pep8-fixes

« back to all changes in this revision

Viewing changes to tests/unittests/test_net.py

support network rendering to sysconfig (for centos and RHEL)

This intends to add support for rendering of network data under sysconfig
distributions (centos and rhel).  The end result will be support for
network configuration via ConfigDrive or NoCloud on these OS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
from cloudinit.net import cmdline
3
3
from cloudinit.net import eni
4
4
from cloudinit.net import network_state
 
5
from cloudinit.net import sysconfig
 
6
from cloudinit.sources.helpers import openstack
5
7
from cloudinit import util
6
8
 
7
9
from .helpers import mock
74
76
                 'dns_nameservers': ['10.0.1.1']}],
75
77
}
76
78
 
 
79
# Examples (and expected outputs for various renderers).
 
80
OS_SAMPLES = [
 
81
    {
 
82
        'in_data': {
 
83
            "services": [{"type": "dns", "address": "172.19.0.12"}],
 
84
            "networks": [{
 
85
                "network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
 
86
                "type": "ipv4", "netmask": "255.255.252.0",
 
87
                "link": "tap1a81968a-79",
 
88
                "routes": [{
 
89
                    "netmask": "0.0.0.0",
 
90
                    "network": "0.0.0.0",
 
91
                    "gateway": "172.19.3.254",
 
92
                }],
 
93
                "ip_address": "172.19.1.34", "id": "network0"
 
94
            }],
 
95
            "links": [
 
96
                {
 
97
                    "ethernet_mac_address": "fa:16:3e:ed:9a:59",
 
98
                    "mtu": None, "type": "bridge", "id":
 
99
                    "tap1a81968a-79",
 
100
                    "vif_id": "1a81968a-797a-400f-8a80-567f997eb93f"
 
101
                },
 
102
            ],
 
103
        },
 
104
        'in_macs': {
 
105
            'fa:16:3e:ed:9a:59': 'eth0',
 
106
        },
 
107
        'out_sysconfig': [
 
108
            ('etc/sysconfig/network-scripts/ifcfg-eth0',
 
109
             """
 
110
# Created by cloud-init on instance boot automatically, do not edit.
 
111
#
 
112
BOOTPROTO=static
 
113
DEFROUTE=yes
 
114
DEVICE=eth0
 
115
GATEWAY=172.19.3.254
 
116
HWADDR=fa:16:3e:ed:9a:59
 
117
IPADDR=172.19.1.34
 
118
NETMASK=255.255.252.0
 
119
NM_CONTROLLED=no
 
120
ONBOOT=yes
 
121
TYPE=Ethernet
 
122
USERCTL=no
 
123
""".lstrip()),
 
124
            ('etc/sysconfig/network-scripts/route-eth0',
 
125
             """
 
126
# Created by cloud-init on instance boot automatically, do not edit.
 
127
#
 
128
ADDRESS0=0.0.0.0
 
129
GATEWAY0=172.19.3.254
 
130
NETMASK0=0.0.0.0
 
131
""".lstrip()),
 
132
            ('etc/resolv.conf',
 
133
             """
 
134
; Created by cloud-init on instance boot automatically, do not edit.
 
135
;
 
136
nameserver 172.19.0.12
 
137
""".lstrip()),
 
138
            ('etc/udev/rules.d/70-persistent-net.rules',
 
139
             "".join(['SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ',
 
140
                      'ATTR{address}=="fa:16:3e:ed:9a:59", NAME="eth0"\n']))]
 
141
    }
 
142
]
 
143
 
 
144
 
 
145
def _setup_test(tmp_dir, mock_get_devicelist, mock_sys_netdev_info,
 
146
                mock_sys_dev_path):
 
147
    mock_get_devicelist.return_value = ['eth1000']
 
148
    dev_characteristics = {
 
149
        'eth1000': {
 
150
            "bridge": False,
 
151
            "carrier": False,
 
152
            "dormant": False,
 
153
            "operstate": "down",
 
154
            "address": "07-1C-C6-75-A4-BE",
 
155
        }
 
156
    }
 
157
 
 
158
    def netdev_info(name, field):
 
159
        return dev_characteristics[name][field]
 
160
 
 
161
    mock_sys_netdev_info.side_effect = netdev_info
 
162
 
 
163
    def sys_dev_path(devname, path=""):
 
164
        return tmp_dir + devname + "/" + path
 
165
 
 
166
    for dev in dev_characteristics:
 
167
        os.makedirs(os.path.join(tmp_dir, dev))
 
168
        with open(os.path.join(tmp_dir, dev, 'operstate'), 'w') as fh:
 
169
            fh.write("down")
 
170
 
 
171
    mock_sys_dev_path.side_effect = sys_dev_path
 
172
 
 
173
 
 
174
class TestSysConfigRendering(TestCase):
 
175
 
 
176
    @mock.patch("cloudinit.net.sys_dev_path")
 
177
    @mock.patch("cloudinit.net.sys_netdev_info")
 
178
    @mock.patch("cloudinit.net.get_devicelist")
 
179
    def test_default_generation(self, mock_get_devicelist,
 
180
                                mock_sys_netdev_info,
 
181
                                mock_sys_dev_path):
 
182
        tmp_dir = tempfile.mkdtemp()
 
183
        self.addCleanup(shutil.rmtree, tmp_dir)
 
184
        _setup_test(tmp_dir, mock_get_devicelist,
 
185
                    mock_sys_netdev_info, mock_sys_dev_path)
 
186
 
 
187
        network_cfg = net.generate_fallback_config()
 
188
        ns = network_state.parse_net_config_data(network_cfg,
 
189
                                                 skip_broken=False)
 
190
 
 
191
        render_dir = os.path.join(tmp_dir, "render")
 
192
        os.makedirs(render_dir)
 
193
 
 
194
        renderer = sysconfig.Renderer()
 
195
        renderer.render_network_state(render_dir, ns)
 
196
 
 
197
        render_file = 'etc/sysconfig/network-scripts/ifcfg-eth1000'
 
198
        with open(os.path.join(render_dir, render_file)) as fh:
 
199
            content = fh.read()
 
200
            expected_content = """
 
201
# Created by cloud-init on instance boot automatically, do not edit.
 
202
#
 
203
BOOTPROTO=dhcp
 
204
DEVICE=eth1000
 
205
HWADDR=07-1C-C6-75-A4-BE
 
206
NM_CONTROLLED=no
 
207
ONBOOT=yes
 
208
TYPE=Ethernet
 
209
USERCTL=no
 
210
""".lstrip()
 
211
            self.assertEqual(expected_content, content)
 
212
 
 
213
    def test_openstack_rendering_samples(self):
 
214
        tmp_dir = tempfile.mkdtemp()
 
215
        self.addCleanup(shutil.rmtree, tmp_dir)
 
216
        render_dir = os.path.join(tmp_dir, "render")
 
217
        for os_sample in OS_SAMPLES:
 
218
            ex_input = os_sample['in_data']
 
219
            ex_mac_addrs = os_sample['in_macs']
 
220
            network_cfg = openstack.convert_net_json(
 
221
                ex_input, known_macs=ex_mac_addrs)
 
222
            ns = network_state.parse_net_config_data(network_cfg,
 
223
                                                     skip_broken=False)
 
224
            renderer = sysconfig.Renderer()
 
225
            renderer.render_network_state(render_dir, ns)
 
226
            for fn, expected_content in os_sample.get('out_sysconfig', []):
 
227
                with open(os.path.join(render_dir, fn)) as fh:
 
228
                    self.assertEqual(expected_content, fh.read())
 
229
 
77
230
 
78
231
class TestEniNetRendering(TestCase):
79
232
 
83
236
    def test_default_generation(self, mock_get_devicelist,
84
237
                                mock_sys_netdev_info,
85
238
                                mock_sys_dev_path):
86
 
        mock_get_devicelist.return_value = ['eth1000', 'lo']
87
 
 
88
 
        dev_characteristics = {
89
 
            'eth1000': {
90
 
                "bridge": False,
91
 
                "carrier": False,
92
 
                "dormant": False,
93
 
                "operstate": "down",
94
 
                "address": "07-1C-C6-75-A4-BE",
95
 
            }
96
 
        }
97
 
 
98
 
        def netdev_info(name, field):
99
 
            return dev_characteristics[name][field]
100
 
 
101
 
        mock_sys_netdev_info.side_effect = netdev_info
102
 
 
103
239
        tmp_dir = tempfile.mkdtemp()
104
240
        self.addCleanup(shutil.rmtree, tmp_dir)
105
 
 
106
 
        def sys_dev_path(devname, path=""):
107
 
            return tmp_dir + devname + "/" + path
108
 
 
109
 
        for dev in dev_characteristics:
110
 
            os.makedirs(os.path.join(tmp_dir, dev))
111
 
            with open(os.path.join(tmp_dir, dev, 'operstate'), 'w') as fh:
112
 
                fh.write("down")
113
 
 
114
 
        mock_sys_dev_path.side_effect = sys_dev_path
 
241
        _setup_test(tmp_dir, mock_get_devicelist,
 
242
                    mock_sys_netdev_info, mock_sys_dev_path)
115
243
 
116
244
        network_cfg = net.generate_fallback_config()
117
245
        ns = network_state.parse_net_config_data(network_cfg,
120
248
        render_dir = os.path.join(tmp_dir, "render")
121
249
        os.makedirs(render_dir)
122
250
 
123
 
        renderer = eni.Renderer()
124
 
        renderer.render_network_state(render_dir, ns,
125
 
                                      eni="interfaces",
126
 
                                      links_prefix=None,
127
 
                                      netrules=None)
 
251
        renderer = eni.Renderer(
 
252
            {'links_path_prefix': None,
 
253
             'eni_path': 'interfaces', 'netrules_path': None,
 
254
             })
 
255
        renderer.render_network_state(render_dir, ns)
128
256
 
129
257
        self.assertTrue(os.path.exists(os.path.join(render_dir,
130
258
                                                    'interfaces')))