class TestLan(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 LAN.
        self.lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(**self.resource['lan']))
        wait_for_completion(self.client, self.lan, 'create_lan')

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

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

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

    @classmethod
    def tearDownClass(self):
        self.client.delete_datacenter(datacenter_id=self.datacenter['id'])
datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022'
server_id = '700e1cab-99b2-4c30-ba8c-1d273ddba023'

client = ProfitBricksService(
    username='******', password='******')

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

response = client.create_nic(
    datacenter_id=datacenter_id,
    server_id=server_id,
    nic=i)

"""Create NIC with FirewallRules
"""
from profitbricks.client import ProfitBricksService, FirewallRule, NIC

datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022'
server_id = '700e1cab-99b2-4c30-ba8c-1d273ddba023'
nic_id = '<NIC-ID>'

client = ProfitBricksService(
    username='******', password='******')

fwrule1 = FirewallRule(
    name='Open SSH port',
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)
Exemple #4
0
class TestLan(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 LAN.
        self.lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(**self.resource['lan']))
        self.client.wait_for_completion(self.lan)

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

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

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

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

    def test_list_lans(self):
        lans = self.client.list_lans(datacenter_id=self.datacenter['id'])

        self.assertGreater(len(lans), 0)
        self.assertEqual(lans['items'][0]['type'], 'lan')
        self.assertIn(lans['items'][0]['id'], ('1', '2', '3'))
        self.assertEqual(lans['items'][0]['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(lans['items'][0]['properties']['public'], self.resource['lan']['public'])

    def test_get_lan(self):
        lan = self.client.get_lan(datacenter_id=self.datacenter['id'], lan_id=self.lan['id'])

        self.assertEqual(lan['type'], 'lan')
        self.assertEqual(lan['id'], self.lan['id'])
        self.assertEqual(lan['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(lan['properties']['public'], self.resource['lan']['public'])

    def test_remove_lan(self):
        lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(**self.resource['lan']))

        self.client.wait_for_completion(lan)

        lan = self.client.delete_lan(datacenter_id=self.datacenter['id'], lan_id=lan['id'])

        self.assertTrue(lan)

    def test_update_lan(self):
        lan = self.client.update_lan(
            datacenter_id=self.datacenter['id'],
            lan_id=self.lan['id'],
            name=self.resource['lan']['name'] + ' - RENAME',
            public=False)

        self.assertEqual(lan['type'], 'lan')
        self.assertEqual(lan['properties']['name'], self.resource['lan']['name'] + ' - RENAME')
        self.assertFalse(lan['properties']['public'])

    def test_create_lan(self):
        self.assertEqual(self.lan['id'], '1')
        self.assertEqual(self.lan['type'], 'lan')
        self.assertEqual(self.lan['properties']['name'], self.resource['lan']['name'])
        self.assertEqual(self.lan['properties']['public'], self.resource['lan']['public'])

    def test_create_complex_lan(self):
        resource = NIC(**self.resource['nic'])

        nic1 = self.client.create_nic(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic=resource)
        self.client.wait_for_completion(nic1)
        self.assertFalse(nic1['properties']['nat'])
        self.assertEqual(nic1['properties']['name'], 'Python SDK Test')
        self.assertTrue(nic1['properties']['dhcp'])
        self.assertEqual(nic1['properties']['lan'], 1)
        self.assertTrue(nic1['properties']['firewallActive'])

        nics = [nic1['id']]
        lan = LAN(nics=nics, **self.resource['lan'])

        response = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=lan)
        self.client.wait_for_completion(response)

        self.assertEqual(response['type'], 'lan')
        self.assertEqual(response['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(response['properties']['public'])

    def test_get_lan_members(self):
        members = self.client.get_lan_members(
            datacenter_id=self.datacenter['id'],
            lan_id=self.lan['id'])

        self.assertGreater(len(members), 0)
        self.assertEqual(members['items'][0]['type'], 'nic')
        self.assertEqual(members['items'][0]['properties']['name'], self.resource['nic']['name'])
        assertRegex(self, members['items'][0]['properties']['mac'], self.resource['mac_match'])

    def test_get_failure(self):
        try:
            self.client.get_lan(datacenter_id=self.datacenter['id'], lan_id=0)
        except PBNotFoundError as e:
            self.assertIn(self.resource['not_found_error'], e.content[0]['message'])

    def test_create_failure(self):
        try:
            self.client.create_lan(
                datacenter_id='00000000-0000-0000-0000-000000000000', lan=LAN())
        except PBNotFoundError as e:
            self.assertIn(self.resource['not_found_error'], e.content[0]['message'])
Exemple #5
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ürgen 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('-t',
                            '--type',
                            dest='metatype',
                            default="OVF",
                            help='type of VM meta data')
        parser.add_argument('-m',
                            '--metadata',
                            dest='metafile',
                            required=True,
                            default=None,
                            help='meta data file')
        parser.add_argument('-d',
                            '--datacenterid',
                            dest='datacenterid',
                            default=None,
                            help='datacenter of the new server')
        parser.add_argument('-D',
                            '--DCname',
                            dest='dcname',
                            default=None,
                            help='new datacenter name')
        parser.add_argument('-l',
                            '--location',
                            dest='location',
                            default=None,
                            help='location for new datacenter')
        parser.add_argument('-v',
                            '--verbose',
                            dest="verbose",
                            action="count",
                            default=0,
                            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

        if verbose > 0:
            print("Verbose mode on")
            print("start {} with args {}".format(program_name, str(args)))

        (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)

        if args.metatype == 'OVF':
            metadata = OFVData(args.metafile)
            metadata.parse()
        else:
            sys.stderr.write("Metadata type '{}' is not supported".format(
                args.metatype))
            return 1

        # we need the DC first to have the location defined
        dc_id = None
        if args.datacenterid is None:
            if args.dcname is None or args.location is None:
                sys.stderr.write(
                    "Either '-d <id>' or '-D <name> -l <loc>'  must be specified"
                )
                return 1
            # else: we will create the DC later after parsing the meta data
        else:
            dc_id = args.datacenterid

        if dc_id is None:
            location = args.location
            dc = Datacenter(name=args.dcname,
                            location=location,
                            description="created by pb_importVM")
            print("create new DC {}".format(str(dc)))
            response = pbclient.create_datacenter(dc)
            dc_id = response['id']
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(result))
        else:
            dc = pbclient.get_datacenter(dc_id)
            location = dc['properties']['location']
            print("use existing DC {} in location {}".format(
                dc['properties']['name'], location))

        # check if images exist
        for disk in metadata.disks:
            disk_name = disk['file']
            images = get_disk_image_by_name(pbclient, location, disk_name)
            if len(images) == 0:
                raise ValueError(
                    "No HDD image with name '{}' found in location {}".format(
                        disk_name, location))
            if len(images) > 1:
                raise ValueError(
                    "Ambigous image name '{}' in location {}".format(
                        disk_name, location))
            disk['image'] = images[0]['id']

        # now we're ready to create the VM
        # Server
        server = Server(name=metadata.name,
                        cores=metadata.cpus,
                        ram=metadata.ram)
        print("create server {}".format(str(Server)))
        response = pbclient.create_server(dc_id, server)
        srv_id = response['id']
        result = wait_for_request(pbclient, response['requestId'])
        print("wait loop returned {}".format(str(result)))
        # NICs (note that createing LANs may be implicit)
        for nic in metadata.nics:
            dcnic = NIC(name=nic['nic'], lan=nic['lanid'])
            print("create NIC {}".format(str(dcnic)))
            response = pbclient.create_nic(dc_id, srv_id, dcnic)
            nic_id = response['id']
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
            response = pbclient.get_nic(dc_id, srv_id, nic_id, 2)
            mac = response['properties']['mac']
            print("dcnic has MAC {} for {}".format(mac, nic_id))
        # end for(nics)
        # Volumes (we use the image name as volume name too
        requests = []
        for disk in metadata.disks:
            dcvol = Volume(name=disk['file'],
                           size=disk['capacity'],
                           image=disk['image'],
                           licence_type=metadata.licenseType)
            print("create Volume {}".format(str(dcvol)))
            response = pbclient.create_volume(dc_id, dcvol)
            requests.append(response['requestId'])
            disk['volume_id'] = response['id']
        # end for(disks)
        if len(requests) != 0:
            result = wait_for_requests(pbclient,
                                       requests,
                                       initial_wait=10,
                                       scaleup=15)
            print("wait loop returned {}".format(str(result)))
        for disk in metadata.disks:
            print("attach volume {}".format(disk))
            response = pbclient.attach_volume(dc_id, srv_id, disk['volume_id'])
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
        # end for(disks)

        print("import of VM succesfully finished")
        return 0

    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
datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022'
server_id = '700e1cab-99b2-4c30-ba8c-1d273ddba023'

client = ProfitBricksService(
    username='******', password='******')

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

response = client.create_nic(
    datacenter_id=datacenter_id,
    server_id=server_id,
    nic=i)

"""Create NIC with FirewallRules
"""
from profitbricks.client import ProfitBricksService, FirewallRule, NIC  # noqa

datacenter_id = '700e1cab-99b2-4c30-ba8c-1d273ddba022'
server_id = '700e1cab-99b2-4c30-ba8c-1d273ddba023'
nic_id = '<NIC-ID>'

client = ProfitBricksService(
    username='******', password='******')

fwrule1 = FirewallRule(
    name='Open SSH port',
class TestNic(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 LAN.
        self.lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(name=self.resource['lan']['name'], public=False))
        self.client.wait_for_completion(self.lan)

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

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

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

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

    def test_list_nics(self):
        nics = self.client.list_nics(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'])

        self.assertGreater(len(nics), 0)
        self.assertIn(nics['items'][0]['id'], (self.nic1['id'], self.nic2['id']))
        self.assertEqual(nics['items'][0]['type'], 'nic')

    def test_get_nic(self):
        nic = self.client.get_nic(datacenter_id=self.datacenter['id'],
                                  server_id=self.server['id'],
                                  nic_id=self.nic1['id'])

        self.assertEqual(nic['type'], 'nic')
        self.assertEqual(nic['id'], self.nic1['id'])
        assertRegex(self, nic['id'], self.resource['uuid_match'])
        self.assertEqual(nic['properties']['name'], self.resource['nic']['name'])
        self.assertEqual(nic['properties']['firewallActive'],
                         self.resource['nic']['firewall_active'])
        self.assertIsInstance(nic['properties']['ips'], list)
        self.assertEqual(nic['properties']['dhcp'], self.resource['nic']['dhcp'])
        self.assertEqual(nic['properties']['nat'], self.resource['nic']['nat'])
        self.assertEqual(nic['properties']['lan'], self.resource['nic']['lan'])

    def test_delete_nic(self):
        nic2 = self.client.delete_nic(datacenter_id=self.datacenter['id'],
                                      server_id=self.server['id'],
                                      nic_id=self.nic2['id'])

        self.assertTrue(nic2)

    def test_update_nic(self):
        nic = self.client.update_nic(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            name=self.resource['nic']['name'] + ' - RENAME')

        self.assertEqual(nic['id'], self.nic1['id'])
        self.assertEqual(nic['type'], 'nic')
        self.assertEqual(nic['properties']['name'], self.resource['nic']['name'] + ' - RENAME')

    def test_create_nic(self):
        self.assertEqual(self.nic1['type'], 'nic')
        self.assertEqual(self.nic1['properties']['name'], self.resource['nic']['name'])
        self.assertEqual(self.nic1['properties']['firewallActive'],
                         self.resource['nic']['firewall_active'])
        self.assertIsInstance(self.nic1['properties']['ips'], list)
        self.assertEqual(self.nic1['properties']['dhcp'], self.resource['nic']['dhcp'])
        self.assertIsNone(self.nic1['properties']['nat'])
        self.assertEqual(str(self.nic1['properties']['lan']), self.lan['id'])

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

    def test_create_failure(self):
        try:
            nic = NIC(name=self.resource['nic']['name'])
            self.client.create_nic(
                datacenter_id=self.datacenter['id'],
                server_id=self.server['id'],
                nic=nic)
        except PBError as e:
            self.assertIn(self.resource['missing_attribute_error'] % 'lan',
                          e.content[0]['message'])
def main(argv=None):
    '''Parse command line options and create a server/volume composite.'''

    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__))
    # 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('-i',
                        '--infile',
                        dest='infile',
                        default=None,
                        required=True,
                        help='the input file name')
    parser.add_argument('-D',
                        '--DCname',
                        dest='dcname',
                        default=None,
                        help='new datacenter name')
    # TODO: add/overwrite image password for creation
    #    parser.add_argument('-P', '--imagepassword', dest='imgpassword',
    #                        default=None, help='the image password')
    parser.add_argument('-v',
                        '--verbose',
                        dest="verbose",
                        action="count",
                        default=0,
                        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

    if verbose > 0:
        print("Verbose mode on")
        print("start {} with args {}".format(program_name, str(args)))

    (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)

    usefile = args.infile
    print("read dc from {}".format(usefile))
    dcdef = read_dc_definition(usefile)
    if verbose > 0:
        print("using DC-DEF {}".format(json.dumps(dcdef)))

    # setup dc:
    #     + create empty dc
    #     + create volumes (unattached), map uuid to servers (custom dict)
    #     + create servers
    #     + create nics
    #     + attach volumes

    if 'custom' in dcdef and 'id' in dcdef['custom']:
        dc_id = dcdef['custom']['id']
        print("using existing DC w/ id {}".format(str(dc_id)))
    else:
        if args.dcname is not None:
            print("Overwrite DC name w/ '{}'".format(args.dcname))
            dcdef['properties']['name'] = args.dcname
        dc = getDatacenterObject(dcdef)
        # print("create DC {}".format(str(dc)))
        response = pbclient.create_datacenter(dc)
        dc_id = response['id']
        if 'custom' not in dcdef:
            dcdef['custom'] = dict()
        dcdef['custom']['id'] = dc_id
        result = wait_for_request(pbclient, response['requestId'])
        print("wait loop returned {}".format(result))
        tmpfile = usefile + ".tmp_postdc"
        write_dc_definition(dcdef, tmpfile)

    requests = []
    print("create Volumes {}".format(str(dc)))
    # we do NOT consider dangling volumes, only server-attached ones
    for server in dcdef['entities']['servers']['items']:
        print("- server {}".format(server['properties']['name']))
        if 'volumes' not in server['entities']:
            print(" server {} has no volumes".format(
                server['properties']['name']))
            continue
        for volume in server['entities']['volumes']['items']:
            if 'custom' in volume and 'id' in volume['custom']:
                vol_id = volume['custom']['id']
                print("using existing volume w/ id {}".format(str(vol_id)))
            else:
                dcvol = getVolumeObject(volume)
                print("OBJ: {}".format(str(dcvol)))
                response = pbclient.create_volume(dc_id, dcvol)
                volume.update({'custom': {'id': response['id']}})
                requests.append(response['requestId'])
        # end for(volume)
    # end for(server)
    if requests:
        result = wait_for_requests(pbclient,
                                   requests,
                                   initial_wait=10,
                                   scaleup=15)
        print("wait loop returned {}".format(str(result)))
        tmpfile = usefile + ".tmp_postvol"
        write_dc_definition(dcdef, tmpfile)
    else:
        print("all volumes existed already")

    requests = []
    print("create Servers {}".format(str(dc)))
    # we do NOT consider dangling volumes, only server-attached ones
    for server in dcdef['entities']['servers']['items']:
        print("- server {}".format(server['properties']['name']))
        if 'custom' in server and 'id' in server['custom']:
            srv_id = server['custom']['id']
            print("using existing server w/ id {}".format(str(srv_id)))
        else:
            dcsrv = getServerObject(server)
            print("OBJ: {}".format(str(dcsrv)))
            response = pbclient.create_server(dc_id, dcsrv)
            server.update({'custom': {'id': response['id']}})
            requests.append(response['requestId'])
    # end for(server)
    if requests:
        result = wait_for_requests(pbclient,
                                   requests,
                                   initial_wait=10,
                                   scaleup=15)
        print("wait loop returned {}".format(str(result)))
        tmpfile = usefile + ".tmp_postsrv"
        write_dc_definition(dcdef, tmpfile)
    else:
        print("all servers existed already")

# TODO: only do this if we have lan entities
    requests = []
    # Huuh, looks like we get unpredictable order for LANs!
    # Nope, order of creation determines the LAN id,
    # thus we better wait for each request
    print("create LANs {}".format(str(dc)))
    for lan in dcdef['entities']['lans']['items']:
        print("- lan {}".format(lan['properties']['name']))
        dclan = getLANObject(lan)
        print("OBJ: {}".format(str(dclan)))
        response = pbclient.create_lan(dc_id, dclan)
        lan.update({'custom': {'id': response['id']}})
        result = wait_for_request(pbclient, response['requestId'])
        print("wait loop returned {}".format(str(result)))
    # end for(lan)
    tmpfile = usefile + ".tmp_postlan"
    write_dc_definition(dcdef, tmpfile)

    requests = []
    # Attention:
    # NICs appear in OS in the order, they are created.
    # But DCD rearranges the display by ascending MAC addresses.
    # This does not change the OS order.
    # MAC may not be available from create response,
    # thus we wait for each request :-(
    print("create NICs {}".format(str(dc)))
    for server in dcdef['entities']['servers']['items']:
        print("- server {}".format(server['properties']['name']))
        srv_id = server['custom']['id']
        if 'nics' not in server['entities']:
            print(" server {} has no NICs".format(
                server['properties']['name']))
            continue
        macmap = dict()
        for nic in server['entities']['nics']['items']:
            dcnic = getNICObject(nic)
            response = pbclient.create_nic(dc_id, srv_id, dcnic)
            # print("dcnic response {}".format(str(response)))
            # mac = response['properties']['mac'] # we don't get it here !?
            nic_id = response['id']
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
            response = pbclient.get_nic(dc_id, srv_id, nic_id, 2)
            mac = response['properties']['mac']
            print("dcnic has MAC {} for {}".format(mac, nic_id))
            macmap[mac] = nic_id
        # end for(nic)
        macs = sorted(macmap)
        print("macs will be displayed by DCD in th following order:")
        for mac in macs:
            print("mac {} -> id{}".format(mac, macmap[mac]))
    # end for(server)
    tmpfile = usefile + ".tmp_postnic"
    write_dc_definition(dcdef, tmpfile)

    requests = []
    # don't know if we get a race here too, so better wait for each request :-/
    print("attach volumes {}".format(str(dc)))
    for server in dcdef['entities']['servers']['items']:
        print("- server {}".format(server['properties']['name']))
        if 'volumes' not in server['entities']:
            print(" server {} has no volumes".format(
                server['properties']['name']))
            continue
        srv_id = server['custom']['id']
        for volume in server['entities']['volumes']['items']:
            print("OBJ: {}".format(volume['properties']['name']))
            response = pbclient.attach_volume(dc_id, srv_id,
                                              volume['custom']['id'])
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
        # end for(volume)
    # end for(server)
    tmpfile = usefile + ".tmp_postatt"
    write_dc_definition(dcdef, tmpfile)

    # TODO: do we need to set boot volume for each server?
    # looks like it's working without

    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ürgen 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('-t', '--type', dest='metatype',
                            default="OVF",
                            help='type of VM meta data')
        parser.add_argument('-m', '--metadata', dest='metafile',
                            required=True, default=None,
                            help='meta data file')
        parser.add_argument('-d', '--datacenterid', dest='datacenterid',
                            default=None,
                            help='datacenter of the new server')
        parser.add_argument('-D', '--DCname', dest='dcname', default=None,
                            help='new datacenter name')
        parser.add_argument('-l', '--location', dest='location', default=None,
                            help='location for new datacenter')
        parser.add_argument('-v', '--verbose', dest="verbose", action="count",
                            default=0,
                            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

        if verbose > 0:
            print("Verbose mode on")
            print("start {} with args {}".format(program_name, str(args)))

        (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)

        if args.metatype == 'OVF':
            metadata = OFVData(args.metafile)
            metadata.parse()
        else:
            sys.stderr.write("Metadata type '{}' is not supported"
                             .format(args.metatype))
            return 1

        # we need the DC first to have the location defined
        dc_id = None
        if args.datacenterid is None:
            if args.dcname is None or args.location is None:
                sys.stderr.write("Either '-d <id>' or '-D <name> -l <loc>'  must be specified")
                return 1
            # else: we will create the DC later after parsing the meta data
        else:
            dc_id = args.datacenterid

        if dc_id is None:
            location = args.location
            dc = Datacenter(name=args.dcname, location=location,
                            description="created by pb_importVM")
            print("create new DC {}".format(str(dc)))
            response = pbclient.create_datacenter(dc)
            dc_id = response['id']
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(result))
        else:
            dc = pbclient.get_datacenter(dc_id)
            location = dc['properties']['location']
            print("use existing DC {} in location {}"
                  .format(dc['properties']['name'], location))

        # check if images exist
        for disk in metadata.disks:
            disk_name = disk['file']
            images = get_disk_image_by_name(pbclient, location, disk_name)
            if len(images) == 0:
                raise ValueError("No HDD image with name '{}' found in location {}"
                                 .format(disk_name, location))
            if len(images) > 1:
                raise ValueError("Ambigous image name '{}' in location {}"
                                 .format(disk_name, location))
            disk['image'] = images[0]['id']

        # now we're ready to create the VM
        # Server
        server = Server(name=metadata.name,
                        cores=metadata.cpus, ram=metadata.ram)
        print("create server {}".format(str(Server)))
        response = pbclient.create_server(dc_id, server)
        srv_id = response['id']
        result = wait_for_request(pbclient, response['requestId'])
        print("wait loop returned {}".format(str(result)))
        # NICs (note that createing LANs may be implicit)
        for nic in metadata.nics:
            dcnic = NIC(name=nic['nic'], lan=nic['lanid'])
            print("create NIC {}".format(str(dcnic)))
            response = pbclient.create_nic(dc_id, srv_id, dcnic)
            nic_id = response['id']
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
            response = pbclient.get_nic(dc_id, srv_id, nic_id, 2)
            mac = response['properties']['mac']
            print("dcnic has MAC {} for {}".format(mac, nic_id))
        # end for(nics)
        # Volumes (we use the image name as volume name too
        requests = []
        for disk in metadata.disks:
            dcvol = Volume(name=disk['file'], size=disk['capacity'],
                           image=disk['image'],
                           licence_type=metadata.licenseType)
            print("create Volume {}".format(str(dcvol)))
            response = pbclient.create_volume(dc_id, dcvol)
            requests.append(response['requestId'])
            disk['volume_id'] = response['id']
        # end for(disks)
        if len(requests) != 0:
            result = wait_for_requests(pbclient, requests, initial_wait=10, scaleup=15)
            print("wait loop returned {}".format(str(result)))
        for disk in metadata.disks:
            print("attach volume {}".format(disk))
            response = pbclient.attach_volume(dc_id, srv_id, disk['volume_id'])
            result = wait_for_request(pbclient, response['requestId'])
            print("wait loop returned {}".format(str(result)))
        # end for(disks)

        print("import of VM succesfully finished")
        return 0

    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
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'])
Exemple #11
0
class TestFirewall(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 LAN.
        self.lan = self.client.create_lan(datacenter_id=self.datacenter['id'],
                                          lan=LAN(**self.resource['lan']))
        self.client.wait_for_completion(self.lan)

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

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

        # Create test Firewall Rule
        fwrule = FirewallRule(**self.resource['fwrule'])
        self.fwrule = self.client.create_firewall_rule(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            firewall_rule=fwrule)
        self.client.wait_for_completion(self.fwrule)

        # Create test Firewall Rule 2
        fwrule2 = FirewallRule(**self.resource['fwrule'])
        fwrule2.port_range_start = 8080
        fwrule2.port_range_end = 8080
        fwrule2.name = "8080"
        self.fwrule2 = self.client.create_firewall_rule(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            firewall_rule=fwrule2)
        self.client.wait_for_completion(self.fwrule2)

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

    def test_list_fwrules(self):
        fwrules = self.client.get_firewall_rules(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'])

        self.assertGreater(len(fwrules), 0)
        self.assertIn(fwrules['items'][0]['id'],
                      (self.fwrule['id'], self.fwrule2['id']))
        self.assertEqual(fwrules['items'][0]['type'], 'firewall-rule')

    def test_get_fwrule(self):
        fwrule = self.client.get_firewall_rule(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            firewall_rule_id=self.fwrule['id'])

        self.assertEqual(fwrule['type'], 'firewall-rule')
        self.assertEqual(fwrule['id'], self.fwrule['id'])
        assertRegex(self, fwrule['id'], self.resource['uuid_match'])
        self.assertEqual(fwrule['properties']['name'],
                         self.fwrule['properties']['name'])
        self.assertEqual(fwrule['properties']['protocol'],
                         self.fwrule['properties']['protocol'])
        self.assertEqual(fwrule['properties']['sourceMac'],
                         self.fwrule['properties']['sourceMac'])
        self.assertIsNone(fwrule['properties']['sourceIp'])
        self.assertIsNone(fwrule['properties']['targetIp'])
        self.assertIsNone(fwrule['properties']['icmpCode'])
        self.assertIsNone(fwrule['properties']['icmpType'])
        self.assertEqual(fwrule['properties']['portRangeStart'],
                         self.fwrule['properties']['portRangeStart'])
        self.assertEqual(fwrule['properties']['portRangeEnd'],
                         self.fwrule['properties']['portRangeEnd'])

    def test_delete_fwrule(self):
        fwrule = self.client.delete_firewall_rule(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            firewall_rule_id=self.fwrule2['id'])

        self.assertTrue(fwrule)

    def test_update_fwrule(self):
        fwrule = self.client.update_firewall_rule(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic_id=self.nic1['id'],
            firewall_rule_id=self.fwrule['id'],
            name=self.resource['fwrule']['name'] + ' - RENAME')

        self.assertEqual(fwrule['type'], 'firewall-rule')
        self.assertEqual(fwrule['properties']['name'],
                         self.resource['fwrule']['name'] + ' - RENAME')

    def test_create_fwrule(self):
        self.assertEqual(self.fwrule['type'], 'firewall-rule')
        self.assertEqual(self.fwrule['properties']['name'],
                         self.resource['fwrule']['name'])
        self.assertEqual(self.fwrule['properties']['protocol'],
                         self.resource['fwrule']['protocol'])
        self.assertEqual(self.fwrule['properties']['sourceMac'],
                         self.resource['fwrule']['source_mac'])
        self.assertIsNone(self.fwrule['properties']['sourceIp'])
        self.assertIsNone(self.fwrule['properties']['targetIp'])
        self.assertIsNone(self.fwrule['properties']['icmpCode'])
        self.assertIsNone(self.fwrule['properties']['icmpType'])
        self.assertEqual(self.fwrule['properties']['portRangeStart'],
                         self.resource['fwrule']['port_range_start'])
        self.assertEqual(self.fwrule['properties']['portRangeEnd'],
                         self.resource['fwrule']['port_range_end'])

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

    def test_create_failure(self):
        try:
            fwrule = FirewallRule(name=self.resource['fwrule']['name'])
            self.client.create_firewall_rule(
                datacenter_id=self.datacenter['id'],
                server_id=self.server['id'],
                nic_id=self.nic1['id'],
                firewall_rule=fwrule)
        except PBError as e:
            self.assertIn(
                self.resource['missing_attribute_error'] % 'protocol',
                e.content[0]['message'])
class TestLan(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 LAN.
        self.lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(**self.resource['lan']))
        wait_for_completion(self.client, self.lan, 'create_lan')

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

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

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

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

    def test_list_lans(self):
        lans = self.client.list_lans(datacenter_id=self.datacenter['id'])

        self.assertGreater(len(lans), 0)
        self.assertEqual(lans['items'][0]['type'], 'lan')
        self.assertIn(lans['items'][0]['id'], ('1', '2', '3'))
        self.assertEqual(lans['items'][0]['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(lans['items'][0]['properties']['public'], self.resource['lan']['public'])

    def test_get_lan(self):
        lan = self.client.get_lan(datacenter_id=self.datacenter['id'], lan_id=self.lan['id'])

        self.assertEqual(lan['type'], 'lan')
        self.assertEqual(lan['id'], self.lan['id'])
        self.assertEqual(lan['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(lan['properties']['public'], self.resource['lan']['public'])

    def test_delete_lan(self):
        lan = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=LAN(**self.resource['lan']))
        wait_for_completion(self.client, self.lan, 'create_lan')

        lan = self.client.delete_lan(datacenter_id=self.datacenter['id'], lan_id=lan['id'])

        self.assertTrue(lan)

    def test_update_lan(self):
        lan = self.client.update_lan(
            datacenter_id=self.datacenter['id'],
            lan_id=self.lan['id'],
            name=self.resource['lan']['name'] + ' RENAME',
            public=False)

        self.assertEqual(lan['type'], 'lan')
        self.assertEqual(lan['properties']['name'], self.resource['lan']['name'] + ' RENAME')
        self.assertFalse(lan['properties']['public'])

    def test_create_lan(self):
        self.assertEqual(self.lan['id'], '1')
        self.assertEqual(self.lan['type'], 'lan')
        self.assertEqual(self.lan['properties']['name'], self.resource['lan']['name'])
        self.assertEqual(self.lan['properties']['public'], self.resource['lan']['public'])

    def test_create_complex_lan(self):
        resource = NIC(**self.resource['nic'])

        nic1 = self.client.create_nic(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic=resource)
        wait_for_completion(self.client, nic1, 'create_nic1')

        nic2 = self.client.create_nic(
            datacenter_id=self.datacenter['id'],
            server_id=self.server['id'],
            nic=resource)
        wait_for_completion(self.client, nic2, 'create_nic2')

        nics = [nic1['id'], nic2['id']]
        lan = LAN(nics=nics, **self.resource['lan'])

        response = self.client.create_lan(
            datacenter_id=self.datacenter['id'],
            lan=lan)
        wait_for_completion(self.client, response, 'create_lan')

        self.assertEqual(response['type'], 'lan')
        self.assertEqual(response['properties']['name'], self.resource['lan']['name'])
        self.assertTrue(response['properties']['public'])

    def test_get_lan_members(self):
        members = self.client.get_lan_members(
            datacenter_id=self.datacenter['id'],
            lan_id=self.lan['id'])

        self.assertGreater(len(members), 0)
        assertRegex(self, members['items'][0]['id'], self.resource['uuid_match'])
        self.assertEqual(members['items'][0]['type'], 'nic')
        self.assertEqual(members['items'][0]['properties']['name'], self.resource['nic']['name'])
        assertRegex(self, members['items'][0]['properties']['mac'], self.resource['mac_match'])
class TestLoadBalancer(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 LAN.
        self.lan = self.client.create_lan(datacenter_id=self.datacenter['id'],
                                          lan=LAN(**self.resource['lan']))
        self.client.wait_for_completion(self.lan)

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

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

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

        # Create test LoadBalancer
        loadbalancer = LoadBalancer(**self.resource['loadbalancer'])
        loadbalancer.balancednics = [self.nic1['id']]
        self.loadbalancer = self.client.create_loadbalancer(
            datacenter_id=self.datacenter['id'], loadbalancer=loadbalancer)

        self.client.wait_for_completion(self.loadbalancer)

        # Create test LoadBalancer2
        loadbalancer2 = LoadBalancer(**self.resource['loadbalancer'])
        loadbalancer2.name = "Python SDK Test 2"
        self.loadbalancer2 = self.client.create_loadbalancer(
            datacenter_id=self.datacenter['id'], loadbalancer=loadbalancer2)

        self.client.wait_for_completion(self.loadbalancer2)

        # Create test LoadBalancer3
        loadbalancer3 = LoadBalancer(**self.resource['loadbalancer'])
        loadbalancer3.balancednics = [self.nic1['id']]
        loadbalancer3.name = "Python SDK Test 3"
        self.loadbalancer3 = self.client.create_loadbalancer(
            datacenter_id=self.datacenter['id'], loadbalancer=loadbalancer3)

        self.client.wait_for_completion(self.loadbalancer3)

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

    def test_list_loadbalancers(self):
        loadbalancers = self.client.list_loadbalancers(
            datacenter_id=self.datacenter['id'])

        self.assertGreater(len(loadbalancers), 0)
        self.assertIn(loadbalancers['items'][0]['id'],
                      (self.loadbalancer['id'], self.loadbalancer2['id'],
                       self.loadbalancer3['id']))
        self.assertEqual(loadbalancers['items'][0]['type'], 'loadbalancer')

    def test_get_loadbalancer(self):
        loadbalancer = self.client.get_loadbalancer(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer['id'])

        self.assertEqual(loadbalancer['type'], 'loadbalancer')
        self.assertEqual(loadbalancer['id'], self.loadbalancer['id'])
        assertRegex(self, loadbalancer['id'], self.resource['uuid_match'])
        self.assertEqual(loadbalancer['properties']['name'],
                         self.loadbalancer['properties']['name'])
        self.assertEqual(loadbalancer['properties']['dhcp'],
                         self.loadbalancer['properties']['dhcp'])
        self.assertIsNotNone(loadbalancer['properties']['ip'])

    def test_delete_loadbalancer(self):
        loadbalancer = self.client.delete_loadbalancer(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer2['id'])

        self.assertTrue(loadbalancer)

    def test_update_loadbalancer(self):
        loadbalancer = self.client.update_loadbalancer(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer['id'],
            name=self.resource['loadbalancer']['name'] + ' - RENAME')

        self.assertEqual(loadbalancer['type'], 'loadbalancer')
        self.assertEqual(loadbalancer['properties']['name'],
                         self.resource['loadbalancer']['name'] + ' - RENAME')

    def test_create_loadbalancer(self):
        self.assertEqual(self.loadbalancer['type'], 'loadbalancer')
        self.assertIsNotNone(self.loadbalancer['entities']['balancednics'])
        self.assertEqual(self.loadbalancer['properties']['name'],
                         self.resource['loadbalancer']['name'])
        self.assertEqual(self.loadbalancer['properties']['dhcp'],
                         self.resource['loadbalancer']['dhcp'])

    def test_associate_nic(self):
        associated_nic = self.client.add_loadbalanced_nics(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer2['id'],
            nic_id=self.nic1['id'])

        self.client.wait_for_completion(associated_nic)

        self.assertEqual(associated_nic['id'], self.nic1['id'])
        self.assertEqual(associated_nic['properties']['name'],
                         self.nic1['properties']['name'])

    def test_remove_nic(self):
        remove_nic = self.client.remove_loadbalanced_nic(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer3['id'],
            nic_id=self.nic1['id'])
        self.assertTrue(remove_nic)
        sleep(30)

    def test_list_balanced_nics(self):
        balanced_nics = self.client.get_loadbalancer_members(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer['id'])

        self.assertGreater(len(balanced_nics['items']), 0)
        self.assertEqual(balanced_nics['items'][0]['id'], self.nic1['id'])
        self.assertEqual(balanced_nics['items'][0]['type'], 'nic')

    def test_get_balanced_nic(self):
        balanced_nic = self.client.get_loadbalanced_nic(
            datacenter_id=self.datacenter['id'],
            loadbalancer_id=self.loadbalancer['id'],
            nic_id=self.nic1['id'])

        self.assertEqual(balanced_nic['id'], self.nic1['id'])
        self.assertEqual(balanced_nic['type'], 'nic')
        self.assertEqual(balanced_nic['properties']['name'],
                         self.nic1['properties']['name'])
        self.assertEqual(balanced_nic['properties']['dhcp'],
                         self.nic1['properties']['dhcp'])
        self.assertIsInstance(balanced_nic['properties']['nat'], bool)
        self.assertIsInstance(balanced_nic['properties']['firewallActive'],
                              bool)
        self.assertGreater(len(balanced_nic['properties']['ips']), 0)
        self.assertIsInstance(balanced_nic['properties']['lan'], int)
        assertRegex(self, balanced_nic['properties']['mac'],
                    self.resource['mac_match'])

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

    def test_create_failure(self):
        try:
            self.client.create_loadbalancer(
                datacenter_id=self.datacenter['id'],
                loadbalancer=LoadBalancer())
        except PBError as e:
            self.assertIn(self.resource['missing_attribute_error'] % 'lan',
                          e.content[0]['message'])
class TestNIC(unittest.TestCase):
    def setUp(self):
        self.nic = ProfitBricksService(
            username='******', password='******')

    def test_list_nics(self):
        nics = self.nic.list_nics(
            datacenter_id=datacenter_id,
            server_id=server_id)

        self.assertEqual(len(nics), 4)
        self.assertEqual(nics['items'][0]['id'], nic_id)
        self.assertEqual(nics['items'][0]['properties']['name'], 'nic1')
        self.assertEqual(
            nics['items'][0]['properties']['mac'], 'AB:21:23:09:78:C2')
        self.assertEqual(nics['items'][0]['properties']['dhcp'], 'true')
        self.assertEqual(nics['items'][0]['properties']['lan'], 1)

    def test_get_nic(self):
        nic = self.nic.get_nic(
            datacenter_id=datacenter_id,
            server_id=server_id,
            nic_id=nic_id)

        self.assertEqual(nic['id'], nic_id)
        self.assertEqual(nic['properties']['name'], 'nic1')
        self.assertEqual(nic['properties']['mac'], 'AB:21:23:09:78:C2')
        self.assertEqual(nic['properties']['dhcp'], 'true')
        self.assertEqual(nic['properties']['lan'], 1)

    def test_delete_nic(self):
        nic = self.nic.delete_nic(
            datacenter_id=datacenter_id,
            server_id=server_id,
            nic_id=nic_id)

        self.assertTrue(nic)

    def test_update_nic(self):
        nic = self.nic.update_nic(
            datacenter_id=datacenter_id,
            server_id=server_id,
            nic_id=nic_id,
            ips=['10.2.2.3', '10.2.3.4'])

        self.assertEqual(nic['id'], nic_id)
        self.assertEqual(nic['properties']['name'], 'nic1')
        self.assertEqual(nic['properties']['mac'], 'AB:21:23:09:78:C2')
        self.assertEqual(nic['properties']['dhcp'], 'true')
        self.assertEqual(nic['properties']['lan'], 1)

    def test_create_complex(self):
        fwrule1 = FirewallRule(
            name='Open SSH port',
            protocol='TCP',
            source_mac='01:23:45:67:89:00',
            port_range_start=22
            )

        fwrule2 = FirewallRule(
            name='Allow PING',
            protocol='ICMP',
            icmp_type=8,
            icmp_code=0
            )

        fw_rules = [fwrule1, fwrule2]

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

        response = self.nic.create_nic(
            datacenter_id=datacenter_id,
            server_id=server_id, nic=i)

        self.assertEqual(response['id'], nic_id)
        self.assertEqual(response['properties']['name'], 'nic1')
        self.assertEqual(
            response['properties']['mac'], 'AB:21:23:09:78:C2')
        self.assertEqual(response['properties']['dhcp'], 'true')
        self.assertEqual(response['properties']['lan'], 1)
        self.assertListEqual(
            response['properties']['ips'], ['10.2.2.3'])

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

        response = self.nic.create_nic(
            datacenter_id=datacenter_id,
            server_id=server_id,
            nic=i)

        self.assertEqual(response['id'], nic_id)
        self.assertEqual(response['properties']['name'], 'nic1')
        self.assertEqual(
            response['properties']['mac'], 'AB:21:23:09:78:C2')
        self.assertEqual(response['properties']['dhcp'], 'true')
        self.assertEqual(response['properties']['lan'], 1)
        self.assertListEqual(
            response['properties']['ips'], ['10.2.2.3'])
def main(argv=None):
    """Parse command line options and create a server/volume composite."""

    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__),
    )
    # 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("-i", "--infile", dest="infile", default=None, required=True, help="the input file name")
    parser.add_argument("-D", "--DCname", dest="dcname", default=None, help="new datacenter name")
    # TODO: add/overwrite image password for creation
    #    parser.add_argument('-P', '--imagepassword', dest='imgpassword',
    #                        default=None, help='the image password')
    parser.add_argument(
        "-v", "--verbose", dest="verbose", action="count", default=0, 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

    if verbose > 0:
        print("Verbose mode on")
        print("start {} with args {}".format(program_name, str(args)))

    (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)

    usefile = args.infile
    print("read dc from {}".format(usefile))
    dcdef = read_dc_definition(pbclient, usefile)
    if verbose > 0:
        print("using DC-DEF {}".format(json.dumps(dcdef)))

    # setup dc:
    #     + create empty dc
    #     + create volumes (unattached), map uuid to servers (custom dict)
    #     + create servers
    #     + create nics
    #     + attach volumes

    if "custom" in dcdef and "id" in dcdef["custom"]:
        dc_id = dcdef["custom"]["id"]
        print("using existing DC w/ id {}".format(str(dc_id)))
    else:
        if args.dcname is not None:
            print("Overwrite DC name w/ '{}'".format(args.dcname))
            dcdef["properties"]["name"] = args.dcname
        dc = getDatacenterObject(dcdef)
        # print("create DC {}".format(str(dc)))
        response = pbclient.create_datacenter(dc)
        dc_id = response["id"]
        if "custom" not in dcdef:
            dcdef["custom"] = dict()
        dcdef["custom"]["id"] = dc_id
        result = wait_for_request(pbclient, response["requestId"])
        print("wait loop returned {}".format(result))
        tmpfile = usefile + ".tmp_postdc"
        write_dc_definition(pbclient, dcdef, tmpfile)

    requests = []
    print("create Volumes {}".format(str(dc)))
    # we do NOT consider dangling volumes, only server-attached ones
    for server in dcdef["entities"]["servers"]["items"]:
        print("- server {}".format(server["properties"]["name"]))
        if "volumes" not in server["entities"]:
            print(" server {} has no volumes".format(server["properties"]["name"]))
            continue
        for volume in server["entities"]["volumes"]["items"]:
            if "custom" in volume and "id" in volume["custom"]:
                vol_id = volume["custom"]["id"]
                print("using existing volume w/ id {}".format(str(vol_id)))
            else:
                dcvol = getVolumeObject(volume)
                print("OBJ: {}".format(str(dcvol)))
                response = pbclient.create_volume(dc_id, dcvol)
                volume.update({"custom": {"id": response["id"]}})
                requests.append(response["requestId"])
        # end for(volume)
    # end for(server)
    if len(requests) != 0:
        result = wait_for_requests(pbclient, requests, initial_wait=10, scaleup=15)
        print("wait loop returned {}".format(str(result)))
        tmpfile = usefile + ".tmp_postvol"
        write_dc_definition(pbclient, dcdef, tmpfile)
    else:
        print("all volumes existed already")

    requests = []
    print("create Servers {}".format(str(dc)))
    # we do NOT consider dangling volumes, only server-attached ones
    for server in dcdef["entities"]["servers"]["items"]:
        print("- server {}".format(server["properties"]["name"]))
        if "custom" in server and "id" in server["custom"]:
            srv_id = server["custom"]["id"]
            print("using existing server w/ id {}".format(str(srv_id)))
        else:
            dcsrv = getServerObject(server)
            print("OBJ: {}".format(str(dcsrv)))
            response = pbclient.create_server(dc_id, dcsrv)
            server.update({"custom": {"id": response["id"]}})
            requests.append(response["requestId"])
    # end for(server)
    if len(requests) != 0:
        result = wait_for_requests(pbclient, requests, initial_wait=10, scaleup=15)
        print("wait loop returned {}".format(str(result)))
        tmpfile = usefile + ".tmp_postsrv"
        write_dc_definition(pbclient, dcdef, tmpfile)
    else:
        print("all servers existed already")

    # TODO: only do this if we have lan entities
    requests = []
    # Huuh, looks like we get unpredictable order for LANs!
    # Nope, order of creation determines the LAN id,
    # thus we better wait for each request
    print("create LANs {}".format(str(dc)))
    for lan in dcdef["entities"]["lans"]["items"]:
        print("- lan {}".format(lan["properties"]["name"]))
        dclan = getLANObject(lan)
        print("OBJ: {}".format(str(dclan)))
        response = pbclient.create_lan(dc_id, dclan)
        lan.update({"custom": {"id": response["id"]}})
        result = wait_for_request(pbclient, response["requestId"])
        print("wait loop returned {}".format(str(result)))
    # end for(lan)
    tmpfile = usefile + ".tmp_postlan"
    write_dc_definition(pbclient, dcdef, tmpfile)

    requests = []
    # Attention:
    # NICs appear in OS in the order, they are created.
    # But DCD rearranges the display by ascending MAC addresses.
    # This does not change the OS order.
    # MAC may not be available from create response,
    # thus we wait for each request :-(
    print("create NICs {}".format(str(dc)))
    for server in dcdef["entities"]["servers"]["items"]:
        print("- server {}".format(server["properties"]["name"]))
        srv_id = server["custom"]["id"]
        if "nics" not in server["entities"]:
            print(" server {} has no NICs".format(server["properties"]["name"]))
            continue
        macmap = dict()
        for nic in server["entities"]["nics"]["items"]:
            dcnic = getNICObject(nic)
            response = pbclient.create_nic(dc_id, srv_id, dcnic)
            # print("dcnic response {}".format(str(response)))
            # mac = response['properties']['mac'] # we don't get it here !?
            nic_id = response["id"]
            result = wait_for_request(pbclient, response["requestId"])
            print("wait loop returned {}".format(str(result)))
            response = pbclient.get_nic(dc_id, srv_id, nic_id, 2)
            mac = response["properties"]["mac"]
            print("dcnic has MAC {} for {}".format(mac, nic_id))
            macmap[mac] = nic_id
        # end for(nic)
        macs = sorted(macmap)
        print("macs will be displayed by DCD in th following order:")
        for mac in macs:
            print("mac {} -> id{}".format(mac, macmap[mac]))
    # end for(server)
    tmpfile = usefile + ".tmp_postnic"
    write_dc_definition(pbclient, dcdef, tmpfile)

    requests = []
    # don't know if we get a race here too, so better wait for each request :-/
    print("attach volumes {}".format(str(dc)))
    for server in dcdef["entities"]["servers"]["items"]:
        print("- server {}".format(server["properties"]["name"]))
        if "volumes" not in server["entities"]:
            print(" server {} has no volumes".format(server["properties"]["name"]))
            continue
        srv_id = server["custom"]["id"]
        for volume in server["entities"]["volumes"]["items"]:
            print("OBJ: {}".format(volume["properties"]["name"]))
            response = pbclient.attach_volume(dc_id, srv_id, volume["custom"]["id"])
            result = wait_for_request(pbclient, response["requestId"])
            print("wait loop returned {}".format(str(result)))
        # end for(volume)
    # end for(server)
    tmpfile = usefile + ".tmp_postatt"
    write_dc_definition(pbclient, dcdef, tmpfile)

    # TODO: do we need to set boot volume for each server?
    # looks like it's working without

    return 0