class TestServer(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.resource = resource()
        self.client = ProfitBricksService(
            username=configuration.USERNAME,
            password=configuration.PASSWORD,
            headers=configuration.HEADERS)

        # Create test datacenter.
        self.datacenter = self.client.create_datacenter(
            datacenter=Datacenter(**self.resource['datacenter']))
        wait_for_completion(self.client, self.datacenter, 'create_datacenter')

        # Create test volume1.
        self.volume1 = self.client.create_volume(
            datacenter_id=self.datacenter['id'],
            volume=Volume(**self.resource['volume']))
        wait_for_completion(self.client, self.volume1, 'create_volume')

        # Create test volume2 (attach volume test).
        self.volume2 = self.client.create_volume(
            datacenter_id=self.datacenter['id'],
            volume=Volume(**self.resource['volume']))
        wait_for_completion(self.client, self.volume2, 'create_volume')

        # Create test server.
        server = Server(**self.resource['server'])
        server.attach_volumes = [self.volume1['id']]
        self.server = self.client.create_server(
            datacenter_id=self.datacenter['id'],
            server=server)
        wait_for_completion(self.client, self.server, 'create_server')

        # Create test NIC.
        self.nic = self.client.create_nic(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic=NIC(**self.resource['nic']))
        wait_for_completion(self.client, self.nic, 'create_nic')

        # Find an Ubuntu image for testing.
        for item in self.client.list_images()['items']:
            if 'Ubuntu-15' in item['properties']['name'] and item['properties']['location'] == configuration.LOCATION:
                self.image = item

    @classmethod
    def tearDownClass(self):
        self.client.delete_datacenter(datacenter_id=self.datacenter['id'])

    def test_list(self):
        servers = self.client.list_servers(datacenter_id=self.datacenter['id'])

        self.assertGreater(len(servers), 0)
        self.assertEqual(servers['items'][0]['type'], 'server')
        assertRegex(self, servers['items'][0]['id'], self.resource['uuid_match'])

    def test_get(self):
        server = self.client.get_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id']
        )

        self.assertEqual(server['type'], 'server')
        self.assertEqual(server['id'], self.server['id'])
        self.assertEqual(server['properties']['name'], self.resource['server']['name'])
        self.assertEqual(server['properties']['cores'], self.resource['server']['cores'])
        self.assertEqual(server['properties']['ram'], self.resource['server']['ram'])

    def test_delete(self):
        server = self.client.create_server(
            datacenter_id=self.datacenter['id'],
            server=Server(**self.resource['server'])
        )
        wait_for_completion(self.client, server, 'create_server')

        response = self.client.delete_server(
            datacenter_id=self.datacenter['id'],
            server_id=server['id']
        )

        self.assertTrue(response)

    def test_update(self):
        server = self.client.update_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            name=self.resource['server']['name'] + ' RENAME')
        wait_for_completion(self.client, server, 'update_server')
        server = self.client.get_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id']
        )

        self.assertEqual(server['id'], self.server['id'])
        self.assertEqual(server['properties']['name'], self.resource['server']['name'] + ' RENAME')
        self.assertEqual(server['properties']['cores'], self.resource['server']['cores'])
        self.assertEqual(server['properties']['ram'], self.resource['server']['ram'])

    def test_create_simple(self):
        # Use server created dring server test setup
        assertRegex(self, self.server['id'], self.resource['uuid_match'])
        self.assertEqual(self.server['type'], 'server')
        self.assertEqual(self.server['properties']['name'], self.resource['server']['name'])
        self.assertEqual(self.server['properties']['cores'], self.resource['server']['cores'])
        self.assertEqual(self.server['properties']['ram'], self.resource['server']['ram'])
        self.assertIsNone(self.server['properties']['availabilityZone'])
        self.assertIsNone(self.server['properties']['vmState'])

    def test_create_complex(self):
        fwrule = FirewallRule(**self.resource['fwrule'])
        nic = NIC(firewall_rules=[fwrule], **self.resource['nic'])
        volume = Volume(image=self.image['id'],
                        image_password='******',
                        ssh_keys=['ssh-rsa AAAAB3NzaC1'],
                        **self.resource['volume'])

        server = Server(
            nics=[nic],
            create_volumes=[volume],
            **self.resource['server'])

        composite_server = self.client.create_server(
            datacenter_id=self.datacenter['id'],
            server=server)
        wait_for_completion(self.client, composite_server, 'create_server', wait_timeout=600)

        composite_server = self.client.get_server(
            datacenter_id=self.datacenter['id'],
            server_id=composite_server['id'])

        assertRegex(self, composite_server['id'], self.resource['uuid_match'])
        self.assertEqual(composite_server['properties']['name'], self.resource['server']['name'])
        self.assertEqual(composite_server['properties']['cores'], self.resource['server']['cores'])
        self.assertEqual(composite_server['properties']['ram'], self.resource['server']['ram'])
        self.assertEqual(composite_server['properties']['availabilityZone'], 'AUTO')
        self.assertIn(composite_server['properties']['vmState'], self.resource['vm_states'])

    def test_start_server(self):
        server = self.client.start_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'])

        self.assertTrue(server)

    def test_stop_server(self):
        server = self.client.stop_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'])

        self.assertTrue(server)

    def test_reboot_server(self):
        server = self.client.reboot_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'])

        self.assertTrue(server)

    def test_get_attached_volumes(self):
        servers = self.client.get_attached_volumes(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'])

        self.assertGreater(len(servers), 0)
        self.assertEqual(servers['items'][0]['id'], self.volume1['id'])
        self.assertEqual(servers['items'][0]['properties']['name'], self.resource['volume']['name'])
        self.assertEqual(servers['items'][0]['properties']['size'], self.resource['volume']['size'])
        self.assertEqual(servers['items'][0]['properties']['bus'], self.resource['volume']['bus'])
        self.assertEqual(servers['items'][0]['properties']['type'], self.resource['volume']['type'])
        self.assertEqual(servers['items'][0]['properties']['licenceType'], 'UNKNOWN')
        self.assertIsNone(servers['items'][0]['properties']['image'])
        self.assertIsNone(servers['items'][0]['properties']['imagePassword'])
        self.assertFalse(servers['items'][0]['properties']['cpuHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['cpuHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotUnplug'])

    def test_get_attached_volume(self):
        server = self.client.get_attached_volume(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            volume_id=self.volume1['id'])

        self.assertEqual(server['id'], self.volume1['id'])
        self.assertEqual(server['properties']['name'], self.resource['volume']['name'])
        self.assertEqual(server['properties']['size'], self.resource['volume']['size'])
        self.assertEqual(server['properties']['bus'], self.resource['volume']['bus'])
        self.assertEqual(server['properties']['type'], self.resource['volume']['type'])
        self.assertEqual(server['properties']['licenceType'], self.resource['volume']['licence_type'])
        self.assertIsNone(server['properties']['image'])
        self.assertIsNone(server['properties']['imagePassword'])
        self.assertFalse(server['properties']['cpuHotPlug'])
        self.assertFalse(server['properties']['cpuHotUnplug'])
        self.assertFalse(server['properties']['ramHotPlug'])
        self.assertFalse(server['properties']['ramHotUnplug'])
        self.assertFalse(server['properties']['nicHotPlug'])
        self.assertFalse(server['properties']['nicHotUnplug'])
        self.assertFalse(server['properties']['discVirtioHotPlug'])
        self.assertFalse(server['properties']['discVirtioHotUnplug'])
        self.assertFalse(server['properties']['discScsiHotPlug'])
        self.assertFalse(server['properties']['discScsiHotUnplug'])

    def test_attach_volume(self):
        volume = self.client.attach_volume(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            volume_id=self.volume2['id'])
        wait_for_completion(self.client, volume, 'attach_volume')

        self.assertEqual(volume['id'], self.volume2['id'])
        self.assertEqual(volume['properties']['name'], self.resource['volume']['name'])
        self.assertEqual(volume['properties']['size'], self.resource['volume']['size'])
        self.assertEqual(volume['properties']['type'], self.resource['volume']['type'])
        self.assertEqual(volume['properties']['licenceType'], self.resource['volume']['licence_type'])
        self.assertIsNone(volume['properties']['bus'])
        self.assertIsNone(volume['properties']['image'])
        self.assertIsNone(volume['properties']['imagePassword'])
        self.assertFalse(volume['properties']['cpuHotPlug'])
        self.assertFalse(volume['properties']['cpuHotUnplug'])
        self.assertFalse(volume['properties']['ramHotPlug'])
        self.assertFalse(volume['properties']['ramHotUnplug'])
        self.assertFalse(volume['properties']['nicHotPlug'])
        self.assertFalse(volume['properties']['nicHotUnplug'])
        self.assertFalse(volume['properties']['discVirtioHotPlug'])
        self.assertFalse(volume['properties']['discVirtioHotUnplug'])
        self.assertFalse(volume['properties']['discScsiHotPlug'])
        self.assertFalse(volume['properties']['discScsiHotUnplug'])

        response = self.client.detach_volume(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            volume_id=self.volume2['id'])

    def test_detach_volume(self):
        volume = self.client.detach_volume(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            volume_id=self.volume1['id'])

        self.assertTrue(volume)
class TestServer(unittest.TestCase):
    def setUp(self):
        self.server = ProfitBricksService(
            username='******', password='******')

    def test_list_servers(self):
        servers = self.server.list_servers(datacenter_id=datacenter_id)

        self.assertEqual(len(servers), 4)
        self.assertEqual(servers['items'][0]['id'], server_id)
        self.assertEqual(servers['items'][0]['properties']['name'], 'New Server')
        self.assertEqual(servers['items'][0]['properties']['cores'], '4')
        self.assertEqual(servers['items'][0]['properties']['ram'], '4096')
        self.assertEqual(servers['items'][0]['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(servers['items'][0]['properties']['vmState'], 'SHUTOFF')
        self.assertEqual(servers['items'][0]['properties']['bootVolume'], None)
        self.assertEqual(servers['items'][0]['properties']['bootCdrom'], None)

    def test_get_server(self):
        server = self.server.get_server(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertEqual(server['id'], server_id)
        self.assertEqual(server['properties']['name'], 'New Server')
        self.assertEqual(server['properties']['cores'], '4')
        self.assertEqual(server['properties']['ram'], '4096')
        self.assertEqual(server['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(server['properties']['vmState'], 'SHUTOFF')
        self.assertEqual(server['properties']['bootVolume'], None)
        self.assertEqual(server['properties']['bootCdrom'], None)

    def test_delete_server(self):
        server = self.server.delete_server(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertTrue(server)

    def test_update_server(self):
        server = self.server.update_server(
            datacenter_id=datacenter_id,
            server_id=server_id,
            cores=16)

        self.assertEqual(server['id'], server_id)
        self.assertEqual(server['properties']['name'], 'server1 - updated')
        self.assertEqual(server['properties']['cores'], '16')
        self.assertEqual(server['properties']['ram'], '4096')
        self.assertEqual(server['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(server['properties']['bootVolume']['id'], '<ID-OF-ANOTHER-STORAGE>')
        self.assertEqual(server['properties']['bootCdrom'], None)

    def test_create_complex(self):
        nic1 = NIC(
            name='nic1',
            ips=['10.2.2.3'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        nic2 = NIC(
            name='nic2',
            ips=['10.2.3.4'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        volume1 = Volume(
            name='volume1',
            size=56,
            image='<IMAGE/SNAPSHOT-ID>',
            bus='VIRTIO'
            )

        volume2 = Volume(
            name='volume2',
            size=56,
            image='<IMAGE/SNAPSHOT-ID>',
            bus='VIRTIO'
            )

        nics = [nic1, nic2]
        create_volumes = [volume1, volume2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            nics=nics,
            create_volumes=create_volumes
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id, server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(
            response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_existing_volume(self):

        volume_id = '<NEW-STORAGE-ID>'

        attach_volumes = [volume_id]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            attach_volumes=attach_volumes
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id, server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(
            response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_volumes_only(self):
        volume1 = Volume(
            name='volume1',
            size=56,
            image='<IMAGE/SNAPSHOT-ID>',
            bus='VIRTIO'
            )

        volume2 = Volume(
            name='volume2',
            size=56,
            image='<IMAGE/SNAPSHOT-ID>',
            bus='VIRTIO'
            )

        create_volumes = [volume1, volume2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            create_volumes=create_volumes
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id, server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_nics_only(self):
        nic1 = NIC(
            name='nic1',
            ips=['10.2.2.3'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        nic2 = NIC(
            name='nic2',
            ips=['10.2.3.4'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        nics = [nic1, nic2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            nics=nics
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id, server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_simple(self):
        i = Server(
            name='server1',
            ram=4096,
            cores=4
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id,
            server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_two_existing_volumes(self):
        volume_id1 = '700e1cab-99b2-4c30-ba8c-1d273ddba023'
        volume_id2 = '800e1cab-99b2-4c30-ba8c-1d273ddba024'

        attach_volumes = [volume_id1, volume_id2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            attach_volumes=attach_volumes
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id,
            server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_boot_volume(self):
        volume_id1 = '700e1cab-99b2-4c30-ba8c-1d273ddba023'
        volume_id2 = '800e1cab-99b2-4c30-ba8c-1d273ddba024'
        boot_volume_id = '800e1cab-99b2-4c30-ba8c-1d273ddba024'

        attach_volumes = [volume_id1, volume_id2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            boot_volume_id=boot_volume_id,
            attach_volumes=attach_volumes
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id,
            server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_create_with_nics_and_existing_volume(self):
        volume_id1 = '700e1cab-99b2-4c30-ba8c-1d273ddba023'
        volume_id2 = '800e1cab-99b2-4c30-ba8c-1d273ddba024'
        boot_volume_id = '800e1cab-99b2-4c30-ba8c-1d273ddba024'

        attach_volumes = [volume_id1, volume_id2]

        nic1 = NIC(
            name='nic1',
            ips=['10.2.2.3'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        nic2 = NIC(
            name='nic2',
            ips=['10.2.3.4'],
            dhcp='true',
            lan=1,
            firewall_active=True,
            )

        nics = [nic1, nic2]

        i = Server(
            name='server1',
            ram=4096,
            cores=4,
            boot_volume_id=boot_volume_id,
            attach_volumes=attach_volumes,
            nics=nics
            )

        response = self.server.create_server(
            datacenter_id=datacenter_id,
            server=i)

        self.assertEqual(response['id'], server_id)
        self.assertEqual(response['properties']['name'], 'New Server')
        self.assertEqual(response['properties']['cores'], '4')
        self.assertEqual(response['properties']['ram'], '4096')
        self.assertEqual(response['properties']['availabilityZone'], 'ZONE_1')
        self.assertEqual(response['properties']['vmState'], 'SHUTOFF')

    def test_get_attached_volumes(self):
        servers = self.server.get_attached_volumes(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertEqual(len(servers), 4)
        self.assertEqual(servers['items'][0]['id'], '700e1cab-99b2-4c30-ba8c-1d273ddba025')
        self.assertEqual(servers['items'][0]['properties']['name'], 'my boot volume for server 1')
        self.assertEqual(servers['items'][0]['properties']['size'], 80)
        self.assertEqual(servers['items'][0]['properties']['bus'], 'VIRTIO')
        self.assertEqual(servers['items'][0]['properties']['image'], None)
        self.assertEqual(servers['items'][0]['properties']['imagePassword'], None)
        self.assertEqual(servers['items'][0]['properties']['type'], 'HDD')
        self.assertEqual(servers['items'][0]['properties']['licenceType'], 'WINDOWS')
        self.assertFalse(servers['items'][0]['properties']['cpuHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['cpuHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotUnplug'])

    def test_get_attached_volume(self):
        volume_id = '700e1cab-99b2-4c30-ba8c-1d273ddba025'

        server = self.server.get_attached_volume(
            datacenter_id=datacenter_id,
            server_id=server_id,
            volume_id=volume_id)

        self.assertEqual(server['id'], volume_id)
        self.assertEqual(server['properties']['name'], 'my boot volume for server 1')
        self.assertEqual(server['properties']['size'], 80)
        self.assertEqual(server['properties']['bus'], 'VIRTIO')
        self.assertEqual(server['properties']['image'], None)
        self.assertEqual(server['properties']['imagePassword'], None)
        self.assertEqual(server['properties']['type'], 'HDD')
        self.assertEqual(server['properties']['licenceType'], 'WINDOWS')
        self.assertFalse(server['properties']['cpuHotPlug'])
        self.assertFalse(server['properties']['cpuHotUnplug'])
        self.assertFalse(server['properties']['ramHotPlug'])
        self.assertFalse(server['properties']['ramHotUnplug'])
        self.assertFalse(server['properties']['nicHotPlug'])
        self.assertFalse(server['properties']['nicHotUnplug'])
        self.assertFalse(server['properties']['discVirtioHotPlug'])
        self.assertFalse(server['properties']['discVirtioHotUnplug'])
        self.assertFalse(server['properties']['discScsiHotPlug'])
        self.assertFalse(server['properties']['discScsiHotUnplug'])

    def test_detach_volume(self):
        volume_id = '700e1cab-99b2-4c30-ba8c-1d273ddba025'

        server = self.server.detach_volume(
            datacenter_id=datacenter_id,
            server_id=server_id,
            volume_id=volume_id)

        self.assertTrue(server)

    def test_attach_volume(self):
        volume_id = '700e1cab-99b2-4c30-ba8c-1d273ddba025'

        server = self.server.attach_volume(
            datacenter_id=datacenter_id,
            server_id=server_id,
            volume_id=volume_id)

        self.assertEqual(server['id'], volume_id)
        self.assertEqual(server['properties']['name'], 'my boot volume for server 1')
        self.assertEqual(server['properties']['size'], 80)
        self.assertEqual(server['properties']['bus'], 'VIRTIO')
        self.assertEqual(server['properties']['image'], None)
        self.assertEqual(server['properties']['imagePassword'], None)
        self.assertEqual(server['properties']['type'], 'HDD')
        self.assertEqual(server['properties']['licenceType'], 'WINDOWS')
        self.assertFalse(server['properties']['cpuHotPlug'])
        self.assertFalse(server['properties']['cpuHotUnplug'])
        self.assertFalse(server['properties']['ramHotPlug'])
        self.assertFalse(server['properties']['ramHotUnplug'])
        self.assertFalse(server['properties']['nicHotPlug'])
        self.assertFalse(server['properties']['nicHotUnplug'])
        self.assertFalse(server['properties']['discVirtioHotPlug'])
        self.assertFalse(server['properties']['discVirtioHotUnplug'])
        self.assertFalse(server['properties']['discScsiHotPlug'])
        self.assertFalse(server['properties']['discScsiHotUnplug'])

    def test_get_attached_cdroms(self):
        servers = self.server.get_attached_cdroms(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertEqual(len(servers), 4)
        self.assertEqual(servers['items'][0]['id'], '7df81087-5835-41c6-a10b-3e098593bbd2')
        self.assertEqual(servers['items'][0]['properties']['name'], 'Ubuntu 14.04')
        self.assertEqual(servers['items'][0]['properties']['size'], 28)
        self.assertEqual(servers['items'][0]['properties']['description'],
                         'Ubuntu image description')
        self.assertEqual(servers['items'][0]['properties']['location'], 'de/fkb')
        self.assertEqual(servers['items'][0]['properties']['imageType'], 'CDROM')
        self.assertEqual(servers['items'][0]['properties']['licenceType'], 'UNKNOWN')
        self.assertFalse(servers['items'][0]['properties']['public'])
        self.assertFalse(servers['items'][0]['properties']['cpuHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['cpuHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['ramHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['nicHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discVirtioHotUnplug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotPlug'])
        self.assertFalse(servers['items'][0]['properties']['discScsiHotUnplug'])

    def test_get_attached_cdrom(self):
        cdrom_id = '7df81087-5835-41c6-a10b-3e098593bbd2'

        server = self.server.get_attached_cdrom(
            datacenter_id=datacenter_id,
            server_id=server_id,
            cdrom_id=cdrom_id)

        self.assertEqual(server['id'], cdrom_id)
        self.assertEqual(server['properties']['name'], 'Ubuntu 14.04')
        self.assertEqual(server['properties']['size'], 28)
        self.assertEqual(server['properties']['description'], 'Ubuntu image description')
        self.assertEqual(server['properties']['location'], 'de/fkb')
        self.assertEqual(server['properties']['imageType'], 'CDROM')
        self.assertEqual(server['properties']['licenceType'], 'UNKNOWN')
        self.assertFalse(server['properties']['public'])
        self.assertFalse(server['properties']['cpuHotPlug'])
        self.assertFalse(server['properties']['cpuHotUnplug'])
        self.assertFalse(server['properties']['ramHotPlug'])
        self.assertFalse(server['properties']['ramHotUnplug'])
        self.assertFalse(server['properties']['nicHotPlug'])
        self.assertFalse(server['properties']['nicHotUnplug'])
        self.assertFalse(server['properties']['discVirtioHotPlug'])
        self.assertFalse(server['properties']['discVirtioHotUnplug'])
        self.assertFalse(server['properties']['discScsiHotPlug'])
        self.assertFalse(server['properties']['discScsiHotUnplug'])

    def test_detach_cdrom(self):
        cdrom_id = '7df81087-5835-41c6-a10b-3e098593bbd2'

        server = self.server.detach_cdrom(
            datacenter_id=datacenter_id,
            server_id=server_id,
            cdrom_id=cdrom_id)

        self.assertTrue(server)

    def test_attach_cdrom(self):
        cdrom_id = '7df81087-5835-41c6-a10b-3e098593bbd2'

        server = self.server.attach_cdrom(
            datacenter_id=datacenter_id,
            server_id=server_id,
            cdrom_id=cdrom_id)

        self.assertEqual(server['id'], cdrom_id)
        self.assertEqual(server['properties']['name'], 'Ubuntu 14.04')
        self.assertEqual(server['properties']['size'], 28)
        self.assertEqual(server['properties']['description'], 'Ubuntu image description')
        self.assertEqual(server['properties']['location'], 'de/fkb')
        self.assertEqual(server['properties']['imageType'], 'CDROM')
        self.assertEqual(server['properties']['licenceType'], 'UNKNOWN')
        self.assertFalse(server['properties']['public'])
        self.assertFalse(server['properties']['cpuHotPlug'])
        self.assertFalse(server['properties']['cpuHotUnplug'])
        self.assertFalse(server['properties']['ramHotPlug'])
        self.assertFalse(server['properties']['ramHotUnplug'])
        self.assertFalse(server['properties']['nicHotPlug'])
        self.assertFalse(server['properties']['nicHotUnplug'])
        self.assertFalse(server['properties']['discVirtioHotPlug'])
        self.assertFalse(server['properties']['discVirtioHotUnplug'])
        self.assertFalse(server['properties']['discScsiHotPlug'])
        self.assertFalse(server['properties']['discScsiHotUnplug'])

    def test_start_server(self):
        server = self.server.start_server(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertTrue(server)

    def test_stop_server(self):
        server = self.server.stop_server(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertTrue(server)

    def test_reboot_server(self):
        server = self.server.reboot_server(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertTrue(server)
class TestServer(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.resource = resource()
        self.client = ProfitBricksService(username=configuration.USERNAME,
                                          password=configuration.PASSWORD,
                                          headers=configuration.HEADERS)

        # Create test datacenter.
        self.datacenter = self.client.create_datacenter(datacenter=Datacenter(
            **self.resource['datacenter']))
        self.client.wait_for_completion(self.datacenter)

        # Create test volume1.
        self.volume1 = self.client.create_volume(
            datacenter_id=self.datacenter['id'],
            volume=Volume(**self.resource['volume']))
        self.client.wait_for_completion(self.volume1)

        # Create test volume2 (attach volume test).
        self.volume2 = self.client.create_volume(
            datacenter_id=self.datacenter['id'],
            volume=Volume(**self.resource['volume']))
        self.client.wait_for_completion(self.volume2)

        # Create test server.
        server = Server(**self.resource['server'])
        server.attach_volumes = [self.volume1['id']]
        self.server = self.client.create_server(
            datacenter_id=self.datacenter['id'], server=server)
        self.client.wait_for_completion(self.server)

        # Create test NIC.
        self.nic = self.client.create_nic(datacenter_id=self.datacenter['id'],
                                          server_id=self.server['id'],
                                          nic=NIC(**self.resource['nic']))
        self.client.wait_for_completion(self.nic)

        # Find an Ubuntu image for testing.
        for item in self.client.list_images()['items']:
            if (configuration.IMAGE_NAME in item['properties']['name'] and
                    item['properties']['location'] == configuration.LOCATION):
                self.image = item
        # Find a cdrom image
        images = self.client.list_images(depth=5)
        usedIndex = 0
        for index, image in enumerate(images['items']):
            if (image['metadata']['state'] == "AVAILABLE"
                    and image['properties']['public'] is True
                    and image['properties']['imageType'] == "CDROM" and
                    image['properties']['location'] == configuration.LOCATION
                    and image['properties']['licenceType'] == "LINUX"):
                if (usedIndex == 0):
                    self.test_image1 = image
                    usedIndex = index
                else:
                    self.test_image2 = image
                    break
        # Create test cdrom
        self.cdrom = self.client.attach_cdrom(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            cdrom_id=self.test_image1['id'])
        self.client.wait_for_completion(self.cdrom)

    @classmethod
    def tearDownClass(self):
        self.client.delete_datacenter(datacenter_id=self.datacenter['id'])

    def test_list_servers(self):
        servers = self.client.list_servers(datacenter_id=self.datacenter['id'])

        self.assertGreater(len(servers), 0)
        self.assertEqual(servers['items'][0]['type'], 'server')
        self.assertTrue(self, len(servers['items']) > 0)
        assertRegex(self, servers['items'][0]['id'],
                    self.resource['uuid_match'])

    def test_get_server(self):
        server = self.client.get_server(datacenter_id=self.datacenter['id'],
                                        server_id=self.server['id'])

        self.assertEqual(server['type'], 'server')
        self.assertEqual(server['id'], self.server['id'])
        self.assertEqual(server['properties']['name'],
                         self.resource['server']['name'])
        self.assertEqual(server['properties']['cores'],
                         self.resource['server']['cores'])
        self.assertEqual(server['properties']['ram'],
                         self.resource['server']['ram'])
        self.assertEqual(server['properties']['availabilityZone'],
                         self.resource['server']['availability_zone'])
        self.assertEqual(server['properties']['cpuFamily'],
                         self.resource['server']['cpu_family'])
        # assertRegex(self, server['properties']['bootVolume']['id'], self.resource['uuid_match'])

    def test_get_failure(self):
        try:
            self.client.get_server(
                datacenter_id=self.datacenter['id'],
                server_id='00000000-0000-0000-0000-000000000000')
        except PBNotFoundError as e:
            self.assertIn(self.resource['not_found_error'],
                          e.content[0]['message'])

    def test_delete_server(self):
        server = self.client.create_server(
            datacenter_id=self.datacenter['id'],
            server=Server(**self.resource['server']))
        self.client.wait_for_completion(server)

        response = self.client.delete_server(
            datacenter_id=self.datacenter['id'], server_id=server['id'])

        self.assertTrue(response)

    def test_update_server(self):
        server = self.client.update_server(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            name=self.resource['server']['name'] + ' RENAME')
        self.client.wait_for_completion(server)
        server = self.client.get_server(datacenter_id=self.datacenter['id'],
                                        server_id=self.server['id'])

        self.assertEqual(server['id'], self.server['id'])
        self.assertEqual(server['properties']['name'],
                         self.resource['server']['name'] + ' RENAME')
        self.assertEqual(server['properties']['cores'],
                         self.resource['server']['cores'])
        self.assertEqual(server['properties']['ram'],
                         self.resource['server']['ram'])

    def test_create_server(self):
        # Use server created during server test setup
        assertRegex(self, self.server['id'], self.resource['uuid_match'])
        self.assertEqual(self.server['type'], 'server')
        self.assertEqual(self.server['properties']['name'],
                         self.resource['server']['name'])
        self.assertEqual(self.server['properties']['cores'],
                         self.resource['server']['cores'])
        self.assertEqual(self.server['properties']['ram'],
                         self.resource['server']['ram'])
        self.assertEqual(self.server['properties']['availabilityZone'],
                         self.resource['server']['availability_zone'])
        self.assertEqual(self.server['properties']['cpuFamily'],
                         self.resource['server']['cpu_family'])
        # assertRegex(self, server['properties']['bootVolume']['id'], self.resource['uuid_match'])
        # self.assertIsNone(self.server['properties']['availabilityZone'])
        self.assertIsNone(self.server['properties']['vmState'])

    def test_create_failure(self):
        try:
            server = Server(name=self.resource['server']['name'],
                            ram=self.resource['server']['ram'])
            self.client.create_server(datacenter_id=self.datacenter['id'],
                                      server=server)
        except PBError as e:
            self.assertIn(self.resource['missing_attribute_error'] % 'cores',
                          e.content[0]['message'])

    def test_create_composite(self):
        fwrule = FirewallRule(**self.resource['fwrule'])
        nic = NIC(firewall_rules=[fwrule], **self.resource['nic'])
        volume = Volume(image=self.image['id'],
                        image_password='******',
                        ssh_keys=['ssh-rsa AAAAB3NzaC1'],
                        **self.resource['volume'])
        volume.availability_zone = 'ZONE_3'

        server = Server(nics=[nic],
                        create_volumes=[volume],
                        **self.resource['server'])

        composite_server = self.client.create_server(
            datacenter_id=self.datacenter['id'], server=server)
        self.client.wait_for_completion(composite_server, timeout=600)

        composite_server = self.client.get_server(
            datacenter_id=self.datacenter['id'],
            server_id=composite_server['id'])

        assertRegex(self, composite_server['id'], self.resource['uuid_match'])
        self.assertEqual(composite_server['properties']['name'],
                         self.resource['server']['name'])
        self.assertEqual(composite_server['properties']['cores'],
                         self.resource['server']['cores'])
        self.assertEqual(composite_server['properties']['ram'],
                         self.resource['server']['ram'])
        self.assertEqual(composite_server['properties']['availabilityZone'],
                         'ZONE_1')
        self.assertIn(composite_server['properties']['vmState'],
                      self.resource['vm_states'])
        self.assertGreater(
            len(composite_server['entities']['volumes']['items']), 0)
        self.assertGreater(len(composite_server['entities']['nics']['items']),
                           0)

    def test_start_server(self):
        server = self.client.start_server(datacenter_id=self.datacenter['id'],
                                          server_id=self.server['id'])

        self.assertTrue(server)

    def test_stop_server(self):
        server = self.client.stop_server(datacenter_id=self.datacenter['id'],
                                         server_id=self.server['id'])

        self.assertTrue(server)

    def test_reboot_server(self):
        server = self.client.reboot_server(datacenter_id=self.datacenter['id'],
                                           server_id=self.server['id'])

        self.assertTrue(server)

    def test_get_attached_volumes(self):
        volumes = self.client.get_attached_volumes(
            datacenter_id=self.datacenter['id'], server_id=self.server['id'])

        self.assertGreater(len(volumes['items']), 0)
        self.assertEqual(volumes['items'][0]['type'], 'volume')
        self.assertEqual(volumes['items'][0]['id'], self.volume1['id'])
        self.assertEqual(volumes['items'][0]['properties']['name'],
                         self.resource['volume']['name'])
        self.assertEqual(volumes['items'][0]['properties']['size'],
                         self.resource['volume']['size'])
        self.assertEqual(volumes['items'][0]['properties']['bus'],
                         self.resource['volume']['bus'])
        self.assertEqual(volumes['items'][0]['properties']['type'],
                         self.resource['volume']['disk_type'])
        self.assertEqual(volumes['items'][0]['properties']['licenceType'],
                         'UNKNOWN')
        self.assertIsNone(volumes['items'][0]['properties']['image'])
        self.assertIsNone(volumes['items'][0]['properties']['imagePassword'])
        self.assertFalse(volumes['items'][0]['properties']['cpuHotPlug'])
        self.assertFalse(volumes['items'][0]['properties']['cpuHotUnplug'])
        self.assertFalse(volumes['items'][0]['properties']['ramHotPlug'])
        self.assertFalse(volumes['items'][0]['properties']['ramHotUnplug'])
        self.assertFalse(volumes['items'][0]['properties']['nicHotPlug'])
        self.assertFalse(volumes['items'][0]['properties']['nicHotUnplug'])
        self.assertFalse(
            volumes['items'][0]['properties']['discVirtioHotPlug'])
        self.assertFalse(
            volumes['items'][0]['properties']['discVirtioHotUnplug'])
        self.assertFalse(volumes['items'][0]['properties']['discScsiHotPlug'])
        self.assertFalse(
            volumes['items'][0]['properties']['discScsiHotUnplug'])

    def test_get_attached_volume(self):
        volume = self.client.get_attached_volume(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            volume_id=self.volume1['id'])

        self.assertEqual(volume['id'], self.volume1['id'])
        self.assertEqual(volume['properties']['name'],
                         self.resource['volume']['name'])
        self.assertEqual(volume['properties']['size'],
                         self.resource['volume']['size'])
        self.assertEqual(volume['properties']['bus'],
                         self.resource['volume']['bus'])
        self.assertEqual(volume['properties']['type'],
                         self.resource['volume']['disk_type'])
        self.assertEqual(volume['properties']['licenceType'],
                         self.resource['volume']['licence_type'])
        self.assertIsNone(volume['properties']['image'])
        self.assertIsNone(volume['properties']['imagePassword'])
        self.assertFalse(volume['properties']['cpuHotPlug'])
        self.assertFalse(volume['properties']['cpuHotUnplug'])
        self.assertFalse(volume['properties']['ramHotPlug'])
        self.assertFalse(volume['properties']['ramHotUnplug'])
        self.assertFalse(volume['properties']['nicHotPlug'])
        self.assertFalse(volume['properties']['nicHotUnplug'])
        self.assertFalse(volume['properties']['discVirtioHotPlug'])
        self.assertFalse(volume['properties']['discVirtioHotUnplug'])
        self.assertFalse(volume['properties']['discScsiHotPlug'])
        self.assertFalse(volume['properties']['discScsiHotUnplug'])

    def test_attach_volume(self):
        volume = self.client.attach_volume(datacenter_id=self.datacenter['id'],
                                           server_id=self.server['id'],
                                           volume_id=self.volume2['id'])
        self.client.wait_for_completion(volume)

        self.assertEqual(volume['id'], self.volume2['id'])
        self.assertEqual(volume['properties']['name'],
                         self.resource['volume']['name'])
        self.assertEqual(volume['properties']['size'],
                         self.resource['volume']['size'])
        self.assertEqual(volume['properties']['type'],
                         self.resource['volume']['disk_type'])
        self.assertEqual(volume['properties']['licenceType'],
                         self.resource['volume']['licence_type'])
        self.assertIsNone(volume['properties']['bus'])
        self.assertIsNone(volume['properties']['image'])
        self.assertIsNone(volume['properties']['imagePassword'])
        self.assertFalse(volume['properties']['cpuHotPlug'])
        self.assertFalse(volume['properties']['cpuHotUnplug'])
        self.assertFalse(volume['properties']['ramHotPlug'])
        self.assertFalse(volume['properties']['ramHotUnplug'])
        self.assertFalse(volume['properties']['nicHotPlug'])
        self.assertFalse(volume['properties']['nicHotUnplug'])
        self.assertFalse(volume['properties']['discVirtioHotPlug'])
        self.assertFalse(volume['properties']['discVirtioHotUnplug'])
        self.assertFalse(volume['properties']['discScsiHotPlug'])
        self.assertFalse(volume['properties']['discScsiHotUnplug'])

        self.client.detach_volume(datacenter_id=self.datacenter['id'],
                                  server_id=self.server['id'],
                                  volume_id=self.volume2['id'])

    def test_detach_volume(self):
        volume = self.client.detach_volume(datacenter_id=self.datacenter['id'],
                                           server_id=self.server['id'],
                                           volume_id=self.volume1['id'])

        self.assertTrue(volume)

    def test_list_cdroms(self):
        cdroms = self.client.get_attached_cdroms(
            datacenter_id=self.datacenter['id'], server_id=self.server['id'])

        self.assertGreater(len(cdroms['items']), 0)

    def test_attach_cdrom(self):
        attached_cdrom = self.client.attach_cdrom(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            cdrom_id=self.test_image2['id'])

        self.client.wait_for_completion(attached_cdrom, timeout=600)
        self.assertEqual(attached_cdrom['id'], self.test_image2['id'])
        self.assertEqual(attached_cdrom['properties']['name'],
                         self.test_image2['properties']['name'])

    def test_get_cdrom(self):
        attached_cdrom = self.client.attach_cdrom(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            cdrom_id=self.test_image1['id'])

        self.client.wait_for_completion(attached_cdrom, timeout=600)
        cdrom = self.client.get_attached_cdrom(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            cdrom_id=attached_cdrom['id'])
        self.assertEqual(cdrom['id'], attached_cdrom['id'])
        self.assertEqual(cdrom['properties']['name'],
                         attached_cdrom['properties']['name'])

    def test_detach_cdrom(self):
        detached_cd = self.client.detach_cdrom(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            cdrom_id=self.cdrom['id'])
        time.sleep(15)

        self.assertTrue(detached_cd)

        try:
            check_detached_cdrom_gone(self)
        except PBNotFoundError as e:
            self.assertIn(self.resource['not_found_error'],
                          e.content[0]['message'])
def main(argv=None):
    '''Command line options.'''

    if argv is None:
        argv = sys.argv
    else:
        sys.argv.extend(argv)

    program_name = os.path.basename(sys.argv[0])
    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version,
                                                     program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s

  Created by J. Buchhammer on %s.
  Copyright 2016 ProfitBricks GmbH. All rights reserved.

  Licensed under the Apache License 2.0
  http://www.apache.org/licenses/LICENSE-2.0

  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.

USAGE
''' % (program_shortdesc, str(__date__))

    try:
        # Setup argument parser
        parser = ArgumentParser(description=program_license,
                                formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('-u', '--user', dest='user', help='the login name')
        parser.add_argument('-p',
                            '--password',
                            dest='password',
                            help='the login password')
        parser.add_argument('-L',
                            '--Login',
                            dest='loginfile',
                            default=None,
                            help='the login file to use')
        parser.add_argument('-d',
                            '--datacenterid',
                            dest='dc_id',
                            required=True,
                            default=None,
                            help='datacenter of the server')
        parser.add_argument('-s',
                            '--serverid',
                            dest='serverid',
                            default=None,
                            help='ID of the server')
        parser.add_argument('-n',
                            '--name',
                            dest='servername',
                            default=None,
                            help='name of the server')
        parser.add_argument('-C',
                            '--command',
                            dest='command',
                            default=None,
                            help='remote shell command to use for shutdown')
        parser.add_argument('-v',
                            '--verbose',
                            dest="verbose",
                            action="count",
                            help="set verbosity level [default: %(default)s]")
        parser.add_argument('-V',
                            '--version',
                            action='version',
                            version=program_version_message)

        # Process arguments
        args = parser.parse_args()
        global verbose
        verbose = args.verbose
        dc_id = args.dc_id

        if verbose > 0:
            print("Verbose mode on")

        if args.serverid is None and args.servername is None:
            parser.error("one of 'serverid' or 'name' must be specified")

        (user, password) = getLogin(args.loginfile, args.user, args.password)
        if user is None or password is None:
            raise ValueError("user or password resolved to None")
        pbclient = ProfitBricksService(user, password)

        server = getServerStates(pbclient, dc_id, args.serverid,
                                 args.servername)
        if server is None:
            raise Exception(1, "specified server not found")
        print("using server {}(id={}) in state {}, {}".format(
            server['name'], server['id'], server['state'], server['vmstate']))
        # ! stop/start/reboot_server() simply return 'True' !
        # this implies, that there's NO response nor requestId to track!
        if server['vmstate'] == 'SHUTOFF':
            print("VM is already shut off")
        else:
            if args.command is None:
                print("no command specified for shutdown of VM")
            else:
                print("executing {}".format(args.command))
                cmdrc = call(args.command, shell=True)
                print("executing {} returned {}".format(args.command, cmdrc))
                server = wait_for_server(pbclient,
                                         dc_id,
                                         server['id'],
                                         indicator='vmstate',
                                         state='SHUTOFF',
                                         timeout=300)
        # first we have to delete all attached volumes
        volumes = pbclient.get_attached_volumes(dc_id, server['id'], 0)
        for vol in volumes['items']:
            print("deleting volume {} of server {}".format(
                vol['id'], server['name']))
            pbclient.delete_volume(dc_id, vol['id'])
        pbclient.delete_server(dc_id, server['id'])
        wait_for_datacenter(pbclient, dc_id)
    except KeyboardInterrupt:
        # handle keyboard interrupt #
        pass
    except Exception:
        traceback.print_exc()
        sys.stderr.write("\n" + program_name + ":  for help use --help\n")
        return 2
    return 0
def main(argv=None):
    '''Command line options.'''

    if argv is None:
        argv = sys.argv
    else:
        sys.argv.extend(argv)

    program_name = os.path.basename(sys.argv[0])
    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version,
                                                     program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s

  Created by J. Buchhammer on %s.
  Copyright 2016 ProfitBricks GmbH. All rights reserved.

  Licensed under the Apache License 2.0
  http://www.apache.org/licenses/LICENSE-2.0

  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.

USAGE
''' % (program_shortdesc, str(__date__))

    try:
        # Setup argument parser
        parser = ArgumentParser(description=program_license,
                                formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('-u', '--user', dest='user', help='the login name')
        parser.add_argument('-p', '--password', dest='password',
                            help='the login password')
        parser.add_argument('-L', '--Login', dest='loginfile', default=None,
                            help='the login file to use')
        parser.add_argument('-d', '--datacenterid', dest='dc_id',
                            required=True, default=None,
                            help='datacenter of the server')
        parser.add_argument('-s', '--serverid', dest='serverid', default=None,
                            help='ID of the server')
        parser.add_argument('-n', '--name', dest='servername', default=None,
                            help='name of the server')
        parser.add_argument('-C', '--command', dest='command', default=None,
                            help='remote shell command to use for shutdown')
        parser.add_argument('-v', '--verbose', dest="verbose", action="count",
                            help="set verbosity level [default: %(default)s]")
        parser.add_argument('-V', '--version', action='version',
                            version=program_version_message)

        # Process arguments
        args = parser.parse_args()
        global verbose
        verbose = args.verbose
        dc_id = args.dc_id

        if verbose > 0:
            print("Verbose mode on")

        if args.serverid is None and args.servername is None:
            parser.error("one of 'serverid' or 'name' must be specified")

        (user, password) = getLogin(args.loginfile, args.user, args.password)
        if user is None or password is None:
            raise ValueError("user or password resolved to None")
        pbclient = ProfitBricksService(user, password)

        server = getServerStates(pbclient, dc_id, args.serverid,
                                 args.servername)
        if server is None:
            raise Exception(1, "specified server not found")
        print("using server {}(id={}) in state {}, {}"
              .format(server['name'], server['id'], server['state'],
                      server['vmstate']))
        # ! stop/start/reboot_server() simply return 'True' !
        # this implies, that there's NO response nor requestId to track!
        if server['vmstate'] == 'SHUTOFF':
            print("VM is already shut off")
        else:
            if args.command is None:
                print("no command specified for shutdown of VM")
            else:
                print("executing {}".format(args.command))
                cmdrc = call(args.command, shell=True)
                print("executing {} returned {}".format(args.command, cmdrc))
                server = wait_for_server(pbclient, dc_id, server['id'],
                                         indicator='vmstate', state='SHUTOFF',
                                         timeout=300)
        # first we have to delete all attached volumes
        volumes = pbclient.get_attached_volumes(dc_id, server['id'], 0)
        for vol in volumes['items']:
            print("deleting volume {} of server {}"
                  .format(vol['id'], server['name']))
            pbclient.delete_volume(dc_id, vol['id'])
        pbclient.delete_server(dc_id, server['id'])
        wait_for_datacenter(pbclient, dc_id)
    except KeyboardInterrupt:
        # handle keyboard interrupt #
        return 0
    except Exception:
        traceback.print_exc()
        sys.stderr.write("\n" + program_name + ":  for help use --help\n")
        return 2