예제 #1
0
    def test_run_ops_no_wait(self):
        state = State(make_inventory(), make_config())
        connect_all(state)

        add_op(state, server.shell, 'echo "hello world"')

        run_ops(state, no_wait=True)
예제 #2
0
    def test_connect_with_ssh_key_password(self):
        state = State(
            make_inventory(hosts=(('somehost', {
                'ssh_key': 'testkey',
                'ssh_key_password': '******'
            }), )), Config())

        with patch('pyinfra.api.ssh.path.isfile', lambda *args, **kwargs: True), \
                patch('pyinfra.api.ssh.RSAKey.from_private_key_file') as fake_key_open:

            def fake_key_open_fail(*args, **kwargs):
                if 'password' not in kwargs:
                    raise PasswordRequiredException()

            fake_key_open.side_effect = fake_key_open_fail

            fake_key = FakeRSAKey()
            fake_key_open.return_value = fake_key

            state.deploy_dir = '/'

            connect_all(state)

            # Check the key was created properly
            fake_key_open.assert_called_with(filename='testkey',
                                             password='******')
예제 #3
0
    def test_pseudo_op(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        pseudo_state.set(state)
        pseudo_host.set(inventory['somehost'])

        # Exceute the op "bare"
        server.shell('echo "hi"')

        # Ensure this is ignored
        state.active = False
        server.shell('echo "hi 2"')

        # We should now have one op
        self.assertEqual(len(state.op_order), 1)

        # Ensure only somehost has actual op
        self.assertEqual(len(state.ops['somehost']), 1)
        self.assertEqual(len(state.ops['anotherhost']), 0)

        # Check we can't call it inside another op
        state.active = True
        state.in_op = True
        with self.assertRaises(PyinfraError):
            server.shell('echo "hi 3"')

        pseudo_state.reset()
        pseudo_host.reset()
예제 #4
0
    def test_connect_with_ssh_key(self):
        state = State(
            make_inventory(hosts=(('somehost', {
                'ssh_key': 'testkey'
            }), )), Config())

        with patch('pyinfra.api.ssh.path.isfile', lambda *args, **kwargs: True), \
                patch('pyinfra.api.ssh.RSAKey.from_private_key_file') as fake_key_open:

            fake_key = FakeRSAKey()
            fake_key_open.return_value = fake_key

            state.deploy_dir = '/'

            connect_all(state)

            # Check the key was created properly
            fake_key_open.assert_called_with(filename='testkey')

            # And check the Paramiko SSH call was correct
            self.fake_connect_mock.assert_called_with('somehost',
                                                      allow_agent=False,
                                                      look_for_keys=False,
                                                      pkey=fake_key,
                                                      port=22,
                                                      timeout=10,
                                                      username='******')
예제 #5
0
파일: test_api.py 프로젝트: xcitic/pyinfra
    def test_connect_with_missing_ssh_key(self):
        state = State(make_inventory(hosts=(
            ('somehost', {'ssh_key': 'testkey'}),
        )), Config())

        with self.assertRaises(IOError) as e:
            connect_all(state)

        # Ensure pyinfra style IOError
        self.assertTrue(e.exception.args[0].startswith('No such private key file:'))
예제 #6
0
파일: test_api.py 프로젝트: xcitic/pyinfra
    def test_fail_percent(self):
        inventory = make_inventory(('somehost', SSHException, 'anotherhost'))
        state = State(inventory, Config(FAIL_PERCENT=1))

        # Ensure we would fail at this point
        with self.assertRaises(PyinfraError) as context:
            connect_all(state)
            self.assertEqual(context.exception.message, 'Over 1% of hosts failed')

        # Ensure the other two did connect
        self.assertEqual(len(state.connected_hosts), 2)
예제 #7
0
    def test_basic_op(self):
        state = State(make_inventory(), make_config())
        connect_all(state)

        add_op(state,
               files.file,
               '/var/log/pyinfra.log',
               user='******',
               group='pyinfra',
               mode='644',
               sudo=True)

        run_ops(state)
예제 #8
0
    def test_connect_all_password(self):
        '''
        Ensure we can connect using a password.
        '''

        inventory = make_inventory(ssh_password='******')

        # Get a host
        host = inventory['somehost']
        self.assertEqual(host.data.ssh_password, 'test')

        state = State(inventory, Config())
        connect_all(state)

        self.assertEqual(len(inventory.connected_hosts), 2)
예제 #9
0
    def test_limited_op(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        # Add op to both hosts
        add_op(state, server.shell, 'echo "hi"')

        # Add op to just the first host
        add_limited_op(state, server.user, inventory['somehost'],
                       'somehost_user')

        # Ensure there are two ops
        self.assertEqual(len(state.op_order), 2)

        # Ensure somehost has two ops and anotherhost only has the one
        self.assertEqual(len(state.ops['somehost']), 2)
        self.assertEqual(len(state.ops['anotherhost']), 1)
예제 #10
0
    def test_run_once_serial_op(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        # Add a run once op
        add_op(state, server.shell, 'echo "hi"', run_once=True, serial=True)

        # Ensure it's added to op_order
        self.assertEqual(len(state.op_order), 1)

        # Ensure between the two hosts we only run the one op
        self.assertEqual(
            len(state.ops['somehost']) + len(state.ops['anotherhost']), 1)

        # Check run works
        run_ops(state)

        self.assertEqual((state.results['somehost']['success_ops'] +
                          state.results['anotherhost']['success_ops']), 1)
예제 #11
0
    def test_ignore_errors_op_fail(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        add_op(state, server.shell, 'echo "hi"', ignore_errors=True)

        with patch('pyinfra.api.operations.run_shell_command'
                   ) as fake_run_command:
            fake_channel = FakeChannel(1)
            fake_run_command.return_value = (fake_channel,
                                             FakeBuffer('', fake_channel),
                                             FakeBuffer('', fake_channel))

            # This should run OK
            run_ops(state)

            # Ensure the op was added to results
            self.assertEqual(state.results['somehost']['ops'], 1)
            self.assertEqual(state.results['somehost']['error_ops'], 1)
            # But not as a success
            self.assertEqual(state.results['somehost']['success_ops'], 0)
예제 #12
0
    def test_full_op_fail(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        add_op(state, server.shell, 'echo "hi"')

        with patch('pyinfra.api.operations.run_shell_command'
                   ) as fake_run_command:
            fake_channel = FakeChannel(1)
            fake_run_command.return_value = (fake_channel,
                                             FakeBuffer('', fake_channel),
                                             FakeBuffer('', fake_channel))

            with self.assertRaises(PyinfraError) as e:
                run_ops(state)

            self.assertEqual(e.exception.args[0], 'No hosts remaining!')

            # Ensure the op was not flagged as success
            self.assertEqual(state.results['somehost']['success_ops'], 0)
            # And was flagged asn an error
            self.assertEqual(state.results['somehost']['error_ops'], 1)
예제 #13
0
    def test_file_op(self):
        state = State(make_inventory(), make_config())
        connect_all(state)

        # Test normal
        with patch('pyinfra.modules.files.open',
                   mock_open(read_data='test!'),
                   create=True):
            add_op(state, files.put, 'files/file.txt',
                   '/home/vagrant/file.txt')

        # And with sudo
        with patch('pyinfra.modules.files.open',
                   mock_open(read_data='test!'),
                   create=True):
            add_op(state,
                   files.put,
                   'files/file.txt',
                   '/home/vagrant/file.txt',
                   sudo=True,
                   sudo_user='******')

        run_ops(state)
예제 #14
0
    def test_pipelining_active_works(self):
        state = State(make_inventory(), Config())
        connect_all(state)

        state.pipelining = True
        add_op(state, server.shell, 'echo "hi"')
예제 #15
0
    # Attach to pseudo state
    pseudo_state.set(state)

    # Setup the data to be passed to config hooks
    hook_data = FallbackAttrData(
        state.inventory.get_override_data(),
        state.inventory.get_group_data(inventory_group),
        state.inventory.get_data()
    )

    # Run the before_connect hook if provided
    run_hook(state, 'before_connect', hook_data)

    # Connect to all the servers
    print('--> Connecting to hosts...')
    connect_all(state)

    print()

    # Run the before_connect hook if provided
    run_hook(state, 'before_facts', hook_data)

    # Just getting a fact?
    if arguments['fact']:
        fact_data = get_facts(
            state, arguments['fact'], args=arguments['fact_args'],
            sudo=arguments['sudo'], sudo_user=arguments['sudo_user'],
            su_user=arguments['su_user']
        )
        print_fact(fact_data)
        _exit()
예제 #16
0
    def test_file_op(self):
        state = State(make_inventory(), Config())
        connect_all(state)

        with patch('pyinfra.modules.files.path.isfile',
                   lambda *args, **kwargs: True):
            # Test normal
            add_op(state, files.put, {'First op name'}, 'files/file.txt',
                   '/home/vagrant/file.txt')

            # And with sudo
            add_op(state,
                   files.put,
                   'files/file.txt',
                   '/home/vagrant/file.txt',
                   sudo=True,
                   sudo_user='******')

            # And with su
            add_op(state,
                   files.put,
                   'files/file.txt',
                   '/home/vagrant/file.txt',
                   sudo=True,
                   su_user='******')

        # Ensure we have all ops
        self.assertEqual(len(state.op_order), 3)

        first_op_hash = state.op_order[0]

        # Ensure first op is the right one
        self.assertEqual(state.op_meta[first_op_hash]['names'],
                         {'First op name'})

        # Ensure first op has the right (upload) command
        self.assertEqual(state.ops['somehost'][first_op_hash]['commands'],
                         [('files/file.txt', '/home/vagrant/file.txt')])

        # Ensure second op has sudo/sudo_user
        self.assertEqual(state.op_meta[state.op_order[1]]['sudo'], True)
        self.assertEqual(state.op_meta[state.op_order[1]]['sudo_user'],
                         'pyinfra')

        # Ensure third has su_user
        self.assertEqual(state.op_meta[state.op_order[2]]['su_user'],
                         'pyinfra')

        # Check run ops works
        with patch('pyinfra.api.util.open',
                   mock_open(read_data='test!'),
                   create=True):
            run_ops(state)

        # Ensure ops completed OK
        self.assertEqual(state.results['somehost']['success_ops'], 3)
        self.assertEqual(state.results['somehost']['ops'], 3)
        self.assertEqual(state.results['anotherhost']['success_ops'], 3)
        self.assertEqual(state.results['anotherhost']['ops'], 3)

        # And w/o errors
        self.assertEqual(state.results['somehost']['error_ops'], 0)
        self.assertEqual(state.results['anotherhost']['error_ops'], 0)
예제 #17
0
    def test_op(self):
        state = State(make_inventory(), Config())

        # Enable printing on this test to catch any exceptions in the formatting
        state.print_output = True
        state.print_fact_info = True
        state.print_fact_output = True
        state.print_lines = True

        connect_all(state)

        add_op(state,
               files.file,
               '/var/log/pyinfra.log',
               user='******',
               group='pyinfra',
               mode='644',
               sudo=True,
               sudo_user='******',
               su_user='******',
               ignore_errors=True,
               env={
                   'TEST': 'what',
               })

        # Ensure we have an op
        self.assertEqual(len(state.op_order), 1)

        first_op_hash = state.op_order[0]

        # Ensure the op name
        self.assertEqual(state.op_meta[first_op_hash]['names'], {'Files/File'})

        # Ensure the commands
        self.assertEqual(state.ops['somehost'][first_op_hash]['commands'], [
            'touch /var/log/pyinfra.log', 'chmod 644 /var/log/pyinfra.log',
            'chown pyinfra:pyinfra /var/log/pyinfra.log'
        ])

        # Ensure the meta
        meta = state.op_meta[first_op_hash]
        self.assertEqual(meta['sudo'], True)
        self.assertEqual(meta['sudo_user'], 'test_sudo')
        self.assertEqual(meta['su_user'], 'test_su')
        self.assertEqual(meta['ignore_errors'], True)

        # Ensure run ops works
        run_ops(state)

        # Ensure ops completed OK
        self.assertEqual(state.results['somehost']['success_ops'], 1)
        self.assertEqual(state.results['somehost']['ops'], 1)
        self.assertEqual(state.results['anotherhost']['success_ops'], 1)
        self.assertEqual(state.results['anotherhost']['ops'], 1)

        # And w/o errors
        self.assertEqual(state.results['somehost']['error_ops'], 0)
        self.assertEqual(state.results['anotherhost']['error_ops'], 0)

        # And with the different modes
        run_ops(state, serial=True)
        run_ops(state, no_wait=True)
예제 #18
0
    def test_connect_all_password(self):
        inventory = make_inventory(ssh_password='******')
        state = State(inventory, make_config())
        connect_all(state)

        self.assertEqual(len(inventory.connected_hosts), 2)
예제 #19
0
    def test_connect_all(self):
        inventory = make_inventory()
        state = State(inventory, Config())
        connect_all(state)

        self.assertEqual(len(inventory.connected_hosts), 2)
예제 #20
0
    def test_fail_percent(self):
        inventory = make_inventory(('somehost', SSHException))
        state = State(inventory, make_config())

        with self.assertRaises(PyinfraError):
            connect_all(state)