class TestImagesClient(object): def test_get_by_id(self, hetzner_client): image = hetzner_client.images.get_by_id(1) assert image.id == 4711 assert image.name == "ubuntu-16.04" assert image.description == "Ubuntu 16.04 Standard 64 bit" def test_get_by_name(self, hetzner_client): image = hetzner_client.images.get_by_name("ubuntu-16.04") assert image.id == 4711 assert image.name == "ubuntu-16.04" assert image.description == "Ubuntu 16.04 Standard 64 bit" def test_get_list(self, hetzner_client): result = hetzner_client.images.get_list() images = result.images assert images[0].id == 4711 assert images[0].name == "ubuntu-16.04" assert images[0].description == "Ubuntu 16.04 Standard 64 bit" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_get_actions_list(self, hetzner_client, image): result = hetzner_client.images.get_actions_list(image) actions = result.actions assert len(actions) == 1 assert actions[0].id == 13 assert actions[0].command == "change_protection" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_update(self, hetzner_client, image): image = hetzner_client.images.update( image, description="My new Image description", type="snapshot", labels={}) assert image.id == 4711 assert image.description == "My new Image description" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_delete(self, hetzner_client, image): delete_success = hetzner_client.images.delete(image) assert delete_success is True @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_change_protection(self, hetzner_client, image): action = hetzner_client.images.change_protection(image, delete=True) assert action.id == 13 assert action.command == "change_protection"
def create_image(self, server, description=None, type=None, labels=None): # type: (servers.domain.Server, str, str, Optional[Dict[str, str]]) -> CreateImageResponse """Creates an image (snapshot) from a server by copying the contents of its disks. :param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>` :param description: str (optional) Description of the image. If you do not set this we auto-generate one for you. :param type: str (optional) Type of image to create (default: snapshot) Choices: snapshot, backup :param labels: Dict[str, str] User-defined labels (key-value pairs) :return: :class:`BoundAction <hcloud.actions.client.BoundAction>` """ data = {} if description is not None: data.update({"description": description}) if type is not None: data.update({"type": type}) if labels is not None: data.update({"labels": labels}) response = self._client.request( url="/servers/{server_id}/actions/create_image".format( server_id=server.id), method="POST", json=data) return CreateImageResponse(action=BoundAction(self._client.actions, response['action']), image=BoundImage(self._client.images, response['image']))
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) super(BoundServer, self).__init__(client, data, complete)
def test_bound_image_init(self, image_response): bound_image = BoundImage(client=mock.MagicMock(), data=image_response['image']) assert bound_image.id == 4711 assert bound_image.type == "snapshot" assert bound_image.status == "available" assert bound_image.name == "ubuntu-20.04" assert bound_image.description == "Ubuntu 20.04 Standard 64 bit" assert bound_image.image_size == 2.3 assert bound_image.disk_size == 10 assert bound_image.created == datetime.datetime(2016, 1, 30, 23, 50, tzinfo=tzoffset( None, 0)) assert bound_image.os_flavor == "ubuntu" assert bound_image.os_version == "16.04" assert bound_image.rapid_deploy is False assert bound_image.deprecated == datetime.datetime(2018, 2, 28, 0, 0, tzinfo=tzoffset( None, 0)) assert isinstance(bound_image.created_from, BoundServer) assert bound_image.created_from.id == 1 assert bound_image.created_from.name == "Server" assert bound_image.created_from.complete is False assert isinstance(bound_image.bound_to, BoundServer) assert bound_image.bound_to.id == 1 assert bound_image.bound_to.complete is False
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'] ] firewalls = [ PublicNetworkFirewall(BoundFirewall(client._client.firewalls, {"id": firewall["id"]}, complete=False), status=firewall["status"]) for firewall in public_net.get("firewalls", []) ] data['public_net'] = PublicNetwork(ipv4=ipv4_address, ipv6=ipv6_network, floating_ips=floating_ips, firewalls=firewalls) 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)
class TestImagesClient(object): @pytest.fixture() def images_client(self): return ImagesClient(client=mock.MagicMock()) def test_get_by_id(self, images_client, image_response): images_client._client.request.return_value = image_response image = images_client.get_by_id(1) images_client._client.request.assert_called_with(url="/images/1", method="GET") assert image._client is images_client assert image.id == 4711 assert image.name == "ubuntu-20.04" @pytest.mark.parametrize("params", [{ 'name': "ubuntu-20.04", "type": "system", "sort": "id", "bound_to": "1", "label_selector": "k==v", "page": 1, "per_page": 10 }, { 'name': "" }, {}]) def test_get_list(self, images_client, two_images_response, params): images_client._client.request.return_value = two_images_response result = images_client.get_list(**params) images_client._client.request.assert_called_with(url="/images", method="GET", params=params) images = result.images assert result.meta is None assert len(images) == 2 images1 = images[0] images2 = images[1] assert images1._client is images_client assert images1.id == 4711 assert images1.name == "ubuntu-20.04" assert images2._client is images_client assert images2.id == 4712 assert images2.name == "ubuntu-18.10" @pytest.mark.parametrize("params", [{ 'name': "ubuntu-20.04", "type": "system", "sort": "id", "bound_to": "1", "label_selector": "k==v", }, {}]) def test_get_all(self, images_client, two_images_response, params): images_client._client.request.return_value = two_images_response images = images_client.get_all(**params) params.update({"page": 1, "per_page": 50}) images_client._client.request.assert_called_with(url="/images", method="GET", params=params) assert len(images) == 2 images1 = images[0] images2 = images[1] assert images1._client is images_client assert images1.id == 4711 assert images1.name == "ubuntu-20.04" assert images2._client is images_client assert images2.id == 4712 assert images2.name == "ubuntu-18.10" def test_get_by_name(self, images_client, one_images_response): images_client._client.request.return_value = one_images_response image = images_client.get_by_name("ubuntu-20.04") params = {"name": "ubuntu-20.04"} images_client._client.request.assert_called_with(url="/images", method="GET", params=params) assert image._client is images_client assert image.id == 4711 assert image.name == "ubuntu-20.04" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_get_actions_list(self, images_client, image, response_get_actions): images_client._client.request.return_value = response_get_actions result = images_client.get_actions_list(image) images_client._client.request.assert_called_with( url="/images/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 == images_client._client.actions assert actions[0].id == 13 assert actions[0].command == "change_protection" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_update(self, images_client, image, response_update_image): images_client._client.request.return_value = response_update_image image = images_client.update(image, description="My new Image description", type="snapshot", labels={}) images_client._client.request.assert_called_with( url="/images/1", method="PUT", json={ "description": "My new Image description", "type": "snapshot", "labels": {} }) assert image.id == 4711 assert image.description == "My new Image description" @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_change_protection(self, images_client, image, generic_action): images_client._client.request.return_value = generic_action action = images_client.change_protection(image, True) images_client._client.request.assert_called_with( url="/images/1/actions/change_protection", method="POST", json={"delete": True}) assert action.id == 1 assert action.progress == 0 @pytest.mark.parametrize( "image", [Image(id=1), BoundImage(mock.MagicMock(), dict(id=1))]) def test_delete(self, images_client, image, generic_action): images_client._client.request.return_value = generic_action delete_success = images_client.delete(image) images_client._client.request.assert_called_with(url="/images/1", method="DELETE") assert delete_success is True
def bound_image(self, hetzner_client): return BoundImage(client=hetzner_client.images, data=dict(id=14))