def test_fork_snapshot_deactivate(network, example_snapshot): """Use fork snapshot to deactivate and restore items.""" deactivate_name = uuid.uuid4().hex restore_name = uuid.uuid4().hex node = 'as2border1' interface = Interface(hostname='as1border1', interface='GigabitEthernet1/0') link = Edge(node1='as2core1', node1interface='GigabitEthernet1/0', node2='as2border2', node2interface='GigabitEthernet2/0') bf_set_network(network) try: # Should succeed with deactivations bf_fork_snapshot(base_name=example_snapshot, name=deactivate_name, deactivate_interfaces=[interface], deactivate_links=[link], deactivate_nodes=[node]) # Should succeed with valid restorations from snapshot with deactivation bf_fork_snapshot(base_name=deactivate_name, name=restore_name, restore_interfaces=[interface], restore_links=[link], restore_nodes=[node]) finally: bf_delete_snapshot(deactivate_name) bf_delete_snapshot(restore_name)
def test_fork_snapshot_deactivate(network, example_snapshot): """Use fork snapshot to deactivate and restore items.""" deactivate_name = uuid.uuid4().hex restore_name = uuid.uuid4().hex node = "as2border1" interface = Interface(hostname="as1border1", interface="GigabitEthernet1/0") bf_set_network(network) try: # Should succeed with deactivations bf_fork_snapshot( base_name=example_snapshot, name=deactivate_name, deactivate_interfaces=[interface], deactivate_nodes=[node], ) # Should succeed with valid restorations from snapshot with deactivation bf_fork_snapshot( base_name=deactivate_name, name=restore_name, restore_interfaces=[interface], restore_nodes=[node], ) finally: bf_delete_snapshot(deactivate_name) bf_delete_snapshot(restore_name)
def test_fork_snapshot_no_network(): """Run fork snapshot command without setting a network.""" name = uuid.uuid4().hex bf_session.network = None # Should fail when network is not set with pytest.raises(ValueError): bf_fork_snapshot(base_name="base_name", name=name)
def test_fork_snapshot_no_base(network): """Run fork snapshot command with a bogus base snapshot.""" name = uuid.uuid4().hex bf_set_network(network) # Should fail with non-existent base snapshot with pytest.raises(HTTPError): bf_fork_snapshot(base_name="bogus", name=name)
def test_fork_snapshot_bad_restore(network, example_snapshot): """Run fork snapshot with invalid restore item.""" fail_name = uuid.uuid4().hex node = 'as2border1' bf_set_network(network) # Should fail when trying to restore an item that was never deactivated # in base snapshot with pytest.raises(HTTPError): bf_fork_snapshot(base_name=example_snapshot, name=fail_name, restore_nodes=[node])
def test_fork_snapshot_add_files(network, example_snapshot): """Run fork snapshot command that adds files.""" name = uuid.uuid4().hex bf_set_network(network) try: # Should succeed uploading a zip with a new file bf_fork_snapshot(base_name=example_snapshot, name=name, add_files=join(_this_dir, 'fork')) finally: bf_delete_snapshot(name)
def test_fork_snapshot(network, example_snapshot): """Run fork snapshot command with valid and invalid inputs.""" name = uuid.uuid4().hex bf_set_network(network) try: # Should succeed with existent base snapshot and valid name bf_fork_snapshot(base_name=example_snapshot, name=name) # Fail using existing snapshot name without specifying overwrite with pytest.raises(ValueError): bf_fork_snapshot(base_name=example_snapshot, name=name) finally: bf_delete_snapshot(name)
def deactivate_nodes(bf_snapshot_base, bf_snapshot_fail): nodes = bfq.nodeProperties(nodes=NODE_SCOPE).answer().frame() for node_index in range(len(nodes)): print( "[*] Deactivating node: [magenta bold]{}[/magenta bold]".format( nodes.loc[node_index].Node), end=" ", ) bf_fork_snapshot( base_name=bf_snapshot_base, name=bf_snapshot_fail, deactivate_nodes=[nodes.loc[node_index].Node], overwrite=True, ) pprint_results( get_differential_reachability(bf_snapshot_base, bf_snapshot_fail))
def deactivate_l3_interfaces(bf_snapshot_base, bf_snapshot_fail): l3_links = (bfq.edges( nodes=L3_INTERFACE_SCOPE, remoteNodes=L3_INTERFACE_SCOPE).answer(bf_snapshot_base).frame()) for link_index in range(len(l3_links)): print( "[*] Deactivating l3 link interface: [magenta bold]{}[/magenta bold]" .format(l3_links.loc[link_index].Interface), end=" ", ) bf_fork_snapshot( base_name=bf_snapshot_base, name=bf_snapshot_fail, deactivate_interfaces=[l3_links.loc[link_index].Interface], overwrite=True, ) pprint_results( get_differential_reachability(bf_snapshot_base, bf_snapshot_fail))
def deactivate_po_members(bf_snapshot_base, bf_snapshot_fail): po_members = list( bfq.interfaceProperties( nodes=PORT_CHANNEL_MEMBER_SCOPE, properties="Channel_Group").answer().frame().dropna().Interface) for po_member in po_members: print( f"[*] Deactivating port-channel member: [magenta bold]{po_member}[/magenta bold]", end=" ", ) bf_fork_snapshot( base_name=bf_snapshot_base, name=bf_snapshot_fail, deactivate_interfaces=[po_member], overwrite=True, ) pprint_results( get_differential_reachability(bf_snapshot_base, bf_snapshot_fail))
def network_failure(self, base_snapshot, reference_snapshot, deactivate_node, deactivated_int, overwrite=True): if not deactivated_int: bf_fork_snapshot(base_snapshot, reference_snapshot, deactivate_nodes=deactivate_node, overwrite=overwrite) else: bf_fork_snapshot(base_snapshot, reference_snapshot, deactivate_interfaces=[ Interface(deactivate_node[0], deactivated_int[0]) ], overwrite=overwrite)
def test_fork_snapshot_validation(): with pytest.raises(ValueError): bf_fork_snapshot(base_name="x", name="foo/bar")
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict(base_name=dict(type='str', required=False, default=None), host=dict(type='str', required=False, default='localhost'), name=dict(type='str', required=True), network=dict(type='str', required=True), path=dict(type='str', required=True)) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, name='', network='', result='', ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if not pybatfish_found: module.fail_json(msg='Python module Pybatfish is required') if module.check_mode: return result base_name = module.params['base_name'] name = module.params['name'] path = module.params['path'] try: bf_session.coordinatorHost = module.params['host'] network = bf_set_network(module.params['network']) except Exception as e: module.fail_json(msg='Failed to set network: {}'.format(e), **result) result['network'] = network try: if base_name is not None: name = bf_fork_snapshot(add_files=path, base_name=base_name, name=name, overwrite=True) result[ 'result'] = "Forked snapshot '{}' from '{}' adding files at '{}'".format( name, base_name, path) else: name = bf_init_snapshot(path, name, overwrite=True) result[ 'result'] = "Created snapshot '{}' from files at '{}'".format( name, path) except Exception as e: module.fail_json(msg='Failed to init snapshot: {}'.format(e), **result) result['name'] = name # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) result['changed'] = True module.exit_json(**result)