def test_rollback_for_bond(eth1_up, eth2_up): current_state = libnmstate.show() desired_state = { INTERFACES: [{ 'name': 'bond99', 'type': 'bond', 'state': 'up', 'ipv4': { 'enabled': True, 'address': [{ 'ip': '192.168.122.250', 'prefix-length': 24 }], }, 'link-aggregation': { 'mode': 'balance-rr', 'slaves': ['eth1', 'eth2'], 'options': { 'miimon': '140' }, }, }] } desired_state[INTERFACES][0]['invalid_key'] = 'foo' with pytest.raises(NmstateVerificationError): libnmstate.apply(desired_state) time.sleep(5) current_state_after_apply = libnmstate.show() assert current_state[INTERFACES] == current_state_after_apply[INTERFACES]
def test_remove_wildcast_route_with_iface(eth1_up, get_routes_func): routes = get_routes_func() libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state) absent_route = { Route.STATE: Route.STATE_ABSENT, Route.NEXT_HOP_INTERFACE: 'eth1', } libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: [absent_route] }, }) expected_routes = [] cur_state = libnmstate.show() _assert_routes(expected_routes, cur_state)
def test_remove_wildcast_route_without_iface(eth1_up, get_routes_func): routes = get_routes_func() libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state) absent_routes = [] for route in routes: absent_routes.append({ Route.STATE: Route.STATE_ABSENT, Route.DESTINATION: route[Route.DESTINATION], }) libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: absent_routes }, }) expected_routes = [] cur_state = libnmstate.show() _assert_routes(expected_routes, cur_state)
def test_rollback_for_vlans(eth1_up): current_state = libnmstate.show() desired_state = create_two_vlans_state() desired_state[Interface.KEY][1]["invalid_key"] = "foo" with pytest.raises(NmstateVerificationError): libnmstate.apply(desired_state) time.sleep(5) # Give some time for NetworkManager to rollback current_state_after_apply = libnmstate.show() assert current_state == current_state_after_apply
def test_rollback_for_vlans(eth1_up): current_state = libnmstate.show() desired_state = TWO_VLANS_STATE desired_state[INTERFACES][1]['invalid_key'] = 'foo' with pytest.raises(NmstateVerificationError): libnmstate.apply(desired_state) time.sleep(5) # Give some time for NetworkManager to rollback current_state_after_apply = libnmstate.show() assert current_state == current_state_after_apply
def diff_initial_state(): old_state = libnmstate.show() yield new_state = libnmstate.show() if old_state != new_state: warnings.warn( "Network state after test run does not match network state " "before test run:\n {}\n".format( libnmstate.prettystate.format_desired_current_state_diff( old_state, new_state)))
def test_rollback_for_linux_bridge(): original_state = libnmstate.show() bridge_name = TEST_BRIDGE0 bridge_state = _create_bridge_subtree_config(()) with pytest.raises(NmstateVerificationError): with linux_bridge(bridge_name, bridge_state) as desired_state: desired_state[Interface.KEY][0]["invalid_key"] = "foo" libnmstate.apply(desired_state) time.sleep(5) # Give some time for NetworkManager to rollback current_state = libnmstate.show() assert original_state == current_state
def test_rollback_for_vxlans(eth1_up): ifname = eth1_up[Interface.KEY][0][Interface.NAME] current_state = libnmstate.show() desired_state = vxlans_up( [ VxlanState(id=VXLAN1_ID, base_if=ifname, remote="192.168.100.1"), VxlanState(id=VXLAN2_ID, base_if=ifname, remote="192.168.100.2"), ] ) desired_state[Interface.KEY][1]["invalid_key"] = "foo" with pytest.raises(NmstateVerificationError): libnmstate.apply(desired_state) time.sleep(5) # Give some time for NetworkManager to rollback current_state_after_apply = libnmstate.show() assert current_state == current_state_after_apply
def test_remove_dns_config(empty_dns_config): dns_config = { DNS.SERVER: [IPV6_DNS_NAMESERVERS[0], IPV4_DNS_NAMESERVERS[0]], DNS.SEARCH: [], } desired_state = { Interface.KEY: _get_test_iface_states(), Route.KEY: { Route.CONFIG: _gen_default_gateway_route() }, DNS.KEY: { DNS.CONFIG: dns_config }, } libnmstate.apply(desired_state) libnmstate.apply({ Interface.KEY: [], DNS.KEY: { DNS.CONFIG: empty_dns_config } }) current_state = libnmstate.show() dns_config = {DNS.SERVER: [], DNS.SEARCH: []} assert dns_config == current_state[DNS.KEY][DNS.CONFIG]
def test_preserve_dns_config_with_empty_state(setup_ipv4_ipv6_name_server): old_state = setup_ipv4_ipv6_name_server libnmstate.apply({Interface.KEY: []}) current_state = libnmstate.show() assert old_state[DNS.KEY][DNS.CONFIG] == current_state[DNS.KEY][DNS.CONFIG]
def test_change_gateway(eth1_up): libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: [ _get_ipv4_gateways()[0], _get_ipv6_gateways()[0], ] }, }) routes = [_get_ipv4_gateways()[1], _get_ipv6_gateways()[1]] libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: [ { Route.STATE: Route.STATE_ABSENT, Route.NEXT_HOP_INTERFACE: 'eth1', Route.DESTINATION: '0.0.0.0/0', }, { Route.STATE: Route.STATE_ABSENT, Route.NEXT_HOP_INTERFACE: 'eth1', Route.DESTINATION: '::/0', }, ] + routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state)
def test_static_ip_with_routes_switch_back_to_dynamic( dhcpcli_up_with_static_ip_and_route, ): desired_state = dhcpcli_up_with_static_ip_and_route desired_state.pop(RT.KEY) dhcp_cli_desired_state = desired_state[Interface.KEY][0] dhcp_cli_desired_state[Interface.STATE] = InterfaceState.UP dhcp_cli_desired_state[Interface.IPV4] = create_ipv4_state(enabled=True, dhcp=True) dhcp_cli_desired_state[Interface.IPV6] = create_ipv6_state(enabled=True, dhcp=True, autoconf=True) libnmstate.apply(desired_state) assertlib.assert_state(desired_state) assert _poll(_has_ipv4_dhcp_nameserver) assert _poll(_has_ipv4_dhcp_gateway) assert _poll(_has_ipv4_classless_route) assert _poll(_has_dhcpv4_addr) assert _poll(_has_dhcpv6_addr) assert _poll(_has_ipv6_auto_gateway) assert _poll(_has_ipv6_auto_extra_route) assert _poll(_has_ipv6_auto_nameserver) current_config_routes = [ route for route in libnmstate.show()[RT.KEY][RT.CONFIG] if route[RT.NEXT_HOP_INTERFACE] == DHCP_CLI_NIC ] assert not current_config_routes
def edit(args): state = _filter_state(libnmstate.show(), args.only) if not state[Interface.KEY]: sys.stderr.write("ERROR: No such interface\n") return os.EX_USAGE pretty_state = PrettyState(state) if args.yaml: suffix = ".yaml" txtstate = pretty_state.yaml else: suffix = ".json" txtstate = pretty_state.json new_state = _get_edited_state(txtstate, suffix, args.yaml) if not new_state: return os.EX_DATAERR print("Applying the following state: ") print_state(new_state, use_yaml=args.yaml) libnmstate.apply( new_state, verify_change=args.verify, save_to_disk=args.save_to_disk )
def test_dynamic_ip_with_static_dns(dhcpcli_up_with_dns_cleanup): iface_state = { Interface.NAME: DHCP_CLI_NIC, Interface.STATE: InterfaceState.UP, Interface.IPV4: create_ipv4_state(enabled=True, dhcp=True, auto_dns=False), Interface.IPV6: create_ipv6_state(enabled=True, dhcp=True, autoconf=True, auto_dns=False), } dns_config = { DNS.CONFIG: { DNS.SERVER: [IPV6_DNS_NAMESERVER, IPV4_DNS_NAMESERVER], DNS.SEARCH: EXAMPLE_SEARCHES, } } desired_state = {Interface.KEY: [iface_state], DNS.KEY: dns_config} libnmstate.apply(desired_state) assertlib.assert_state_match(desired_state) assert _poll(_has_ipv4_dhcp_gateway) assert _poll(_has_ipv6_auto_gateway) assert _poll(_has_dhcpv4_addr) assert _poll(_has_dhcpv6_addr) assert not _has_ipv4_dhcp_nameserver() assert not _has_ipv6_auto_nameserver() new_state = libnmstate.show() assert dns_config[DNS.CONFIG] == new_state[DNS.KEY][DNS.CONFIG] assert dns_config[DNS.CONFIG] == new_state[DNS.KEY][DNS.RUNNING]
def assert_no_config_route_to_iface(iface_name): """ Asserts no config route next hop to specified interface. """ current_state = libnmstate.show() assert not any(route for route in current_state[Route.KEY][Route.CONFIG] if route[Route.NEXT_HOP_INTERFACE] == iface_name)
def show_only(ifnames): """ Report the current state, filtering based on the given interface names. """ base_filter_state = {INTERFACES: [{'name': ifname} for ifname in ifnames]} current_state = State(libnmstate.show()) current_state.filter(base_filter_state) return current_state.state
def test_env_setup(): _logging_setup() old_state = libnmstate.show() _empty_net_state() _ethx_init() yield libnmstate.apply(old_state, verify_change=False) _diff_initial_state(old_state)
def _get_running_routes(): """ return a list of running routes """ running_routes = (libnmstate.show().get(Constants.ROUTES, {}).get(RT.RUNNING, [])) logging.debug("Current running routes: {}".format(running_routes)) return running_routes
def _get_nameservers(): """ Return a list of name server string configured in RESOLV_CONF_PATH. """ running_ns = (libnmstate.show().get(Constants.DNS, {}).get(DNS.RUNNING, {}).get(DNS.SERVER, [])) logging.debug("Current running DNS: {}".format(running_ns)) return running_ns
def test_dns_edit_nameserver_with_static_gateway(dns_config): desired_state = { Interface.KEY: _get_test_iface_states(), Route.KEY: {Route.CONFIG: _gen_default_gateway_route()}, DNS.KEY: {DNS.CONFIG: dns_config}, } libnmstate.apply(desired_state) current_state = libnmstate.show() assert dns_config == current_state[DNS.KEY][DNS.CONFIG]
def test_apply_empty_state_preserve_routes(eth1_static_gateway_dns): state = eth1_static_gateway_dns libnmstate.apply({Interface.KEY: []}) current_state = libnmstate.show() assert (current_state[Route.KEY][Route.CONFIG] == state[Route.KEY][ Route.CONFIG]) assert current_state[DNS.KEY][DNS.CONFIG] == state[DNS.KEY][DNS.CONFIG]
def _get_nameservers(): """ Return a list of name server string configured in RESOLV_CONF_PATH. """ return ( libnmstate.show() .get(Constants.DNS, {}) .get(DNS.RUNNING, {}) .get(DNS.SERVER, []) )
def test_add_static_routes(eth1_up): routes = _get_ipv4_test_routes() + _get_ipv6_test_routes() libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state)
def test_add_gateway(eth1_up): routes = [_get_ipv4_gateways()[0], _get_ipv6_test_routes()[0]] libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state)
def _empty_net_state(): """ Remove existing DNS, routes, route rules in case it interference tests. """ desired_state = libnmstate.show() desired_state[DNS.KEY] = {DNS.CONFIG: {}} desired_state[Route.KEY] = { Route.CONFIG: [{Route.STATE: Route.STATE_ABSENT}] } desired_state[RouteRule.KEY] = {RouteRule.CONFIG: []} libnmstate.apply(desired_state)
def test_rollback_for_bond(eth1_up, eth2_up): current_state = libnmstate.show() desired_state = { Interface.KEY: [{ Interface.NAME: BOND99, Interface.TYPE: InterfaceType.BOND, Interface.STATE: InterfaceState.UP, Interface.IPV4: { InterfaceIPv4.ENABLED: True, InterfaceIPv4.ADDRESS: [{ InterfaceIPv4.ADDRESS_IP: "192.168.122.250", InterfaceIPv4.ADDRESS_PREFIX_LENGTH: 24, }], }, Bond.CONFIG_SUBTREE: { Bond.MODE: BondMode.ROUND_ROBIN, Bond.SLAVES: [ eth1_up[Interface.KEY][0][Interface.NAME], eth2_up[Interface.KEY][0][Interface.NAME], ], Bond.OPTIONS_SUBTREE: { "miimon": "140" }, }, }] } desired_state[Interface.KEY][0]["invalid_key"] = "foo" with pytest.raises(NmstateVerificationError): libnmstate.apply(desired_state) time.sleep(5) current_state_after_apply = libnmstate.show() assert (current_state[Interface.KEY] == current_state_after_apply[ Interface.KEY])
def test_dns_edit_three_nameservers(dns_servers): dns_config = { DNS.SERVER: dns_servers, DNS.SEARCH: [], } desired_state = { Interface.KEY: _get_test_iface_states(), Route.KEY: {Route.CONFIG: _gen_default_gateway_route()}, DNS.KEY: {DNS.CONFIG: dns_config}, } libnmstate.apply(desired_state) current_state = libnmstate.show() assert dns_config == current_state[DNS.KEY][DNS.CONFIG]
def test_dns_edit_ipv6_nameserver_before_ipv4(): dns_config = { DNS.SERVER: [IPV6_DNS_NAMESERVERS[0], IPV4_DNS_NAMESERVERS[0]], DNS.SEARCH: [], } desired_state = { Interface.KEY: _get_test_iface_states(), Route.KEY: {Route.CONFIG: _gen_default_gateway_route()}, DNS.KEY: {DNS.CONFIG: dns_config}, } libnmstate.apply(desired_state) current_state = libnmstate.show() assert dns_config == current_state[DNS.KEY][DNS.CONFIG]
def test_add_route_without_table_id(eth1_up): routes = _get_ipv4_test_routes() + _get_ipv6_test_routes() for route in routes: del route[Route.TABLE_ID] libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: routes }, }) cur_state = libnmstate.show() _assert_routes(routes, cur_state)
def test_disable_ipv4_with_routes_in_current(eth1_up): libnmstate.apply({ Interface.KEY: [ETH1_INTERFACE_STATE], Route.KEY: { Route.CONFIG: _get_ipv4_test_routes() }, }) eth1_state = copy.deepcopy(ETH1_INTERFACE_STATE) eth1_state[Interface.IPV4] = {'enabled': False} libnmstate.apply({Interface.KEY: [eth1_state]}) cur_state = libnmstate.show() _assert_routes([], cur_state)