Ejemplo n.º 1
0
    def test_bound_network_init(self, network_response):
        bound_network = BoundNetwork(
            client=mock.MagicMock(),
            data=network_response['network']
        )

        assert bound_network.id == 1
        assert bound_network.created == isoparse("2016-01-30T23:50:11+00:00")
        assert bound_network.name == "mynet"
        assert bound_network.ip_range == "10.0.0.0/16"
        assert bound_network.protection['delete'] is False

        assert len(bound_network.servers) == 1
        assert isinstance(bound_network.servers[0], BoundServer)
        assert bound_network.servers[0].id == 42
        assert bound_network.servers[0].complete is False

        assert len(bound_network.subnets) == 2
        assert isinstance(bound_network.subnets[0], NetworkSubnet)
        assert bound_network.subnets[0].type == "cloud"
        assert bound_network.subnets[0].ip_range == "10.0.1.0/24"
        assert bound_network.subnets[0].network_zone == "eu-central"
        assert bound_network.subnets[0].gateway == "10.0.0.1"

        assert len(bound_network.routes) == 1
        assert isinstance(bound_network.routes[0], NetworkRoute)
        assert bound_network.routes[0].destination == "10.100.1.0/24"
        assert bound_network.routes[0].gateway == "10.0.1.1"
Ejemplo n.º 2
0
    def __init__(self, client, data, complete=True):

        datacenter = data.get('datacenter')
        if datacenter is not None:
            data['datacenter'] = BoundDatacenter(client._client.datacenters,
                                                 datacenter)

        volumes = data.get('volumes', [])
        if volumes:
            volumes = [
                BoundVolume(client._client.volumes, {"id": volume},
                            complete=False) for volume in volumes
            ]
            data['volumes'] = volumes

        image = data.get("image", None)
        if image is not None:
            data['image'] = BoundImage(client._client.images, image)

        iso = data.get("iso", None)
        if iso is not None:
            data['iso'] = BoundIso(client._client.isos, iso)

        server_type = data.get("server_type")
        if server_type is not None:
            data['server_type'] = BoundServerType(client._client.server_types,
                                                  server_type)

        public_net = data.get("public_net")
        if public_net:
            ipv4_address = IPv4Address(**public_net['ipv4'])
            ipv6_network = IPv6Network(**public_net['ipv6'])
            floating_ips = [
                BoundFloatingIP(client._client.floating_ips,
                                {"id": floating_ip},
                                complete=False)
                for floating_ip in public_net['floating_ips']
            ]
            data['public_net'] = PublicNetwork(ipv4=ipv4_address,
                                               ipv6=ipv6_network,
                                               floating_ips=floating_ips)

        private_nets = data.get("private_net")
        if private_nets:
            private_nets = [
                PrivateNet(network=BoundNetwork(client._client.networks,
                                                {"id": private_net['network']},
                                                complete=False),
                           ip=private_net['ip'],
                           alias_ips=private_net['alias_ips'],
                           mac_address=private_net['mac_address'])
                for private_net in private_nets
            ]
            data['private_net'] = private_nets

        super(BoundServer, self).__init__(client, data, complete)
Ejemplo n.º 3
0
    def test_create_with_networks(self, servers_client, response_create_simple_server):
        servers_client._client.request.return_value = response_create_simple_server
        networks = [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=2))]
        response = servers_client.create(
            "my-server",
            server_type=ServerType(name="cx11"),
            image=Image(id=4711),
            networks=networks,
            start_after_create=False
        )
        servers_client._client.request.assert_called_with(
            url="/servers",
            method="POST",
            json={
                'name': "my-server",
                'server_type': "cx11",
                'image': 4711,
                'networks': [1, 2],
                "start_after_create": False
            }
        )

        bound_server = response.server
        bound_action = response.action
        next_actions = response.next_actions
        root_password = response.root_password

        assert root_password == "YItygq1v3GYjjMomLaKc"

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

        assert isinstance(bound_action, BoundAction)
        assert bound_action._client == servers_client._client.actions
        assert bound_action.id == 1
        assert bound_action.command == "create_server"

        assert next_actions[0].id == 13
Ejemplo n.º 4
0
class TestServersClient(object):
    @pytest.fixture()
    def servers_client(self):
        return ServersClient(client=mock.MagicMock())

    def test_get_by_id(self, servers_client, response_simple_server):
        servers_client._client.request.return_value = response_simple_server
        bound_server = servers_client.get_by_id(1)
        servers_client._client.request.assert_called_with(url="/servers/1",
                                                          method="GET")
        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

    @pytest.mark.parametrize("params", [{
        'name': "server1",
        'label_selector': "label1",
        'page': 1,
        'per_page': 10
    }, {
        'name': ""
    }, {}])
    def test_get_list(self, servers_client, response_simple_servers, params):
        servers_client._client.request.return_value = response_simple_servers
        result = servers_client.get_list(**params)
        servers_client._client.request.assert_called_with(url="/servers",
                                                          method="GET",
                                                          params=params)

        bound_servers = result.servers
        assert result.meta is None

        assert len(bound_servers) == 2

        bound_server1 = bound_servers[0]
        bound_server2 = bound_servers[1]

        assert bound_server1._client is servers_client
        assert bound_server1.id == 1
        assert bound_server1.name == "my-server"

        assert bound_server2._client is servers_client
        assert bound_server2.id == 2
        assert bound_server2.name == "my-server2"

    @pytest.mark.parametrize("params", [{
        'name': "server1",
        'label_selector': "label1"
    }, {}])
    def test_get_all(self, servers_client, response_simple_servers, params):
        servers_client._client.request.return_value = response_simple_servers
        bound_servers = servers_client.get_all(**params)

        params.update({'page': 1, 'per_page': 50})

        servers_client._client.request.assert_called_with(url="/servers",
                                                          method="GET",
                                                          params=params)

        assert len(bound_servers) == 2

        bound_server1 = bound_servers[0]
        bound_server2 = bound_servers[1]

        assert bound_server1._client is servers_client
        assert bound_server1.id == 1
        assert bound_server1.name == "my-server"

        assert bound_server2._client is servers_client
        assert bound_server2.id == 2
        assert bound_server2.name == "my-server2"

    def test_get_by_name(self, servers_client, response_simple_servers):
        servers_client._client.request.return_value = response_simple_servers
        bound_server = servers_client.get_by_name("my-server")

        params = {'name': "my-server"}

        servers_client._client.request.assert_called_with(url="/servers",
                                                          method="GET",
                                                          params=params)

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

    def test_create_with_datacenter(self, servers_client,
                                    response_create_simple_server):
        servers_client._client.request.return_value = response_create_simple_server
        response = servers_client.create("my-server",
                                         server_type=ServerType(name="cx11"),
                                         image=Image(id=4711),
                                         datacenter=Datacenter(id=1))
        servers_client._client.request.assert_called_with(
            url="/servers",
            method="POST",
            json={
                'name': "my-server",
                'server_type': "cx11",
                'image': 4711,
                'datacenter': 1,
                "start_after_create": True
            })

        bound_server = response.server

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

    def test_create_with_location(self, servers_client,
                                  response_create_simple_server):
        servers_client._client.request.return_value = response_create_simple_server
        response = servers_client.create("my-server",
                                         server_type=ServerType(name="cx11"),
                                         image=Image(name="ubuntu-20.04"),
                                         location=Location(name="fsn1"))
        servers_client._client.request.assert_called_with(
            url="/servers",
            method="POST",
            json={
                'name': "my-server",
                'server_type': "cx11",
                'image': "ubuntu-20.04",
                'location': "fsn1",
                "start_after_create": True
            })

        bound_server = response.server
        bound_action = response.action

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

        assert isinstance(bound_action, BoundAction)
        assert bound_action._client == servers_client._client.actions
        assert bound_action.id == 1
        assert bound_action.command == "create_server"

    def test_create_with_volumes(self, servers_client,
                                 response_create_simple_server):
        servers_client._client.request.return_value = response_create_simple_server
        volumes = [Volume(id=1), BoundVolume(mock.MagicMock(), dict(id=2))]
        response = servers_client.create("my-server",
                                         server_type=ServerType(name="cx11"),
                                         image=Image(id=4711),
                                         volumes=volumes,
                                         start_after_create=False)
        servers_client._client.request.assert_called_with(
            url="/servers",
            method="POST",
            json={
                'name': "my-server",
                'server_type': "cx11",
                'image': 4711,
                'volumes': [1, 2],
                "start_after_create": False
            })

        bound_server = response.server
        bound_action = response.action
        next_actions = response.next_actions
        root_password = response.root_password

        assert root_password == "YItygq1v3GYjjMomLaKc"

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

        assert isinstance(bound_action, BoundAction)
        assert bound_action._client == servers_client._client.actions
        assert bound_action.id == 1
        assert bound_action.command == "create_server"

        assert next_actions[0].id == 13

    def test_create_with_networks(self, servers_client,
                                  response_create_simple_server):
        servers_client._client.request.return_value = response_create_simple_server
        networks = [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=2))]
        response = servers_client.create("my-server",
                                         server_type=ServerType(name="cx11"),
                                         image=Image(id=4711),
                                         networks=networks,
                                         start_after_create=False)
        servers_client._client.request.assert_called_with(
            url="/servers",
            method="POST",
            json={
                'name': "my-server",
                'server_type': "cx11",
                'image': 4711,
                'networks': [1, 2],
                "start_after_create": False
            })

        bound_server = response.server
        bound_action = response.action
        next_actions = response.next_actions
        root_password = response.root_password

        assert root_password == "YItygq1v3GYjjMomLaKc"

        assert bound_server._client is servers_client
        assert bound_server.id == 1
        assert bound_server.name == "my-server"

        assert isinstance(bound_action, BoundAction)
        assert bound_action._client == servers_client._client.actions
        assert bound_action.id == 1
        assert bound_action.command == "create_server"

        assert next_actions[0].id == 13

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_get_actions_list(self, servers_client, server,
                              response_get_actions):
        servers_client._client.request.return_value = response_get_actions
        result = servers_client.get_actions_list(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions", method="GET", params={})

        actions = result.actions
        assert result.meta is None

        assert len(actions) == 1
        assert isinstance(actions[0], BoundAction)

        assert actions[0]._client == servers_client._client.actions
        assert actions[0].id == 13
        assert actions[0].command == "start_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_update(self, servers_client, server, response_update_server):
        servers_client._client.request.return_value = response_update_server
        server = servers_client.update(server, name="new-name", labels={})
        servers_client._client.request.assert_called_with(url="/servers/1",
                                                          method="PUT",
                                                          json={
                                                              "name":
                                                              "new-name",
                                                              "labels": {}
                                                          })

        assert server.id == 14
        assert server.name == "new-name"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_delete(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.delete(server)
        servers_client._client.request.assert_called_with(url="/servers/1",
                                                          method="DELETE")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_power_off(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.power_off(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/poweroff", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_power_on(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.power_on(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/poweron", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reboot(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.reboot(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/reboot", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reset(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.reset(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/reset", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_shutdown(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.shutdown(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/shutdown", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reset_password(self, servers_client, server,
                            response_server_reset_password):
        servers_client._client.request.return_value = response_server_reset_password
        response = servers_client.reset_password(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/reset_password", method="POST")

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.root_password == "YItygq1v3GYjjMomLaKc"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_type_with_server_type_name(self, servers_client, server,
                                               generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.change_type(server,
                                            ServerType(name="cx11"),
                                            upgrade_disk=True)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/change_type",
            method="POST",
            json={
                "server_type": "cx11",
                "upgrade_disk": True
            })

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_type_with_server_type_id(self, servers_client, server,
                                             generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.change_type(server,
                                            ServerType(id=1),
                                            upgrade_disk=True)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/change_type",
            method="POST",
            json={
                "server_type": 1,
                "upgrade_disk": True
            })

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_type_with_blank_server_type(self, servers_client, server):
        with pytest.raises(ValueError) as e:
            servers_client.change_type(server, ServerType(), upgrade_disk=True)
        assert str(e.value) == "id or name must be set"
        servers_client._client.request.assert_not_called()

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_enable_rescue(self, servers_client, server,
                           response_server_enable_rescue):
        servers_client._client.request.return_value = response_server_enable_rescue
        response = servers_client.enable_rescue(server, "linux64", [2323])
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/enable_rescue",
            method="POST",
            json={
                "type": "linux64",
                "ssh_keys": [2323]
            })

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.root_password == "YItygq1v3GYjjMomLaKc"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_disable_rescue(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.disable_rescue(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/disable_rescue", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_create_image(self, servers_client, server,
                          response_server_create_image):
        servers_client._client.request.return_value = response_server_create_image
        response = servers_client.create_image(server,
                                               description="my image",
                                               type="snapshot",
                                               labels={"key": "value"})
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/create_image",
            method="POST",
            json={
                "description": "my image",
                "type": "snapshot",
                "labels": {
                    "key": "value"
                }
            })

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.image.description == "my image"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_rebuild(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.rebuild(server, Image(name="ubuntu-20.04"))
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/rebuild",
            method="POST",
            json={"image": "ubuntu-20.04"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_enable_backup(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.enable_backup(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/enable_backup", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_disable_backup(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.disable_backup(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/disable_backup", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_attach_iso(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.attach_iso(
            server, Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1"))
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/attach_iso",
            method="POST",
            json={"iso": "FreeBSD-11.0-RELEASE-amd64-dvd1"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_detach_iso(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.detach_iso(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/detach_iso", method="POST")

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_dns_ptr(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.change_dns_ptr(server, "1.2.3.4",
                                               "example.com")
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/change_dns_ptr",
            method="POST",
            json={
                "ip": "1.2.3.4",
                "dns_ptr": "example.com"
            })

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_protection(self, servers_client, server, generic_action):
        servers_client._client.request.return_value = generic_action
        action = servers_client.change_protection(server, True, True)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/change_protection",
            method="POST",
            json={
                "delete": True,
                "rebuild": True
            })

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_request_console(self, servers_client, server,
                             response_server_request_console):
        servers_client._client.request.return_value = response_server_request_console
        response = servers_client.request_console(server)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/request_console", method="POST")

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c"
        assert response.password == "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_attach_to_network(self, servers_client, server, network,
                               response_attach_to_network):
        servers_client._client.request.return_value = response_attach_to_network
        action = servers_client.attach_to_network(server, network, "10.0.1.1",
                                                  ["10.0.1.2", "10.0.1.3"])
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/attach_to_network",
            method="POST",
            json={
                "network": 4711,
                "ip": "10.0.1.1",
                "alias_ips": ["10.0.1.2", "10.0.1.3"]
            })

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "attach_to_network"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_detach_from_network(self, servers_client, server, network,
                                 response_detach_from_network):
        servers_client._client.request.return_value = response_detach_from_network
        action = servers_client.detach_from_network(server, network)
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/detach_from_network",
            method="POST",
            json={"network": 4711})

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "detach_from_network"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_alias_ips(self, servers_client, server, network,
                              response_change_alias_ips):
        servers_client._client.request.return_value = response_change_alias_ips
        action = servers_client.change_alias_ips(server, network,
                                                 ["10.0.1.2", "10.0.1.3"])
        servers_client._client.request.assert_called_with(
            url="/servers/1/actions/change_alias_ips",
            method="POST",
            json={
                "network": 4711,
                "alias_ips": ["10.0.1.2", "10.0.1.3"]
            })

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "change_alias_ips"
Ejemplo n.º 5
0
class TestBoundServer(object):
    @pytest.fixture()
    def bound_server(self, hetzner_client):
        return BoundServer(client=hetzner_client.servers, data=dict(id=14))

    def test_bound_server_init(self, response_full_server):
        bound_server = BoundServer(client=mock.MagicMock(),
                                   data=response_full_server['server'])

        assert bound_server.id == 42
        assert bound_server.name == "my-server"
        assert isinstance(bound_server.public_net, PublicNetwork)
        assert isinstance(bound_server.public_net.ipv4, IPv4Address)
        assert bound_server.public_net.ipv4.ip == "1.2.3.4"
        assert bound_server.public_net.ipv4.blocked is False
        assert bound_server.public_net.ipv4.dns_ptr == "server01.example.com"

        assert isinstance(bound_server.public_net.ipv6, IPv6Network)
        assert bound_server.public_net.ipv6.ip == "2001:db8::/64"
        assert bound_server.public_net.ipv6.blocked is False
        assert bound_server.public_net.ipv6.network == "2001:db8::"
        assert bound_server.public_net.ipv6.network_mask == "64"

        assert isinstance(bound_server.public_net.floating_ips[0],
                          BoundFloatingIP)
        assert bound_server.public_net.floating_ips[0].id == 478
        assert bound_server.public_net.floating_ips[0].complete is False

        assert isinstance(bound_server.datacenter, BoundDatacenter)
        assert bound_server.datacenter._client == bound_server._client._client.datacenters
        assert bound_server.datacenter.id == 1
        assert bound_server.datacenter.complete is True

        assert isinstance(bound_server.server_type, BoundServerType)
        assert bound_server.server_type._client == bound_server._client._client.server_types
        assert bound_server.server_type.id == 1
        assert bound_server.server_type.complete is True

        assert len(bound_server.volumes) == 2
        assert isinstance(bound_server.volumes[0], BoundVolume)
        assert bound_server.volumes[
            0]._client == bound_server._client._client.volumes
        assert bound_server.volumes[0].id == 1
        assert bound_server.volumes[0].complete is False

        assert isinstance(bound_server.volumes[1], BoundVolume)
        assert bound_server.volumes[
            1]._client == bound_server._client._client.volumes
        assert bound_server.volumes[1].id == 2
        assert bound_server.volumes[1].complete is False

        assert isinstance(bound_server.image, BoundImage)
        assert bound_server.image._client == bound_server._client._client.images
        assert bound_server.image.id == 4711
        assert bound_server.image.name == "ubuntu-20.04"
        assert bound_server.image.complete is True

        assert isinstance(bound_server.iso, BoundIso)
        assert bound_server.iso._client == bound_server._client._client.isos
        assert bound_server.iso.id == 4711
        assert bound_server.iso.name == "FreeBSD-11.0-RELEASE-amd64-dvd1"
        assert bound_server.iso.complete is True

        assert len(bound_server.private_net) == 1
        assert isinstance(bound_server.private_net[0], PrivateNet)
        assert bound_server.private_net[
            0].network._client == bound_server._client._client.networks
        assert bound_server.private_net[0].ip == "10.1.1.5"
        assert bound_server.private_net[0].mac_address == "86:00:ff:2a:7d:e1"
        assert len(bound_server.private_net[0].alias_ips) == 1
        assert bound_server.private_net[0].alias_ips[0] == "10.1.1.8"

    @pytest.mark.parametrize("params", [{
        "status": [Server.STATUS_RUNNING],
        "sort": "status",
        "page": 1,
        "per_page": 10
    }, {}])
    def test_get_actions_list(self, hetzner_client, bound_server,
                              response_get_actions, params):
        hetzner_client.request.return_value = response_get_actions
        result = bound_server.get_actions_list(**params)
        hetzner_client.request.assert_called_with(url="/servers/14/actions",
                                                  method="GET",
                                                  params=params)

        actions = result.actions
        assert result.meta is None

        assert len(actions) == 1
        assert isinstance(actions[0], BoundAction)
        assert actions[0].id == 13
        assert actions[0].command == "start_server"

    @pytest.mark.parametrize("params", [{
        "status": [Server.STATUS_RUNNING],
        "sort": "status"
    }, {}])
    def test_get_actions(self, hetzner_client, bound_server,
                         response_get_actions, params):
        hetzner_client.request.return_value = response_get_actions
        actions = bound_server.get_actions(**params)

        params.update({'page': 1, 'per_page': 50})

        hetzner_client.request.assert_called_with(url="/servers/14/actions",
                                                  method="GET",
                                                  params=params)

        assert len(actions) == 1
        assert isinstance(actions[0], BoundAction)
        assert actions[0].id == 13
        assert actions[0].command == "start_server"

    def test_update(self, hetzner_client, bound_server,
                    response_update_server):
        hetzner_client.request.return_value = response_update_server
        server = bound_server.update(name="new-name", labels={})
        hetzner_client.request.assert_called_with(url="/servers/14",
                                                  method="PUT",
                                                  json={
                                                      "name": "new-name",
                                                      "labels": {}
                                                  })

        assert server.id == 14
        assert server.name == "new-name"

    def test_delete(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.delete()
        hetzner_client.request.assert_called_with(url="/servers/14",
                                                  method="DELETE")

        assert action.id == 1
        assert action.progress == 0

    def test_power_off(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.power_off()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/poweroff", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_power_on(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.power_on()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/poweron", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_reboot(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.reboot()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/reboot", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_reset(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.reset()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/reset", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_shutdown(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.shutdown()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/shutdown", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_reset_password(self, hetzner_client, bound_server,
                            response_server_reset_password):
        hetzner_client.request.return_value = response_server_reset_password
        response = bound_server.reset_password()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/reset_password", method="POST")

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.root_password == "YItygq1v3GYjjMomLaKc"

    def test_change_type(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.change_type(ServerType(name="cx11"),
                                          upgrade_disk=True)
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/change_type",
            method="POST",
            json={
                "server_type": "cx11",
                "upgrade_disk": True
            })

        assert action.id == 1
        assert action.progress == 0

    def test_enable_rescue(self, hetzner_client, bound_server,
                           response_server_enable_rescue):
        hetzner_client.request.return_value = response_server_enable_rescue
        response = bound_server.enable_rescue(type="linux64")
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/enable_rescue",
            method="POST",
            json={"type": "linux64"})

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.root_password == "YItygq1v3GYjjMomLaKc"

    def test_disable_rescue(self, hetzner_client, bound_server,
                            generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.disable_rescue()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/disable_rescue", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_create_image(self, hetzner_client, bound_server,
                          response_server_create_image):
        hetzner_client.request.return_value = response_server_create_image
        response = bound_server.create_image(description="my image",
                                             type="snapshot")
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/create_image",
            method="POST",
            json={
                "description": "my image",
                "type": "snapshot"
            })

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.image.description == "my image"

    def test_rebuild(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.rebuild(Image(name="ubuntu-20.04"))
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/rebuild",
            method="POST",
            json={"image": "ubuntu-20.04"})

        assert action.id == 1
        assert action.progress == 0

    def test_enable_backup(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.enable_backup()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/enable_backup", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_disable_backup(self, hetzner_client, bound_server,
                            generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.disable_backup()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/disable_backup", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_attach_iso(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.attach_iso(
            Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1"))
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/attach_iso",
            method="POST",
            json={"iso": "FreeBSD-11.0-RELEASE-amd64-dvd1"})

        assert action.id == 1
        assert action.progress == 0

    def test_detach_iso(self, hetzner_client, bound_server, generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.detach_iso()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/detach_iso", method="POST")

        assert action.id == 1
        assert action.progress == 0

    def test_change_dns_ptr(self, hetzner_client, bound_server,
                            generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.change_dns_ptr("1.2.3.4", "example.com")
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/change_dns_ptr",
            method="POST",
            json={
                "ip": "1.2.3.4",
                "dns_ptr": "example.com"
            })

        assert action.id == 1
        assert action.progress == 0

    def test_change_protection(self, hetzner_client, bound_server,
                               generic_action):
        hetzner_client.request.return_value = generic_action
        action = bound_server.change_protection(True, True)
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/change_protection",
            method="POST",
            json={
                "delete": True,
                "rebuild": True
            })

        assert action.id == 1
        assert action.progress == 0

    def test_request_console(self, hetzner_client, bound_server,
                             response_server_request_console):
        hetzner_client.request.return_value = response_server_request_console
        response = bound_server.request_console()
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/request_console", method="POST")

        assert response.action.id == 1
        assert response.action.progress == 0
        assert response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c"
        assert response.password == "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_attach_to_network(self, hetzner_client, bound_server, network,
                               response_attach_to_network):
        hetzner_client.request.return_value = response_attach_to_network
        action = bound_server.attach_to_network(network, "10.0.1.1",
                                                ["10.0.1.2", "10.0.1.3"])
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/attach_to_network",
            method="POST",
            json={
                "network": 4711,
                "ip": "10.0.1.1",
                "alias_ips": ["10.0.1.2", "10.0.1.3"]
            })

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "attach_to_network"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_detach_from_network(self, hetzner_client, bound_server, network,
                                 response_detach_from_network):
        hetzner_client.request.return_value = response_detach_from_network
        action = bound_server.detach_from_network(network)
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/detach_from_network",
            method="POST",
            json={"network": 4711})

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "detach_from_network"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_alias_ips(self, hetzner_client, bound_server, network,
                              response_change_alias_ips):
        hetzner_client.request.return_value = response_change_alias_ips
        action = bound_server.change_alias_ips(network,
                                               ["10.0.1.2", "10.0.1.3"])
        hetzner_client.request.assert_called_with(
            url="/servers/14/actions/change_alias_ips",
            method="POST",
            json={
                "network": 4711,
                "alias_ips": ["10.0.1.2", "10.0.1.3"]
            })

        assert action.id == 1
        assert action.progress == 0
        assert action.command == "change_alias_ips"
Ejemplo n.º 6
0
class TestNetworksClient(object):

    @pytest.fixture()
    def network_subnet(self):
        return NetworkSubnet(type="server", ip_range="10.0.1.0/24", network_zone="eu-central")

    @pytest.fixture()
    def network_route(self):
        return NetworkRoute(destination="10.100.1.0/24", gateway="10.0.1.1")

    def test_get_by_id(self, hetzner_client):
        network = hetzner_client.networks.get_by_id(4711)
        assert network.id == 4711
        assert network.name == "mynet"
        assert network.ip_range == "10.0.0.0/16"
        assert len(network.subnets) == 1
        assert len(network.routes) == 1
        assert len(network.servers) == 1
        assert network.protection['delete'] is False

    def test_get_by_name(self, hetzner_client):
        network = hetzner_client.networks.get_by_name("mynet")
        assert network.id == 4711
        assert network.name == "mynet"
        assert network.ip_range == "10.0.0.0/16"
        assert len(network.subnets) == 1
        assert len(network.routes) == 1
        assert len(network.servers) == 1
        assert network.protection['delete'] is False

    def test_get_list(self, hetzner_client):
        result = hetzner_client.networks.get_list()
        networks = result.networks
        assert networks[0].id == 4711
        assert networks[0].name == "mynet"
        assert networks[0].ip_range == "10.0.0.0/16"
        assert len(networks[0].subnets) == 1
        assert len(networks[0].routes) == 1
        assert len(networks[0].servers) == 1
        assert networks[0].protection['delete'] is False

    def test_get_all(self, hetzner_client):
        networks = hetzner_client.networks.get_all()
        assert networks[0].id == 4711
        assert networks[0].name == "mynet"
        assert networks[0].ip_range == "10.0.0.0/16"
        assert len(networks[0].subnets) == 1
        assert len(networks[0].routes) == 1
        assert len(networks[0].servers) == 1
        assert networks[0].protection['delete'] is False

    def test_create(self, hetzner_client, network_subnet, network_route):
        network = hetzner_client.networks.create(name="mynet", ip_range="10.0.0.0/16", subnets=[network_subnet],
                                                 routes=[network_route])
        assert network.id == 4711
        assert network.name == "mynet"
        assert network.ip_range == "10.0.0.0/16"
        assert len(network.subnets) == 1
        assert len(network.routes) == 1
        assert len(network.servers) == 1
        assert network.protection['delete'] is False

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_get_actions_list(self, hetzner_client, network):
        result = hetzner_client.networks.get_actions_list(network)
        actions = result.actions

        assert len(actions) == 1
        assert actions[0].id == 13
        assert actions[0].command == "add_subnet"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_update(self, hetzner_client, network):
        network = hetzner_client.networks.update(network, name="new-name", labels={})

        assert network.id == 4711
        assert network.name == "new-name"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_delete(self, hetzner_client, network):
        result = hetzner_client.networks.delete(network)

        assert result is True

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_protection(self, hetzner_client, network):
        action = hetzner_client.networks.change_protection(network, delete=True)

        assert action.id == 13
        assert action.command == "change_protection"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_add_subnet(self, hetzner_client, network, network_subnet):
        action = hetzner_client.networks.add_subnet(network, network_subnet)

        assert action.id == 13
        assert action.command == "add_subnet"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_delete_subnet(self, hetzner_client, network, network_subnet):
        action = hetzner_client.networks.delete_subnet(network, network_subnet)

        assert action.id == 13
        assert action.command == "delete_subnet"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_add_route(self, hetzner_client, network, network_route):
        action = hetzner_client.networks.add_route(network, network_route)

        assert action.id == 13
        assert action.command == "add_route"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_delete_route(self, hetzner_client, network, network_route):
        action = hetzner_client.networks.delete_route(network, network_route)

        assert action.id == 13
        assert action.command == "delete_route"

    @pytest.mark.parametrize("network", [Network(id=4711), BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_ip_range(self, hetzner_client, network):
        action = hetzner_client.networks.change_ip_range(network, "10.0.0.0/12")

        assert action.id == 13
        assert action.command == "change_ip_range"
Ejemplo n.º 7
0
 def bound_network(self, hetzner_client):
     return BoundNetwork(client=hetzner_client.networks, data=dict(id=4711))
Ejemplo n.º 8
0
class TestServersClient(object):
    def test_get_by_id(self, hetzner_client):
        server = hetzner_client.servers.get_by_id(42)
        assert server.id == 42
        assert server.volumes == []
        assert server.server_type.id == 1
        assert server.datacenter.id == 1
        assert server.image.id == 4711

    def test_get_by_name(self, hetzner_client):
        server = hetzner_client.servers.get_by_name("my-server")
        assert server.id == 42
        assert server.name == "my-server"
        assert server.volumes == []
        assert server.server_type.id == 1
        assert server.datacenter.id == 1
        assert server.image.id == 4711

    def test_get_list(self, hetzner_client):
        result = hetzner_client.servers.get_list()
        servers = result.servers
        assert servers[0].id == 42
        assert servers[0].volumes == []
        assert servers[0].server_type.id == 1
        assert servers[0].datacenter.id == 1
        assert servers[0].image.id == 4711

    def test_create(self, hetzner_client):
        response = hetzner_client.servers.create(
            "my-server",
            server_type=ServerType(name="cx11"),
            image=Image(name="ubuntu-16.04"),
            ssh_keys=[SSHKey(name="my-ssh-key")],
            volumes=[Volume(id=1)],
            user_data=
            "#cloud-config\\nruncmd:\\n- [touch, /root/cloud-init-worked]\\n",
            location=Location(name="nbg1"),
            automount=False)
        server = response.server
        action = response.action
        next_actions = response.next_actions
        root_password = response.root_password

        assert server.id == 42
        assert server.volumes == []
        assert server.server_type.id == 1
        assert server.datacenter.id == 1
        assert server.image.id == 4711

        assert action.id == 1
        assert action.command == "create_server"

        assert len(next_actions) == 1
        assert next_actions[0].id == 13
        assert next_actions[0].command == "start_server"

        assert root_password == "YItygq1v3GYjjMomLaKc"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_get_actions_list(self, hetzner_client, server):
        result = hetzner_client.servers.get_actions_list(server)
        actions = result.actions

        assert len(actions) == 1
        assert actions[0].id == 13
        assert actions[0].command == "start_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_update(self, hetzner_client, server):
        server = hetzner_client.servers.update(server,
                                               name="new-name",
                                               labels={})

        assert server.id == 42
        assert server.name == "new-name"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_delete(self, hetzner_client, server):
        action = hetzner_client.servers.delete(server)

        assert action.id == 13
        assert action.command == "delete_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_power_off(self, hetzner_client, server):
        action = hetzner_client.servers.power_off(server)

        assert action.id == 13
        assert action.command == "stop_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_power_on(self, hetzner_client, server):
        action = hetzner_client.servers.power_on(server)

        assert action.id == 13
        assert action.command == "start_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reboot(self, hetzner_client, server):
        action = hetzner_client.servers.reboot(server)

        assert action.id == 13
        assert action.command == "reboot_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reset(self, hetzner_client, server):
        action = hetzner_client.servers.reset(server)

        assert action.id == 13
        assert action.command == "reset_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_shutdown(self, hetzner_client, server):
        action = hetzner_client.servers.shutdown(server)

        assert action.id == 13
        assert action.command == "shutdown_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_reset_password(self, hetzner_client, server):
        response = hetzner_client.servers.reset_password(server)

        assert response.action.id == 13
        assert response.action.command == "reset_password"
        assert response.root_password == "zCWbFhnu950dUTko5f40"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_type(self, hetzner_client, server):
        action = hetzner_client.servers.change_type(server,
                                                    ServerType(name="cx11"),
                                                    upgrade_disk=True)

        assert action.id == 13
        assert action.command == "change_server_type"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_enable_rescue(self, hetzner_client, server):
        response = hetzner_client.servers.enable_rescue(server,
                                                        type="linux64",
                                                        ssh_keys=[2323])

        assert response.action.id == 13
        assert response.action.command == "enable_rescue"
        assert response.root_password == "zCWbFhnu950dUTko5f40"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_disable_rescue(self, hetzner_client, server):
        action = hetzner_client.servers.disable_rescue(server)

        assert action.id == 13
        assert action.command == "disable_rescue"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_create_image(self, hetzner_client, server):
        response = hetzner_client.servers.create_image(server,
                                                       description="my image",
                                                       type="snapshot")

        assert response.action.id == 13
        assert response.action.command == "create_image"
        assert response.image.description == "my image"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_rebuild(self, hetzner_client, server):
        action = hetzner_client.servers.rebuild(server,
                                                Image(name="ubuntu-16.04"))

        assert action.id == 13
        assert action.command == "rebuild_server"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_enable_backup(self, hetzner_client, server):
        action = hetzner_client.servers.enable_backup(server)

        assert action.id == 13
        assert action.command == "enable_backup"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_disable_backup(self, hetzner_client, server):
        action = hetzner_client.servers.disable_backup(server)

        assert action.id == 13
        assert action.command == "disable_backup"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_attach_iso(self, hetzner_client, server):
        action = hetzner_client.servers.attach_iso(
            server, Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1"))

        assert action.id == 13
        assert action.command == "attach_iso"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_detach_iso(self, hetzner_client, server):
        action = hetzner_client.servers.detach_iso(server)

        assert action.id == 13
        assert action.command == "detach_iso"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_dns_ptr(self, hetzner_client, server):
        action = hetzner_client.servers.change_dns_ptr(server, "1.2.3.4",
                                                       "example.com")

        assert action.id == 13
        assert action.command == "change_dns_ptr"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_change_protection(self, hetzner_client, server):
        action = hetzner_client.servers.change_protection(server,
                                                          delete=True,
                                                          rebuild=True)

        assert action.id == 13
        assert action.command == "change_protection"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    def test_request_console(self, hetzner_client, server):
        response = hetzner_client.servers.request_console(server)

        assert response.action.id == 13
        assert response.action.command == "request_console"
        assert response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c"
        assert response.password == "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_attach_to_network(self, hetzner_client, server, network):
        action = hetzner_client.servers.attach_to_network(
            server, network, ip="10.0.1.1", alias_ips=["10.0.1.2"])

        assert action.id == 13
        assert action.command == "attach_to_network"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_detach_from_network(self, hetzner_client, server, network):
        action = hetzner_client.servers.detach_from_network(server, network)

        assert action.id == 13
        assert action.command == "detach_from_network"

    @pytest.mark.parametrize(
        "server",
        [Server(id=1), BoundServer(mock.MagicMock(), dict(id=1))])
    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_alias_ips(self, hetzner_client, server, network):
        action = hetzner_client.servers.change_alias_ips(
            server, network, alias_ips=["10.0.1.2"])

        assert action.id == 13
        assert action.command == "change_alias_ips"
Ejemplo n.º 9
0
class TestBoundServer(object):
    @pytest.fixture()
    def bound_server(self, hetzner_client):
        return BoundServer(client=hetzner_client.servers, data=dict(id=42))

    def test_get_actions_list(self, bound_server):
        result = bound_server.get_actions_list()
        actions = result.actions

        assert len(actions) == 1
        assert actions[0].id == 13
        assert actions[0].command == "start_server"

    def test_update(self, bound_server):
        server = bound_server.update(name="new-name", labels={})
        assert server.id == 42
        assert server.name == "new-name"

    def test_delete(self, bound_server):
        action = bound_server.delete()
        assert action.id == 13
        assert action.command == "delete_server"

    def test_power_off(self, bound_server):
        action = bound_server.power_off()
        assert action.id == 13
        assert action.command == "stop_server"

    def test_power_on(self, bound_server):
        action = bound_server.power_on()

        assert action.id == 13
        assert action.command == "start_server"

    def test_reboot(self, bound_server):
        action = bound_server.reboot()

        assert action.id == 13
        assert action.command == "reboot_server"

    def test_reset(self, bound_server):
        action = bound_server.reset()

        assert action.id == 13
        assert action.command == "reset_server"

    def test_reset_password(self, bound_server):
        response = bound_server.reset_password()

        assert response.action.id == 13
        assert response.action.command == "reset_password"
        assert response.root_password == "zCWbFhnu950dUTko5f40"

    def test_change_type(self, bound_server):
        action = bound_server.change_type(ServerType(name="cx11"),
                                          upgrade_disk=True)
        assert action.id == 13
        assert action.command == "change_server_type"

    def test_enable_rescue(self, bound_server):
        response = bound_server.enable_rescue(type="linux64", ssh_keys=[2323])

        assert response.action.id == 13
        assert response.action.command == "enable_rescue"
        assert response.root_password == "zCWbFhnu950dUTko5f40"

    def test_disable_rescue(self, bound_server):
        action = bound_server.disable_rescue()

        assert action.id == 13
        assert action.command == "disable_rescue"

    def test_create_image(self, bound_server):
        response = bound_server.create_image(description="my image",
                                             type="snapshot")

        assert response.action.id == 13
        assert response.action.command == "create_image"
        assert response.image.description == "my image"

    def test_rebuild(self, bound_server):
        action = bound_server.rebuild(Image(name="ubuntu-16.04"))

        assert action.id == 13
        assert action.command == "rebuild_server"

    def test_enable_backup(self, bound_server):
        action = bound_server.enable_backup()

        assert action.id == 13
        assert action.command == "enable_backup"

    def test_disable_backup(self, bound_server):
        action = bound_server.disable_backup()

        assert action.id == 13
        assert action.command == "disable_backup"

    def test_attach_iso(self, bound_server):
        action = bound_server.attach_iso(
            Iso(name="FreeBSD-11.0-RELEASE-amd64-dvd1"))

        assert action.id == 13
        assert action.command == "attach_iso"

    def test_detach_iso(self, bound_server):
        action = bound_server.detach_iso()

        assert action.id == 13
        assert action.command == "detach_iso"

    def test_change_dns_ptr(self, bound_server):
        action = bound_server.change_dns_ptr(ip="1.2.3.4",
                                             dns_ptr="example.com")

        assert action.id == 13
        assert action.command == "change_dns_ptr"

    def test_change_protection(self, bound_server):
        action = bound_server.change_protection(True, True)

        assert action.id == 13
        assert action.command == "change_protection"

    def test_request_console(self, bound_server):
        response = bound_server.request_console()

        assert response.action.id == 13
        assert response.action.command == "request_console"
        assert response.wss_url == "wss://console.hetzner.cloud/?server_id=1&token=3db32d15-af2f-459c-8bf8-dee1fd05f49c"
        assert response.password == "9MQaTg2VAGI0FIpc10k3UpRXcHj2wQ6x"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_attach_to_network(self, bound_server, network):
        action = bound_server.attach_to_network(network,
                                                ip="10.0.1.1",
                                                alias_ips=["10.0.1.2"])

        assert action.id == 13
        assert action.command == "attach_to_network"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_detach_from_network(self, bound_server, network):
        action = bound_server.detach_from_network(network)

        assert action.id == 13
        assert action.command == "detach_from_network"

    @pytest.mark.parametrize(
        "network",
        [Network(id=4711),
         BoundNetwork(mock.MagicMock(), dict(id=4711))])
    def test_change_alias_ips(self, bound_server, network):
        action = bound_server.change_alias_ips(network, alias_ips=["10.0.1.2"])

        assert action.id == 13
        assert action.command == "change_alias_ips"
Ejemplo n.º 10
0
    def __init__(self, client, data, complete=True):
        algorithm = data.get("algorithm")
        if algorithm:
            data['algorithm'] = LoadBalancerAlgorithm(type=algorithm['type'])

        public_net = data.get("public_net")
        if public_net:
            ipv4_address = IPv4Address(**public_net['ipv4'])
            ipv6_network = IPv6Network(**public_net['ipv6'])
            data['public_net'] = PublicNetwork(ipv4=ipv4_address,
                                               ipv6=ipv6_network,
                                               enabled=public_net['enabled'])

        private_nets = data.get("private_net")
        if private_nets:
            private_nets = [
                PrivateNet(network=BoundNetwork(client._client.networks,
                                                {"id": private_net['network']},
                                                complete=False),
                           ip=private_net['ip'])
                for private_net in private_nets
            ]
            data['private_net'] = private_nets

        targets = data.get("targets")
        if targets:
            tmp_targets = []
            for target in targets:
                tmp_target = LoadBalancerTarget(type=target["type"])
                if target["type"] == "server":
                    tmp_target.server = BoundServer(client._client.servers,
                                                    data=target['server'],
                                                    complete=False)
                    tmp_target.use_private_ip = target["use_private_ip"]
                elif target["type"] == "label_selector":
                    tmp_target.label_selector = LoadBalancerTargetLabelSelector(
                        selector=target['label_selector']['selector'])
                    tmp_target.use_private_ip = target["use_private_ip"]
                elif target["type"] == "ip":
                    tmp_target.ip = LoadBalancerTargetIP(ip=target['ip']['ip'])
                tmp_targets.append(tmp_target)
            data['targets'] = tmp_targets

        services = data.get("services")
        if services:
            tmp_services = []
            for service in services:
                tmp_service = LoadBalancerService(
                    protocol=service["protocol"],
                    listen_port=service["listen_port"],
                    destination_port=service["destination_port"],
                    proxyprotocol=service["proxyprotocol"])
                if service["protocol"] != "tcp":
                    tmp_service.http = LoadBalancerServiceHttp(
                        sticky_sessions=service['http']['sticky_sessions'],
                        redirect_http=service['http']['redirect_http'],
                        cookie_name=service['http']['cookie_name'],
                        cookie_lifetime=service['http']['cookie_lifetime'])
                    tmp_service.http.certificates = [
                        BoundCertificate(client._client.certificates,
                                         {"id": certificate},
                                         complete=False)
                        for certificate in service['http']['certificates']
                    ]

                tmp_service.health_check = LoadBalancerHealthCheck(
                    protocol=service['health_check']['protocol'],
                    port=service['health_check']['port'],
                    interval=service['health_check']['interval'],
                    retries=service['health_check']['retries'],
                    timeout=service['health_check']['timeout'])
                if tmp_service.health_check.protocol != "tcp":
                    tmp_service.health_check.http = LoadBalancerHealtCheckHttp(
                        domain=service['health_check']['http']['domain'],
                        path=service['health_check']['http']['path'],
                        response=service['health_check']['http']['response'],
                        tls=service['health_check']['http']['tls'],
                        status_codes=service['health_check']['http']
                        ['status_codes'])
                tmp_services.append(tmp_service)
            data['services'] = tmp_services

        load_balancer_type = data.get("load_balancer_type")
        if load_balancer_type is not None:
            data['load_balancer_type'] = BoundLoadBalancerType(
                client._client.load_balancer_types, load_balancer_type)

        location = data.get("location")
        if location is not None:
            data['location'] = BoundLocation(client._client.locations,
                                             location)

        super(BoundLoadBalancer, self).__init__(client, data, complete)
Ejemplo n.º 11
0
class TestNetworksClient(object):

    @pytest.fixture()
    def networks_client(self):
        return NetworksClient(client=mock.MagicMock())

    @pytest.fixture()
    def network_subnet(self):
        return NetworkSubnet(type="cloud", ip_range="10.0.1.0/24", network_zone="eu-central")

    @pytest.fixture()
    def network_route(self):
        return NetworkRoute(destination="10.100.1.0/24", gateway="10.0.1.1")

    def test_get_by_id(self, networks_client, network_response):
        networks_client._client.request.return_value = network_response
        bound_network = networks_client.get_by_id(1)
        networks_client._client.request.assert_called_with(url="/networks/1", method="GET")
        assert bound_network._client is networks_client
        assert bound_network.id == 1
        assert bound_network.name == "mynet"

    @pytest.mark.parametrize(
        "params",
        [
            {'label_selector': "label1", 'page': 1, 'per_page': 10},
            {}
        ]
    )
    def test_get_list(self, networks_client, two_networks_response, params):
        networks_client._client.request.return_value = two_networks_response
        result = networks_client.get_list(**params)
        networks_client._client.request.assert_called_with(url="/networks", method="GET", params=params)

        bound_networks = result.networks
        assert result.meta is None

        assert len(bound_networks) == 2

        bound_network1 = bound_networks[0]
        bound_network2 = bound_networks[1]

        assert bound_network1._client is networks_client
        assert bound_network1.id == 1
        assert bound_network1.name == "mynet"

        assert bound_network2._client is networks_client
        assert bound_network2.id == 2
        assert bound_network2.name == "myanothernet"

    @pytest.mark.parametrize("params", [{'label_selector': "label1"}])
    def test_get_all(self, networks_client, two_networks_response, params):
        networks_client._client.request.return_value = two_networks_response
        bound_networks = networks_client.get_all(**params)

        params.update({'page': 1, 'per_page': 50})

        networks_client._client.request.assert_called_with(url="/networks", method="GET", params=params)

        assert len(bound_networks) == 2

        bound_network1 = bound_networks[0]
        bound_network2 = bound_networks[1]

        assert bound_network1._client is networks_client
        assert bound_network1.id == 1
        assert bound_network1.name == "mynet"

        assert bound_network2._client is networks_client
        assert bound_network2.id == 2
        assert bound_network2.name == "myanothernet"

    def test_get_by_name(self, networks_client, one_network_response):
        networks_client._client.request.return_value = one_network_response
        bound_network = networks_client.get_by_name("mynet")

        params = {'name': "mynet"}

        networks_client._client.request.assert_called_with(url="/networks", method="GET", params=params)

        assert bound_network._client is networks_client
        assert bound_network.id == 1
        assert bound_network.name == "mynet"

    def test_create(self, networks_client, network_create_response):
        networks_client._client.request.return_value = network_create_response
        networks_client.create(
            name="mynet",
            ip_range="10.0.0.0/8"
        )
        networks_client._client.request.assert_called_with(
            url="/networks",
            method="POST",
            json={
                'name': "mynet",
                'ip_range': "10.0.0.0/8",
            }
        )

    def test_create_with_subnet(self, networks_client, network_subnet, network_create_response):
        networks_client._client.request.return_value = network_create_response
        networks_client.create(
            name="mynet",
            ip_range="10.0.0.0/8",
            subnets=[network_subnet]
        )
        networks_client._client.request.assert_called_with(
            url="/networks",
            method="POST",
            json={
                'name': "mynet",
                'ip_range': "10.0.0.0/8",
                'subnets': [
                    {
                        'type': "cloud",
                        'ip_range': "10.0.1.0/24",
                        'network_zone': "eu-central"
                    }
                ]
            }
        )

    def test_create_with_route(self, networks_client, network_route, network_create_response):
        networks_client._client.request.return_value = network_create_response
        networks_client.create(
            name="mynet",
            ip_range="10.0.0.0/8",
            routes=[network_route]
        )
        networks_client._client.request.assert_called_with(
            url="/networks",
            method="POST",
            json={
                'name': "mynet",
                'ip_range': "10.0.0.0/8",
                'routes': [
                    {
                        'destination': "10.100.1.0/24",
                        'gateway': "10.0.1.1",
                    }
                ]
            }
        )

    def test_create_with_route_and_subnet(self, networks_client, network_subnet, network_route,
                                          network_create_response):
        networks_client._client.request.return_value = network_create_response
        networks_client.create(
            name="mynet",
            ip_range="10.0.0.0/8",
            subnets=[network_subnet],
            routes=[network_route]
        )
        networks_client._client.request.assert_called_with(
            url="/networks",
            method="POST",
            json={
                'name': "mynet",
                'ip_range': "10.0.0.0/8",
                'subnets': [
                    {
                        'type': "cloud",
                        'ip_range': "10.0.1.0/24",
                        'network_zone': "eu-central"
                    }
                ],
                'routes': [
                    {
                        'destination': "10.100.1.0/24",
                        'gateway': "10.0.1.1",
                    }
                ]
            }
        )

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_get_actions_list(self, networks_client, network, response_get_actions):
        networks_client._client.request.return_value = response_get_actions
        result = networks_client.get_actions_list(network, sort="id")
        networks_client._client.request.assert_called_with(url="/networks/1/actions", method="GET",
                                                           params={"sort": "id"})

        actions = result.actions
        assert len(actions) == 1
        assert isinstance(actions[0], BoundAction)

        assert actions[0]._client == networks_client._client.actions
        assert actions[0].id == 13
        assert actions[0].command == "add_subnet"

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_update(self, networks_client, network, response_update_network):
        networks_client._client.request.return_value = response_update_network
        network = networks_client.update(network, name="new-name")
        networks_client._client.request.assert_called_with(url="/networks/1", method="PUT", json={"name": "new-name"})

        assert network.id == 4711
        assert network.name == "new-name"

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_change_protection(self, networks_client, network, generic_action):
        networks_client._client.request.return_value = generic_action
        action = networks_client.change_protection(network, True)
        networks_client._client.request.assert_called_with(url="/networks/1/actions/change_protection", method="POST",
                                                           json={"delete": True})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_delete(self, networks_client, network, generic_action):
        networks_client._client.request.return_value = generic_action
        delete_success = networks_client.delete(network)
        networks_client._client.request.assert_called_with(url="/networks/1", method="DELETE")

        assert delete_success is True

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_add_subnet(self, networks_client, network, generic_action, network_subnet):
        networks_client._client.request.return_value = generic_action

        action = networks_client.add_subnet(network, network_subnet)
        networks_client._client.request.assert_called_with(url="/networks/1/actions/add_subnet", method="POST",
                                                           json={"type": "cloud", "ip_range": "10.0.1.0/24",
                                                                 "network_zone": "eu-central"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_delete_subnet(self, networks_client, network, generic_action, network_subnet):
        networks_client._client.request.return_value = generic_action

        action = networks_client.delete_subnet(network, network_subnet)
        networks_client._client.request.assert_called_with(url="/networks/1/actions/delete_subnet", method="POST",
                                                           json={"ip_range": "10.0.1.0/24"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_add_route(self, networks_client, network, generic_action, network_route):
        networks_client._client.request.return_value = generic_action

        action = networks_client.add_route(network, network_route)
        networks_client._client.request.assert_called_with(url="/networks/1/actions/add_route", method="POST",
                                                           json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_delete_route(self, networks_client, network, generic_action, network_route):
        networks_client._client.request.return_value = generic_action

        action = networks_client.delete_route(network, network_route)
        networks_client._client.request.assert_called_with(url="/networks/1/actions/delete_route", method="POST",
                                                           json={"destination": "10.100.1.0/24", "gateway": "10.0.1.1"})

        assert action.id == 1
        assert action.progress == 0

    @pytest.mark.parametrize("network", [Network(id=1), BoundNetwork(mock.MagicMock(), dict(id=1))])
    def test_change_ip_range(self, networks_client, network, generic_action):
        networks_client._client.request.return_value = generic_action
        action = networks_client.change_ip_range(network, "10.0.0.0/12")
        networks_client._client.request.assert_called_with(url="/networks/1/actions/change_ip_range", method="POST",
                                                           json={"ip_range": "10.0.0.0/12"})

        assert action.id == 1
        assert action.progress == 0